@waveso/ui 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -59,9 +59,15 @@ This is the right shape for a system centered on an emphasis ladder: clean and m
59
59
 
60
60
  The three themes are a homage to the **pre-digital writing desk** — the _surface_, the _pen_, the _pencil_ — and each maps to its color: cream ***Paper***, blue-black ***Ink***, gray ***Graphite***.
61
61
 
62
- **Graphite** is the default **neutral pencil-gray** theme, built on a low-saturation dark-neutral family with a subtle blue bias. That bias keeps the light steps from going flat — a tiny cool cast instead of pure gray.
62
+ Wave **follows your operating system by default** — a light OS gets **Paper**, a dark OS gets **Graphite** (the neutral pencil-gray theme, a low-saturation dark-neutral with a subtle blue bias so its steps never go flat). **Ink**, the deep-navy _night_ theme, is opt-in.
63
63
 
64
- **Paper** and **Ink** are an elegant classic pair, each with a purpose: Paper is tuned for daytime and bright spaces; Ink for night and dark spaces. In every theme the _structure_ (text and borders) stays a cool-biased neutral, while the _surface_ carries the identity.
64
+ | Theme | Role | Select with |
65
+ | --- | --- | --- |
66
+ | **Paper** | Light | light OS · `<html class="paper">` |
67
+ | **Graphite** | Dark | dark OS · `<html class="graphite">` |
68
+ | **Ink** | Night (premium) | `<html class="ink">` |
69
+
70
+ A pinned class always beats the OS — put `.paper`, `.graphite`, or `.ink` on your `<html>` (or any subtree) from your app's own theme toggle. In every theme the _structure_ (text and borders) stays a cool-biased neutral, while the _surface_ carries the identity.
65
71
 
66
72
  ## Taxonomy
67
73
 
@@ -144,7 +150,7 @@ Import Tailwind, then the Wave UI preset, in your CSS entry point:
144
150
  @import "@waveso/ui/styles.css";
