Selaa lähdekoodia

feat(ui): updates to design system (#37471)

Aarav Sareen 1 kuukausi sitten
vanhempi
sitoutus
86978e7a8c

+ 23 - 0
packages/ui/src/v2/components/button-v2.css

@@ -113,6 +113,29 @@
   cursor: not-allowed;
 }
 
+[data-component="button-v2"][data-variant="warning"] {
+  background-color: var(--v2-background-bg-button-neutral);
+  color: var(--v2-state-fg-warning);
+  box-shadow: var(--v2-elevation-button-neutral);
+}
+
+[data-component="button-v2"][data-variant="warning"]:is(:hover, [data-state="hover"]):not(:disabled) {
+  background-image:
+    linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
+    linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
+}
+
+[data-component="button-v2"][data-variant="warning"]:is(:active, [data-state="pressed"]):not(:disabled) {
+  background-image:
+    linear-gradient(90deg, var(--v2-overlay-simple-overlay-pressed) 0%, var(--v2-overlay-simple-overlay-pressed) 100%),
+    linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
+}
+
+[data-component="button-v2"][data-variant="warning"]:is(:disabled, [data-state="disabled"]) {
+  opacity: 0.5;
+  cursor: not-allowed;
+}
+
 /* Outline */
 [data-component="button-v2"][data-variant="outline"] {
   background-color: transparent;

+ 4 - 3
packages/ui/src/v2/components/button-v2.stories.tsx

@@ -4,7 +4,7 @@ const docs = `### Overview
 Button v2 with visual variants and three sizes.
 
 ### API
-- \`variant\`: "neutral" | "danger" | "contrast" | "ghost" | "ghost-muted" | "loading".
+- \`variant\`: "neutral" | "danger" | "warning" | "contrast" | "ghost" | "ghost-muted" | "loading".
 - \`size\`: "small" | "normal" | "large".
 - \`icon\`: Optional icon name.
 - Inherits Kobalte Button props and native button attributes.
@@ -39,7 +39,7 @@ export default {
     },
     variant: {
       control: "select",
-      options: ["neutral", "danger", "contrast", "ghost", "ghost-muted", "loading"],
+      options: ["neutral", "danger", "warning", "contrast", "ghost", "ghost-muted", "loading"],
     },
     size: {
       control: "select",
@@ -62,6 +62,7 @@ export const Variants = {
     >
       <ButtonV2 variant="neutral">Neutral</ButtonV2>
       <ButtonV2 variant="danger">Danger</ButtonV2>
+      <ButtonV2 variant="warning">Warning</ButtonV2>
       <ButtonV2 variant="contrast">Contrast</ButtonV2>
       <ButtonV2 variant="ghost">Ghost</ButtonV2>
       <ButtonV2 variant="ghost-muted" icon="edit">
@@ -117,7 +118,7 @@ export const Icon = {
 
 export const AllStates = {
   render: () => {
-    const variants = ["neutral", "danger", "contrast", "ghost", "ghost-muted", "loading"] as const
+    const variants = ["neutral", "danger", "warning", "contrast", "ghost", "ghost-muted", "loading"] as const
     const states = ["default", "hover", "pressed", "focus", "disabled"] as const
     const toTitleCase = (value: string) => value.charAt(0).toUpperCase() + value.slice(1)
     return (

+ 1 - 1
packages/ui/src/v2/components/button-v2.tsx

@@ -7,7 +7,7 @@ export interface ButtonV2Props
   extends ComponentProps<typeof Kobalte>,
     Pick<ComponentProps<"button">, "class" | "classList" | "children"> {
   size?: "small" | "normal" | "large"
-  variant?: "neutral" | "danger" | "outline" | "contrast" | "ghost" | "ghost-muted" | "loading"
+  variant?: "neutral" | "danger" | "warning" | "outline" | "contrast" | "ghost" | "ghost-muted" | "loading"
   icon?: IconProps["name"]
 }
 

+ 2 - 2
packages/ui/src/v2/components/divider-v2.css

@@ -1,8 +1,8 @@
 [data-component="divider-v2"] {
   box-sizing: border-box;
   width: 100%;
-  height: 0.5px;
-  margin-block: 0.25px;
+  height: 1px;
+  transform: scaleY(0.5);
   border: none;
   background: var(--v2-border-border-strong);
   flex: none;

+ 7 - 0
packages/ui/src/v2/components/inline-input-v2.css

@@ -67,9 +67,14 @@
   gap: 4px;
   background: var(--v2-background-bg-layer-01);
   border-radius: 4px 0 0 4px;
+  cursor: default;
   transition: background 85ms ease-out;
 }
 
+[data-component="inline-input-v2"]:where([data-disabled]) [data-slot="inline-input-v2-prefix"] {
+  cursor: not-allowed;
+}
+
 [data-component="inline-input-v2"][data-label-width] [data-slot="inline-input-v2-prefix"] {
   width: var(--inline-input-v2-label-width);
   min-width: var(--inline-input-v2-label-width);
@@ -89,6 +94,7 @@
   letter-spacing: -0.04px;
   color: var(--v2-text-text-muted);
   font-variation-settings: "slnt" 0;
+  user-select: none;
 }
 
 [data-component="inline-input-v2"][data-numeric] [data-slot="inline-input-v2-prefix-text"] {
@@ -149,6 +155,7 @@
 
 [data-component="inline-input-v2"] [data-slot="inline-input-v2-input"]::placeholder {
   color: var(--v2-text-text-faint);
+  user-select: none;
 }
 
 [data-component="inline-input-v2"][data-numeric] [data-slot="inline-input-v2-input"] {

+ 16 - 1
packages/ui/src/v2/components/inline-input-v2.tsx

@@ -37,6 +37,8 @@ export function InlineInputV2(props: InlineInputV2Props) {
     "style",
   ])
 
+  let input: HTMLInputElement | undefined
+
   return (
     <div
       data-component="inline-input-v2"
@@ -59,7 +61,15 @@ export function InlineInputV2(props: InlineInputV2Props) {
           : {}),
       }}
     >
-      <div data-slot="inline-input-v2-prefix">
+      <div
+        data-slot="inline-input-v2-prefix"
+        onMouseDown={(event) => {
+          if (local.disabled || event.button !== 0) return
+          // Keep focus on the input without using a native <label>, so external labels still work.
+          event.preventDefault()
+          input?.focus()
+        }}
+      >
         <span data-slot="inline-input-v2-prefix-text">{local.prefix}</span>
       </div>
       <div data-slot="inline-input-v2-divider" aria-hidden="true" />
@@ -67,6 +77,11 @@ export function InlineInputV2(props: InlineInputV2Props) {
         <div data-slot="inline-input-v2-value">
           <input
             {...inputProps}
+            ref={(el) => {
+              input = el
+              const ref = inputProps.ref
+              if (typeof ref === "function") ref(el)
+            }}
             type={inputProps.type ?? "text"}
             disabled={local.disabled}
             aria-invalid={local.invalid ? true : undefined}

+ 1 - 0
packages/ui/src/v2/components/text-input-v2.css

@@ -98,6 +98,7 @@
 
 [data-component="text-input-v2"] [data-slot="text-input-v2-input"]::placeholder {
   color: var(--v2-text-text-faint);
+  user-select: none;
 }
 
 [data-component="text-input-v2"] [data-slot="text-input-v2-input"][type="search"]::-webkit-search-cancel-button {