145
151
  ```
146
152
 
147
- The preset provides every CSS variable (colors, radii, motion, shadows) with light and dark support. Override any variable in your own `:root` / `.dark` blocks to customize the theme.
153
+ The preset provides every CSS variable (colors, radii, motion, shadows) with light and dark support. Override any variable in your own `:root` or a theme block (`.graphite`, `.ink`, …) to customize the theme.
148
154
 
149
155
  ## Usage
150
156
 
@@ -12,7 +12,7 @@ function Autocomplete({ ...props }) {
12
12
  function AutocompleteInput({ className, ...props }) {
13
13
  return /* @__PURE__ */ jsx(Autocomplete$1.Input, {
14
14
  "data-slot": "autocomplete-input",
15
- className: cn("dark:bg-edge/30 border-edge focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-edge/50 dark:disabled:bg-edge/80 placeholder:text-soft h-8 w-full min-w-0 rounded-md border bg-transparent px-2.5 py-1 text-base transition-colors outline-hidden focus-visible:ring-3 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm", className),
15
+ className: cn("dark:bg-edge/30 border-edge focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive disabled:bg-edge/50 dark:disabled:bg-edge/80 placeholder:text-soft h-8 w-full min-w-0 rounded-md border bg-transparent px-2.5 py-1 text-base transition-colors outline-hidden focus-visible:ring-3 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm", className),
16
16
  ...props
17
17
  });
18
18
  }
package/dist/badge.d.ts CHANGED
@@ -5,7 +5,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
5
5
 
6
6
  //#region src/badge.d.ts
7
7
  declare const badgeVariants: (props?: ({
8
- variant?: "default" | "outline" | "link" | "destructive" | "success" | "warning" | "secondary" | "ghost" | null | undefined;
8
+ variant?: "default" | "link" | "success" | "destructive" | "warning" | "secondary" | "outline" | "ghost" | null | undefined;
9
9
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
10
10
  type BadgeProps = useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>;
11
11
  declare function Badge({
@@ -37,8 +37,6 @@ function BreadcrumbLink({ className, render, ...props }) {
37
37
  function BreadcrumbPage({ className, ...props }) {
38
38
  return /* @__PURE__ */ jsx("span", {
39
39
  "data-slot": "breadcrumb-page",
40
- role: "link",
41
- "aria-disabled": "true",
42
40
  "aria-current": "page",
43
41
  className: cn("text-contrast font-normal", className),
44
42
  ...props
package/dist/button.d.ts CHANGED
@@ -6,8 +6,8 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
6
6
 
7
7
  //#region src/button.d.ts
8
8
  declare const buttonVariants: (props?: ({
9
- variant?: "default" | "outline" | "link" | "destructive" | "success" | "secondary" | "ghost" | null | undefined;
10
- size?: "default" | "sm" | "xs" | "icon" | "icon-xs" | "icon-sm" | "lg" | "xl" | "icon-lg" | null | undefined;
9
+ variant?: "default" | "link" | "destructive" | "secondary" | "outline" | "ghost" | null | undefined;
10
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
11
11
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
12
12
  type ButtonProps = React.ComponentProps<typeof Button$1> & VariantProps<typeof buttonVariants>;
13
13
  declare function Button({
package/dist/button.js CHANGED
@@ -4,27 +4,25 @@ import { jsx } from "react/jsx-runtime";
4
4
  import { Button as Button$1 } from "@base-ui/react/button";
5
5
  import { cva } from "class-variance-authority";
6
6
  //#region src/button.tsx
7
- const buttonVariants = cva("cursor-clickable focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-md border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap motion-color disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-hidden group/button select-none", {
7
+ const buttonVariants = cva("cursor-clickable focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive rounded-md border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap motion-color disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-hidden group/button select-none active:not-aria-[haspopup]:scale-[0.97]", {
8
8
  variants: {
9
9
  variant: {
10
10
  default: "bg-primary text-white hover:bg-primary/80",
11
- outline: "border-line bg-foundation hover:bg-secondary hover:text-contrast dark:bg-edge/30 dark:border-edge dark:hover:bg-edge/50 aria-expanded:bg-secondary aria-expanded:text-contrast",
11
+ outline: "border-edge bg-foundation hover:bg-secondary/80 hover:text-contrast dark:bg-edge/30 aria-expanded:bg-secondary aria-expanded:text-contrast",
12
12
  secondary: "bg-secondary text-contrast hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-contrast",
13
- ghost: "hover:bg-secondary/80 hover:text-contrast aria-expanded:bg-secondary aria-expanded:text-contrast",
14
- success: "bg-success/10 hover:bg-success/20 focus-visible:ring-success/20 dark:focus-visible:ring-success/40 dark:bg-success/20 text-success focus-visible:border-success/40 dark:hover:bg-success/30",
15
- destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
13
+ ghost: "text-contrast hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-contrast",
14
+ destructive: "bg-destructive text-white hover:bg-destructive/80 focus-visible:ring-destructive/50",
16
15
  link: "text-primary underline-offset-4 hover:underline"
17
16
  },
18
17
  size: {
19
- default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
20
- xs: "h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
21
- sm: "h-7 gap-1 rounded-sm px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
22
- lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
23
- xl: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
24
- icon: "size-8",
18
+ default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pe-2.5 has-data-[icon=inline-start]:ps-2.5",
19
+ xs: "h-6 gap-1 rounded-sm px-2.5 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-3",
20
+ sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
21
+ lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pe-3 has-data-[icon=inline-start]:ps-3",
22
+ icon: "size-9",
25
23
  "icon-xs": "size-6 rounded-sm in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
26
- "icon-sm": "size-7 rounded-sm in-data-[slot=button-group]:rounded-md",
27
- "icon-lg": "size-9"
24
+ "icon-sm": "size-8",
25
+ "icon-lg": "size-10"
28
26
  }
29
27
  },
30
28
  defaultVariants: {
package/dist/checkbox.js CHANGED
@@ -7,7 +7,7 @@ import { Checkbox as Checkbox$1 } from "@base-ui/react/checkbox";
7
7
  function Checkbox({ className, ...props }) {
8
8
  return /* @__PURE__ */ jsx(Checkbox$1.Root, {
9
9
  "data-slot": "checkbox",
10
- className: cn("cursor-clickable border-edge dark:bg-edge/30 data-checked:bg-primary data-indeterminate:bg-primary data-checked:text-white data-indeterminate:text-white dark:data-checked:bg-primary dark:data-indeterminate:bg-primary data-checked:border-primary data-indeterminate:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors outline-hidden group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3", className),
10
+ className: cn("cursor-clickable border-edge dark:bg-edge/30 data-checked:bg-primary data-indeterminate:bg-primary data-checked:text-white data-indeterminate:text-white dark:data-checked:bg-primary dark:data-indeterminate:bg-primary data-checked:border-primary data-indeterminate:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors outline-hidden group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3", className),
11
11
  ...props,
12
12
  children: /* @__PURE__ */ jsxs(Checkbox$1.Indicator, {
13
13
  "data-slot": "checkbox-indicator",
package/dist/combobox.js CHANGED
@@ -153,7 +153,7 @@ function ComboboxSeparator({ className, ...props }) {
153
153
  function ComboboxChips({ className, ...props }) {
154
154
  return /* @__PURE__ */ jsx(Combobox$1.Chips, {
155
155
  "data-slot": "combobox-chips",
156
- className: cn("dark:bg-edge/30 border-edge focus-within:border-focus focus-within:ring-focus/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 flex min-h-8 flex-wrap items-center gap-1 rounded-md border bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:ring-3 has-aria-invalid:ring-3 has-data-[slot=combobox-chip]:px-1", className),
156
+ className: cn("dark:bg-edge/30 border-edge focus-within:border-focus focus-within:ring-focus/50 has-aria-invalid:ring-destructive/30 has-aria-invalid:border-destructive flex min-h-8 flex-wrap items-center gap-1 rounded-md border bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:ring-3 has-aria-invalid:ring-3 has-data-[slot=combobox-chip]:px-1", className),
157
157
  ...props
158
158
  });
159
159
  }
@@ -165,7 +165,7 @@ function ComboboxChip({ className, children, showRemove = true, ...props }) {
165
165
  children: [children, showRemove ? /* @__PURE__ */ jsx(Combobox$1.ChipRemove, {
166
166
  render: /* @__PURE__ */ jsx(Button, {
167
167
  variant: "ghost",
168
- size: "icon-xs"
168
+ size: "icon-sm"
169
169
  }),
170
170
  className: "-ml-1 opacity-50 hover:opacity-100",
171
171
  "data-slot": "combobox-chip-remove",
@@ -26,7 +26,7 @@ declare function InputGroupAddon({
26
26
  ...props
27
27
  }: InputGroupAddonProps): _$react_jsx_runtime0.JSX.Element;
28
28
  declare const inputGroupButtonVariants: (props?: ({
29
- size?: "sm" | "xs" | "icon-xs" | "icon-sm" | null | undefined;
29
+ size?: "xs" | "sm" | "icon-xs" | "icon-sm" | null | undefined;
30
30
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
31
31
  declare function InputGroupButton({
32
32
  className,
@@ -10,7 +10,7 @@ function InputGroup({ className, ...props }) {
10
10
  return /* @__PURE__ */ jsx("div", {
11
11
  "data-slot": "input-group",
12
12
  role: "group",
13
- className: cn("border-edge dark:bg-edge/30 has-[[data-slot=input-group-control]:focus-visible]:border-focus has-[[data-slot=input-group-control]:focus-visible]:ring-focus/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-disabled:bg-edge/50 dark:has-disabled:bg-edge/80 group/input-group relative flex h-8 w-full min-w-0 items-center rounded-md border transition-colors outline-hidden in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 not-has-disabled:has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
13
+ className: cn("border-edge dark:bg-edge/30 has-[[data-slot=input-group-control]:focus-visible]:border-focus has-[[data-slot=input-group-control]:focus-visible]:ring-focus/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/30 has-[[data-slot][aria-invalid=true]]:border-destructive has-disabled:bg-edge/50 dark:has-disabled:bg-edge/80 group/input-group relative flex h-8 w-full min-w-0 items-center rounded-md border transition-colors outline-hidden in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 not-has-disabled:has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
14
14
  ...props
15
15
  });
16
16
  }
package/dist/input-otp.js CHANGED
@@ -26,7 +26,7 @@ function InputOTPSlot({ index, className, ...props }) {
26
26
  return /* @__PURE__ */ jsxs("div", {
27
27
  "data-slot": "input-otp-slot",
28
28
  "data-active": isActive || void 0,
29
- className: cn("border-edge dark:bg-edge/30 relative flex size-9 items-center justify-center border-y border-r text-sm motion-color outline-hidden first:rounded-l-md first:border-l last:rounded-r-md", "data-active:border-focus data-active:ring-3 data-active:ring-focus/50 data-active:z-10", "group-has-aria-invalid/input-otp:border-destructive group-has-aria-invalid/input-otp:data-active:ring-3 group-has-aria-invalid/input-otp:data-active:ring-destructive/20 dark:group-has-aria-invalid/input-otp:data-active:ring-destructive/40", className),
29
+ className: cn("border-edge dark:bg-edge/30 relative flex size-9 items-center justify-center border-y border-r text-sm motion-color outline-hidden first:rounded-l-md first:border-l last:rounded-r-md", "data-active:border-focus data-active:ring-3 data-active:ring-focus/50 data-active:z-10", "group-has-aria-invalid/input-otp:border-destructive group-has-aria-invalid/input-otp:data-active:ring-3 group-has-aria-invalid/input-otp:data-active:ring-destructive/30", className),
30
30
  ...props,
31
31
  children: [char, hasFakeCaret && /* @__PURE__ */ jsx("div", {
32
32
  className: "pointer-events-none absolute inset-0 flex items-center justify-center",
package/dist/input.js CHANGED
@@ -6,7 +6,7 @@ function Input({ className, type, ...props }) {
6
6
  return /* @__PURE__ */ jsx(Input$1, {
7
7
  type,
8
8
  "data-slot": "input",
9
- className: cn("dark:bg-edge/30 border-edge focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-edge/50 dark:disabled:bg-edge/80 file:text-contrast placeholder:text-soft h-8 w-full min-w-0 rounded-md border bg-transparent px-2.5 py-1 text-base transition-colors outline-hidden file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-3 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm", className),
9
+ className: cn("dark:bg-edge/30 border-edge focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive disabled:bg-edge/50 dark:disabled:bg-edge/80 file:text-contrast placeholder:text-soft h-8 w-full min-w-0 rounded-md border bg-transparent px-2.5 py-1 text-base transition-colors outline-hidden file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-3 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm", className),
10
10
  ...props
11
11
  });
12
12
  }
package/dist/item.d.ts CHANGED
@@ -8,7 +8,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
8
8
  //#region src/item.d.ts
9
9
  declare const itemVariants: (props?: ({
10
10
  variant?: "default" | "outline" | "muted" | null | undefined;
11
- size?: "default" | "sm" | "xs" | null | undefined;
11
+ size?: "default" | "xs" | "sm" | null | undefined;
12
12
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
13
13
  declare const itemMediaVariants: (props?: ({
14
14
  variant?: "default" | "icon" | "image" | null | undefined;
package/dist/radio.js CHANGED
@@ -6,7 +6,7 @@ import { Radio as Radio$1 } from "@base-ui/react/radio";
6
6
  function Radio({ className, ...props }) {
7
7
  return /* @__PURE__ */ jsx(Radio$1.Root, {
8
8
  "data-slot": "radio",
9
- className: cn("cursor-clickable border-edge dark:bg-edge/30 data-checked:bg-primary data-checked:text-white data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 dark:aria-invalid:border-destructive/50 group/radio peer relative flex aspect-square size-4 shrink-0 rounded-full border outline-hidden after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3", className),
9
+ className: cn("cursor-clickable border-edge dark:bg-edge/30 data-checked:bg-primary data-checked:text-white data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 group/radio peer relative flex aspect-square size-4 shrink-0 rounded-full border outline-hidden after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3", className),
10
10
  ...props,
11
11
  children: /* @__PURE__ */ jsx(RadioIndicator, {})
12
12
  });
package/dist/select.js CHANGED
@@ -48,7 +48,7 @@ function SelectTrigger({ className, size = "default", children, ...props }) {
48
48
  return /* @__PURE__ */ jsxs(Select$1.Trigger, {
49
49
  "data-slot": "select-trigger",
50
50
  "data-size": size,
51
- className: cn("border-edge data-placeholder:text-soft dark:bg-edge/30 dark:hover:bg-edge/50 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 flex w-fit items-center justify-between gap-1.5 rounded-md border bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap motion-color outline-hidden select-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-sm *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
51
+ className: cn("border-edge data-placeholder:text-soft dark:bg-edge/30 dark:hover:bg-edge/50 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive flex w-fit items-center justify-between gap-1.5 rounded-md border bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap motion-color outline-hidden select-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-sm *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
52
52
  ...props,
53
53
  children: [children, /* @__PURE__ */ jsx(Select$1.Icon, {
54
54
  "data-slot": "select-icon",
package/dist/styles.css CHANGED
@@ -7,7 +7,7 @@
7
7
  * @import '@waveso/ui/styles.css';
8
8
  *
9
9
  * This brings the `dark` variant, every theme token (override in your own
10
- * :root / .dark), motion tokens + recipes, the few self-hosted keyframe
10
+ * :root or a theme class), motion tokens + recipes, the few self-hosted keyframe
11
11
  * utilities the components need, and the `@source` rule. No other
12
12
  * library-related imports needed — zero runtime dependencies.
13
13
  */
@@ -17,13 +17,33 @@
17
17
  * file's location in node_modules/@waveso/ui/dist/. */
18
18
  @source "./";
19
19
 
20
- /* Tailwind v4 `dark:` variant — applies to the `.dark` element itself and any
21
- * descendant. `:where()` keeps utilities at their normal (zero-added) specificity
22
- * so the cascade is decided by source order, like every other Tailwind utility. */
23
- @custom-variant dark (&:where(.dark, .dark *));
20
+ /* Tailwind v4 `dark:` variant — fires on the DARK themes (`.graphite`, `.ink`)
21
+ * AND on the OS-dark default when no theme is pinned. `.paper` (light) always
22
+ * opts out. `:where()` keeps utilities at zero-added specificity so source order
23
+ * decides the cascade, like every Tailwind utility. A future dark theme gets
24
+ * added to both lists below. */
25
+ @custom-variant dark {
26
+ &:where(.graphite, .graphite *, .ink, .ink *) {
27
+ @slot;
28
+ }
29
+ @media (prefers-color-scheme: dark) {
30
+ &:where(
31
+ :root:not(.paper):not(.graphite):not(.ink),
32
+ :root:not(.paper):not(.graphite):not(.ink) *
33
+ ) {
34
+ @slot;
35
+ }
36
+ }
37
+ }
24
38
 
25
39
  /* ---------------------------------------------------------------------------
26
- * Light theme (default)
40
+ * Themes — named by identity: Paper (light) · Graphite (dark) · Ink (dark)
41
+ *
42
+ * Follows the OS by default: no class → Paper on a light system, Graphite on a
43
+ * dark one (`@media prefers-color-scheme`). Pin one by name — `.paper`,
44
+ * `.graphite`, `.ink` — and it always beats the OS. A theme class sits on the
45
+ * same <html> as `:root`, so every var() alias below (inverse, presence)
46
+ * re-resolves to the active theme.
27
47
  * ------------------------------------------------------------------------- */
28
48
 
29
49
  :root {
@@ -47,11 +67,50 @@
47
67
  --wave-900: oklch(0.284 0.088 255); /* #042954 */
48
68
  --wave-950: oklch(0.226 0.060 255); /* #061C37 */
49
69
 
50
- /* ── Neutral theme palettes (primitives) ─────────────────────────────────
51
- * Three complete neutral ramps, one per theme. The theme class on <html>
52
- * wires the ACTIVE one into the `--ui-*` alias (step 2); the semantic layer
53
- * reads `--ui-*`, never these directly. `--wave-*` (brand) is shared by all
54
- * three. Default theme = Graphite.
70
+ /* Status ramps — shared across every theme (mode-stable, like Wave).
71
+ * 500 = the locked status colour; the semantic layer picks a swatch per
72
+ * light/dark (base + hover) so components never carry a `dark:` for it. */
73
+ --success-50: oklch(0.975 0.014 155); /* #F0FAF3 */
74
+ --success-100: oklch(0.951 0.034 155); /* #DEF6E5 */
75
+ --success-200: oklch(0.911 0.068 155); /* #BFF0CE */
76
+ --success-300: oklch(0.857 0.113 155); /* #91E6B0 */
77
+ --success-400: oklch(0.797 0.165 155); /* #4FDB8D */
78
+ --success-500: oklch(0.710 0.185 155); /* #00C26B */
79
+ --success-600: oklch(0.620 0.176 155); /* #00A354 */
80
+ --success-700: oklch(0.504 0.151 155); /* #007C3B */
81
+ --success-800: oklch(0.388 0.119 155); /* #005626 */
82
+ --success-900: oklch(0.287 0.088 155); /* #003615 */
83
+ --success-950: oklch(0.200 0.060 155); /* #001D09 */
84
+
85
+ --warning-50: oklch(0.975 0.012 93); /* #F9F7EE */
86
+ --warning-100: oklch(0.962 0.029 93); /* #F9F2DD */
87
+ --warning-200: oklch(0.940 0.058 93); /* #F8EBC0 */
88
+ --warning-300: oklch(0.911 0.095 93); /* #F7E198 */
89
+ --warning-400: oklch(0.878 0.139 93); /* #F6D460 */
90
+ --warning-500: oklch(0.830 0.156 93); /* #EAC434 */
91
+ --warning-600: oklch(0.719 0.148 93); /* #C4A100 */
92
+ --warning-700: oklch(0.576 0.127 93); /* #937600 */
93
+ --warning-800: oklch(0.432 0.100 93); /* #634E00 */
94
+ --warning-900: oklch(0.308 0.075 93); /* #3D2E00 */
95
+ --warning-950: oklch(0.200 0.051 93); /* #1E1500 */
96
+
97
+ --destructive-50: oklch(0.975 0.015 25); /* #FFF3F2 */
98
+ --destructive-100: oklch(0.943 0.037 25); /* #FFE3E0 */
99
+ --destructive-200: oklch(0.890 0.074 25); /* #FFC8C2 */
100
+ --destructive-300: oklch(0.817 0.122 25); /* #FFA39B */
101
+ --destructive-400: oklch(0.736 0.178 25); /* #FF756E */
102
+ --destructive-500: oklch(0.620 0.200 25); /* #E64343 */
103
+ --destructive-600: oklch(0.546 0.190 25); /* #C72D32 */
104
+ --destructive-700: oklch(0.451 0.163 25); /* #9C1C21 */
105
+ --destructive-800: oklch(0.355 0.128 25); /* #701115 */
106
+ --destructive-900: oklch(0.272 0.096 25); /* #4C0A0C */
107
+ --destructive-950: oklch(0.200 0.065 25); /* #2D0606 */
108
+
109
+ /* ── Neutral ramps (primitives) ───────────────────────────────────────────
110
+ * Three complete neutral ramps. Each theme's semantic block below references
111
+ * exactly one of them directly: Paper → light, Graphite → default dark, Ink →
112
+ * night. `--wave-*` (brand) is shared by all three. Never used by components
113
+ * directly — only through the semantic tokens (`--foundation`, `--contrast`…).
55
114
  * ──────────────────────────────────────────────────────────────────────── */
56
115
 
57
116
  /* Graphite — neutral grey (default) */
@@ -95,79 +154,32 @@
95
154
  --paper-900: oklch(0.224 0.008 118); /* #1B1C18 */
96
155
  --paper-950: oklch(0.156 0.008 119); /* #0C0D09 */
97
156
 
98
- /* Active neutral alias — the theme class on <html> repoints these to one of
99
- * the ramps above (step 3). Default (no theme class) = Graphite. The semantic
100
- * layer below reads ONLY `--ui-*`; components never touch a ramp directly. */
101
- --ui-50: var(--graphite-50);
102
- --ui-100: var(--graphite-100);
103
- --ui-200: var(--graphite-200);
104
- --ui-300: var(--graphite-300);
105
- --ui-400: var(--graphite-400);
106
- --ui-500: var(--graphite-500);
107
- --ui-600: var(--graphite-600);
108
- --ui-700: var(--graphite-700);
109
- --ui-800: var(--graphite-800);
110
- --ui-900: var(--graphite-900);
111
- --ui-950: var(--graphite-950);
112
-
113
157
  /* ========================================================================
114
- * Semantic tokens — light (default). The spec's `.light` block lives in
115
- * `:root` so consumers get the light theme without needing a `.light` class.
158
+ * Theme-independent tokens — identical in Paper / Graphite / Ink. The
159
+ * per-theme semantic tokens (surfaces, text, borders, secondary, shadow,
160
+ * status) live in the theme blocks below; the aliases here (`inverse`,
161
+ * `presence`) read those, so they re-resolve to whatever theme is on <html>.
116
162
  * ====================================================================== */
117
163
 
118
- /* Backgrounds = elevation */
119
- --foundation: var(--ui-200);
120
- --surface: var(--ui-100);
121
- --elevated: var(--ui-50);
122
-
123
- /* Contrast = emphasis — highest-contrast text → muted → soft. */
124
- --contrast: var(--ui-950);
125
- --muted: var(--ui-600);
126
- --soft: var(--ui-500);
127
-
128
- /* Inverse — an inverted neutral pair (e.g. the dark tooltip). Aliases, so
129
- * they auto-flip with `.dark` (var() re-resolves at the use site). */
164
+ /* Inverse — an inverted neutral pair (e.g. the dark tooltip). Aliases of the
165
+ * active theme's own `--contrast` / `--foundation`. */
130
166
  --surface-inverse: var(--contrast);
131
167
  --contrast-inverse: var(--foundation);
132
168
 
133
- /* Brand — `primary` wired to the Wave ramp; `secondary` is the neutral fill
134
- * (secondary/ghost buttons, hovers, selected) at ui-300; `accent` is the
135
- * bright signal (Wave Blue 300, the strand now-glow). No per-fill on-color
136
- * tokens: text on the saturated fills is
137
- * `text-white`, text on the neutral `secondary` is `text-contrast`. */
169
+ /* Brand — `primary` = the Wave ramp; `accent` = the bright signal (Wave Blue
170
+ * 300, the strand now-glow). `secondary` (the neutral fill) is per-theme, so
171
+ * it lives in the theme blocks. Text on the saturated fills is `text-white`. */
138
172
  --primary: var(--wave-500);
139
- --secondary: var(--ui-300);
140
173
  --accent: var(--wave-300); /* the bright signal — the strand's "now" cursor glow */
141
174
 
142
- /* Borders = structure — mixed from the ACTIVE palette so they auto-match
143
- * every theme: a hairline of the darkest neutral in light mode. */
144
- --line: color-mix(in srgb, var(--ui-950) 7%, transparent);
145
- --edge: color-mix(in srgb, var(--ui-950) 14%, transparent);
146
- --solid: var(--ui-300);
147
-
148
175
  /* Rings = brand themed */
149
176
  --focus: var(--primary);
150
177
 
151
178
  /* Scrim — the dim behind modal overlays (dialog / drawer / alert backdrop). */
152
179
  --scrim: oklch(0 0 0 / 0.1);
153
180
 
154
- /* Shadow — two dials for the layered `shadow-*` scale: `--shadow-color` (oklch
155
- * components `L C H` — a deep cool-tinted near-black, never pure black which
156
- * reads heavy) and `--shadow-strength` (per-layer alpha / intensity). Both
157
- * resolve per :root/.dark, so retinting OR dimming every shadow is one token.
158
- * For a colored surface set a named tint, e.g. `--shadow-color-primary`. */
159
- --shadow-color: 0.159 0.021 263; /* was hsl(220 45% 6%) */
160
- --shadow-strength: 0.22;
161
-
162
- /* Status */
163
- --destructive: oklch(0.620 0.200 25);
164
- --success: oklch(0.710 0.185 155); /* cool emerald — distinct from the warning yellow, kept ownable (off the Apple/Tailwind default) */
165
- --warning: oklch(0.830 0.156 93);
166
- --info: var(--wave-500); /* the one blue — Wave Blue (= --primary / --focus) */
167
-
168
- /* Presence */
169
- /* Presence dots reuse the status colours — aliased, not duplicated, so they
170
- * stay in sync (and follow a consumer's `--success`/etc. override). */
181
+ /* Presence — dots reuse the status colours (aliased, not duplicated, so they
182
+ * stay in sync and follow a consumer's `--success`/etc. override). */
171
183
  --presence-online: var(--success);
172
184
  --presence-away: var(--warning);
173
185
  --presence-busy: var(--destructive);
@@ -219,73 +231,102 @@
219
231
  }
220
232
 
221
233
  /* ---------------------------------------------------------------------------
222
- * Dark theme
234
+ * Paper — the LIGHT theme, and the default. The single source for Paper's
235
+ * per-theme tokens, shared by `:root` (the default) and `.paper` (explicit —
236
+ * what a theme toggle sets, or to override an inherited dark theme in a nested
237
+ * scope).
238
+ * ------------------------------------------------------------------------- */
239
+ :root,
240
+ .paper {
241
+ --foundation: var(--paper-200);
242
+ --surface: var(--paper-100);
243
+ --elevated: var(--paper-50);
244
+ --contrast: var(--paper-950);
245
+ --muted: var(--paper-600);
246
+ --soft: var(--paper-500);
247
+ --secondary: var(--paper-300);
248
+ --line: color-mix(in srgb, var(--paper-950) 7%, transparent);
249
+ --edge: color-mix(in srgb, var(--paper-950) 14%, transparent);
250
+ --solid: var(--paper-300);
251
+ --shadow-color: 0.159 0.021 263;
252
+ --shadow-strength: 0.22;
253
+ --destructive: oklch(0.620 0.200 25);
254
+ --success: oklch(0.710 0.185 155);
255
+ --warning: oklch(0.830 0.156 93);
256
+ --info: var(--wave-500);
257
+ }
258
+
259
+ /* ---------------------------------------------------------------------------
260
+ * Graphite — the DARK theme (neutral). Two ways in: the OS-dark default (the
261
+ * `@media` block, active only when no theme is pinned) and an explicit
262
+ * `.graphite` (what a theme toggle sets). Same tokens both ways — a media query
263
+ * can't be folded into a plain class selector, so they're stated once each.
264
+ * Status brightens and the shadow dims for the dark surface; any pinned theme
265
+ * beats the OS.
223
266
  * ------------------------------------------------------------------------- */
267
+ @media (prefers-color-scheme: dark) {
268
+ :root:not(.paper):not(.graphite):not(.ink) {
269
+ --foundation: var(--graphite-950);
270
+ --surface: var(--graphite-900);
271
+ --elevated: var(--graphite-800);
272
+ --contrast: var(--graphite-100);
273
+ --muted: var(--graphite-400);
274
+ --soft: var(--graphite-600);
275
+ --secondary: var(--graphite-700);
276
+ --line: color-mix(in srgb, var(--graphite-50) 5%, transparent);
277
+ --edge: color-mix(in srgb, var(--graphite-50) 13%, transparent);
278
+ --solid: var(--graphite-700);
279
+ --shadow-color: 0.125 0.011 259;
280
+ --shadow-strength: 0.18;
281
+ --destructive: oklch(0.630 0.200 25);
282
+ --success: oklch(0.735 0.185 155);
283
+ --warning: oklch(0.850 0.156 93);
284
+ --info: var(--wave-400);
285
+ }
286
+ }
224
287
 
225
- .dark {
226
- /* Backgrounds = elevation */
227
- --foundation: var(--ui-950);
228
- --surface: var(--ui-900);
229
- --elevated: var(--ui-800);
230
-
231
- /* Contrast = emphasis */
232
- --contrast: var(--ui-100);
233
- --muted: var(--ui-400);
234
- --soft: var(--ui-600);
235
-
236
- /* Brand — only `secondary` differs from light; mirrored to ui-700 so the
237
- * neutral fill stands out against the dark surfaces. primary / accent /
238
- * inverse / focus auto-flip or stay constant via the `:root` definitions. */
239
- --secondary: var(--ui-700);
240
-
241
- /* Borders = structure — a hairline of the lightest neutral (auto-matches theme). */
242
- --line: color-mix(in srgb, var(--ui-50) 5%, transparent);
243
- --edge: color-mix(in srgb, var(--ui-50) 13%, transparent);
244
- --solid: var(--ui-700);
245
-
246
- /* Shadow — darker tint, lower strength: a near-black shadow on a dark
247
- * surface reads heavier than on white, so dim it. */
248
- --shadow-color: 0.125 0.011 259; /* was hsl(220 40% 3%) */
288
+ .graphite {
289
+ --foundation: var(--graphite-950);
290
+ --surface: var(--graphite-900);
291
+ --elevated: var(--graphite-800);
292
+ --contrast: var(--graphite-100);
293
+ --muted: var(--graphite-400);
294
+ --soft: var(--graphite-600);
295
+ --secondary: var(--graphite-700);
296
+ --line: color-mix(in srgb, var(--graphite-50) 5%, transparent);
297
+ --edge: color-mix(in srgb, var(--graphite-50) 13%, transparent);
298
+ --solid: var(--graphite-700);
299
+ --shadow-color: 0.125 0.011 259;
249
300
  --shadow-strength: 0.18;
250
-
251
- /* Status */
252
- /* Slightly BRIGHTER than the :root (light) values.
253
- * Never darker, or the colour recedes on dark surfaces (the old reversal bug). */
254
301
  --destructive: oklch(0.630 0.200 25);
255
- --success: oklch(0.735 0.185 155); /* green A, hue-aware lift (+.025) brighter than light */
302
+ --success: oklch(0.735 0.185 155);
256
303
  --warning: oklch(0.850 0.156 93);
257
- --info: var(--wave-400); /* brighter Wave Blue for legible text-info on dark surfaces */
258
-
259
- /* Presence */
260
- --presence-online: var(--success);
261
- --presence-away: var(--warning);
262
- --presence-busy: var(--destructive);
263
- --presence-invisible: var(--foundation); /* re-resolves to the dark foundation */
304
+ --info: var(--wave-400);
264
305
  }
265
306
 
266
307
  /* ---------------------------------------------------------------------------
267
- * Theme presets — each repoints the `--ui-*` alias to one neutral ramp. Put a
268
- * class on a root element: `<html class="theme-paper">`. Graphite is also the bare
269
- * `:root` default, so `theme-graphite` is optional/explicit. Light vs dark is the
270
- * separate `.dark` axis — they compose (e.g. `class="theme-paper dark"`).
308
+ * Ink — the premium night theme. Opt-in only: `<html class="ink">`.
309
+ * A complete, self-contained dark theme (deep navy), separate from the Graphite
310
+ * default dark. It's dark, so it drives the `dark:` variant too. primary /
311
+ * accent / focus / inverse / presence stay constant or re-resolve via `:root`.
271
312
  * ------------------------------------------------------------------------- */
272
- .theme-graphite {
273
- --ui-50: var(--graphite-50); --ui-100: var(--graphite-100); --ui-200: var(--graphite-200);
274
- --ui-300: var(--graphite-300); --ui-400: var(--graphite-400); --ui-500: var(--graphite-500);
275
- --ui-600: var(--graphite-600); --ui-700: var(--graphite-700); --ui-800: var(--graphite-800);
276
- --ui-900: var(--graphite-900); --ui-950: var(--graphite-950);
277
- }
278
- .theme-ink {
279
- --ui-50: var(--ink-50); --ui-100: var(--ink-100); --ui-200: var(--ink-200);
280
- --ui-300: var(--ink-300); --ui-400: var(--ink-400); --ui-500: var(--ink-500);
281
- --ui-600: var(--ink-600); --ui-700: var(--ink-700); --ui-800: var(--ink-800);
282
- --ui-900: var(--ink-900); --ui-950: var(--ink-950);
283
- }
284
- .theme-paper {
285
- --ui-50: var(--paper-50); --ui-100: var(--paper-100); --ui-200: var(--paper-200);
286
- --ui-300: var(--paper-300); --ui-400: var(--paper-400); --ui-500: var(--paper-500);
287
- --ui-600: var(--paper-600); --ui-700: var(--paper-700); --ui-800: var(--paper-800);
288
- --ui-900: var(--paper-900); --ui-950: var(--paper-950);
313
+ .ink {
314
+ --foundation: var(--ink-950);
315
+ --surface: var(--ink-900);
316
+ --elevated: var(--ink-800);
317
+ --contrast: var(--ink-100);
318
+ --muted: var(--ink-400);
319
+ --soft: var(--ink-600);
320
+ --secondary: var(--ink-700);
321
+ --line: color-mix(in srgb, var(--ink-50) 5%, transparent);
322
+ --edge: color-mix(in srgb, var(--ink-50) 13%, transparent);
323
+ --solid: var(--ink-700);
324
+ --shadow-color: 0.125 0.011 259;
325
+ --shadow-strength: 0.18;
326
+ --destructive: oklch(0.630 0.200 25);
327
+ --success: oklch(0.735 0.185 155);
328
+ --warning: oklch(0.850 0.156 93);
329
+ --info: var(--wave-400);
289
330
  }
290
331
 
291
332
  /* ---------------------------------------------------------------------------
@@ -350,7 +391,7 @@
350
391
  }
351
392
 
352
393
  /* Shadow scale — layered, tinted by `--shadow-color` and dimmed by
353
- * `--shadow-strength` (both resolve per :root/.dark, so retinting or dimming
394
+ * `--shadow-strength` (both resolve per theme, so retinting or dimming
354
395
  * every shadow is one token). Tiers differ by layer count + spread, not alpha.
355
396
  * Overrides Tailwind's shadow-sm/md/lg. */
356
397
  @theme {
package/dist/switch.js CHANGED
@@ -4,7 +4,7 @@ import { jsx } from "react/jsx-runtime";
4
4
  import { cva } from "class-variance-authority";
5
5
  import { Switch as Switch$1 } from "@base-ui/react/switch";
6
6
  //#region src/switch.tsx
7
- const switchVariants = cva("cursor-clickable data-checked:bg-primary data-unchecked:bg-edge focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 dark:data-unchecked:bg-edge/80 peer relative inline-flex shrink-0 items-center rounded-full border border-transparent motion-color outline-hidden after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 aria-invalid:ring-3 data-disabled:cursor-not-allowed data-disabled:opacity-50", {
7
+ const switchVariants = cva("cursor-clickable data-checked:bg-primary data-unchecked:bg-edge focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive dark:data-unchecked:bg-edge/80 peer relative inline-flex shrink-0 items-center rounded-full border border-transparent motion-color outline-hidden after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 aria-invalid:ring-3 data-disabled:cursor-not-allowed data-disabled:opacity-50", {
8
8
  variants: { size: {
9
9
  default: "h-[18.4px] w-[32px]",
10
10
  sm: "h-[14px] w-[24px]"
package/dist/textarea.js CHANGED
@@ -9,7 +9,7 @@ function Textarea({ className, onChange, onValueChange, ...props }) {
9
9
  }
10
10
  return /* @__PURE__ */ jsx("textarea", {
11
11
  "data-slot": "textarea",
12
- className: cn("border-edge dark:bg-edge/30 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 resize-none disabled:bg-edge/50 disabled:cursor-not-allowed dark:disabled:bg-edge/80 placeholder:text-soft flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-2.5 py-2 text-base transition-colors outline-hidden focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm", className),
12
+ className: cn("border-edge dark:bg-edge/30 focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive resize-none disabled:bg-edge/50 disabled:cursor-not-allowed dark:disabled:bg-edge/80 placeholder:text-soft flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-2.5 py-2 text-base transition-colors outline-hidden focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm", className),
13
13
  onChange: handleChange,
14
14
  ...props
15
15
  });
package/dist/toggle.js CHANGED
@@ -4,7 +4,7 @@ import { jsx } from "react/jsx-runtime";
4
4
  import { cva } from "class-variance-authority";
5
5
  import { Toggle as Toggle$1 } from "@base-ui/react/toggle";
6
6
  //#region src/toggle.tsx
7
- const toggleVariants = cva("cursor-clickable hover:text-contrast focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-pressed:bg-secondary gap-1 rounded-md text-sm font-medium motion-color [&_svg:not([class*='size-'])]:size-4 group/toggle hover:bg-secondary inline-flex items-center justify-center whitespace-nowrap outline-hidden focus-visible:ring-3 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", {
7
+ const toggleVariants = cva("cursor-clickable hover:text-contrast focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-destructive/30 aria-invalid:border-destructive data-pressed:bg-secondary gap-1 rounded-md text-sm font-medium motion-color [&_svg:not([class*='size-'])]:size-4 group/toggle hover:bg-secondary inline-flex items-center justify-center whitespace-nowrap outline-hidden focus-visible:ring-3 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", {
8
8
  variants: {
9
9
  variant: {
10
10
  default: "bg-transparent",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waveso/ui",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Wave UI component library built on Base UI and Tailwind CSS",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -55,6 +55,7 @@
55
55
  "clean": "rm -rf dist",
56
56
  "storybook": "storybook dev -p 6006",
57
57
  "build-storybook": "storybook build",
58
+ "chromatic": "chromatic --exit-zero-on-changes",
58
59
  "prepublishOnly": "npm run build",
59
60
  "changeset": "changeset",
60
61
  "version": "changeset version",
@@ -98,6 +99,7 @@
98
99
  "@testing-library/user-event": "^14.6.1",
99
100
  "@types/react": "^19",
100
101
  "@types/react-dom": "^19",
102
+ "chromatic": "^18.0.1",
101
103
  "class-variance-authority": "^0.7.1",
102
104
  "clsx": "^2.1.1",
103
105
  "input-otp": "^1.4.2",