@waveso/ui 0.15.1 → 0.17.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.
Files changed (87) hide show
  1. package/README.md +13 -12
  2. package/dist/accordion.js +2 -2
  3. package/dist/action-bar.js +4 -4
  4. package/dist/alert-dialog.js +5 -5
  5. package/dist/alert.d.ts +8 -1
  6. package/dist/alert.js +13 -4
  7. package/dist/animate.d.ts +1 -1
  8. package/dist/animate.js +2 -9
  9. package/dist/autocomplete.js +3 -3
  10. package/dist/avatar.d.ts +1 -1
  11. package/dist/avatar.js +4 -4
  12. package/dist/badge.d.ts +1 -1
  13. package/dist/badge.js +6 -6
  14. package/dist/button-group.d.ts +4 -2
  15. package/dist/button-group.js +5 -4
  16. package/dist/button.d.ts +1 -1
  17. package/dist/button.js +6 -6
  18. package/dist/card.d.ts +11 -4
  19. package/dist/card.js +27 -14
  20. package/dist/checkbox.js +2 -2
  21. package/dist/combobox.js +4 -4
  22. package/dist/context-menu.d.ts +2 -1
  23. package/dist/context-menu.js +14 -14
  24. package/dist/dialog.js +5 -5
  25. package/dist/drawer.js +1 -1
  26. package/dist/encrypted-text.d.ts +15 -1
  27. package/dist/encrypted-text.js +205 -67
  28. package/dist/field.d.ts +21 -3
  29. package/dist/field.js +36 -8
  30. package/dist/fieldset.d.ts +14 -0
  31. package/dist/fieldset.js +26 -0
  32. package/dist/form.d.ts +14 -14
  33. package/dist/form.js +7 -4
  34. package/dist/glyph-matrix.d.ts +25 -0
  35. package/dist/glyph-matrix.js +266 -0
  36. package/dist/gradient-reveal-text.d.ts +3 -3
  37. package/dist/gradient-reveal-text.js +8 -8
  38. package/dist/input-group.js +1 -1
  39. package/dist/input-otp.d.ts +3 -3
  40. package/dist/input-otp.js +2 -2
  41. package/dist/input.js +1 -1
  42. package/dist/item.d.ts +1 -1
  43. package/dist/item.js +17 -11
  44. package/dist/kbd.d.ts +1 -1
  45. package/dist/kbd.js +2 -2
  46. package/dist/label.js +1 -1
  47. package/dist/lib/merge-refs.d.ts +9 -0
  48. package/dist/lib/merge-refs.js +16 -0
  49. package/dist/lib/utils.js +7 -0
  50. package/dist/masonry.d.ts +1 -1
  51. package/dist/masonry.js +4 -2
  52. package/dist/menu.d.ts +2 -1
  53. package/dist/menu.js +7 -7
  54. package/dist/menubar.js +1 -1
  55. package/dist/pagination.js +1 -1
  56. package/dist/popover.js +1 -1
  57. package/dist/preview-card.js +1 -1
  58. package/dist/progress.js +2 -2
  59. package/dist/radio-group.js +1 -1
  60. package/dist/radio.js +2 -2
  61. package/dist/resizable.d.ts +43 -0
  62. package/dist/resizable.js +53 -0
  63. package/dist/scroll-area.d.ts +13 -2
  64. package/dist/scroll-area.js +26 -7
  65. package/dist/select.js +4 -4
  66. package/dist/separator.js +1 -1
  67. package/dist/sidebar.js +12 -12
  68. package/dist/slider.js +3 -3
  69. package/dist/spinner.d.ts +7 -0
  70. package/dist/spinner.js +24 -6
  71. package/dist/styles.css +581 -194
  72. package/dist/swipe-deck.d.ts +98 -0
  73. package/dist/swipe-deck.js +931 -0
  74. package/dist/switch.js +6 -6
  75. package/dist/table.d.ts +7 -1
  76. package/dist/table.js +40 -9
  77. package/dist/tabs.js +3 -3
  78. package/dist/textarea.js +1 -1
  79. package/dist/toast.js +4 -4
  80. package/dist/toggle-group.js +3 -3
  81. package/dist/toggle.d.ts +1 -1
  82. package/dist/toggle.js +11 -6
  83. package/dist/tooltip.d.ts +3 -1
  84. package/dist/tooltip.js +10 -6
  85. package/dist/video-text.d.ts +25 -0
  86. package/dist/video-text.js +147 -0
  87. package/package.json +6 -1
package/README.md CHANGED
@@ -85,11 +85,13 @@ Wave pays close attention to token taxonomy. Surfaces encode elevation; borders
85
85
  - `--muted` — body text, icons, any mark
86
86
  - `--soft` — placeholders, hints
87
87
 
88
- ### Borders
88
+ ### Form
89
89
 
90
- - `--line` — subtle separators
91
- - `--edge` — component boundary
92
- - `--solid` — structural definition
90
+ The theme's foreground made translucent, at three strengths — the way a draughtsman renders a form. Each is translucent, so it reads the same on any surface, and each keeps one job on a border or a background.
91
+
92
+ - `--contour` — where a shape ends: hairline borders, separators, dividers
93
+ - `--highlight` — where attention lands: hovered, keyboard-highlighted and open items
94
+ - `--shade` — what gives a control its body: field and track fills, and the intense border (control outlines, layout regions)
93
95
 
94
96
  ### Ring
95
97
 
@@ -105,22 +107,21 @@ Wave pays close attention to token taxonomy. Surfaces encode elevation; borders
105
107
 
106
108
  This is the sophisticated move most libraries skip.
107
109
 
108
- Wave biases heavily toward **transparent (alpha) borders as the default**, with a **solid token reserved for functional states**.
110
+ Wave uses **transparent (alpha) borders only**: `contour` by default, and `shade` where a boundary has to be intense.
109
111
 
110
- Wave's palette behaves like a layered _material system_, not a flat UI. Dark surfaces, a soft text hierarchy, and subtle elevation shifts (low-contrast steps) mean borders should not introduce a new "color layer" — that would break the illusion of depth — yet structure still needs a solid option.
112
+ Wave's palette behaves like a layered _material system_, not a flat UI. Dark surfaces, a soft text hierarchy, and subtle elevation shifts (low-contrast steps) mean borders should not introduce a new "color layer" — that would break the illusion of depth — yet structure still needs an intense option.
111
113
 
112
114
  Alpha borders **inherit the surface beneath them**, take the **content color as their luminance source**, keep hue consistent across surfaces, and scale naturally.
113
115
 
114
- Solid borders compete with the surface ladder and create visual "grid noise" if overused, so use them sparingly. Overusing them flattens everything into "outlined boxes" with reduced perceived elevation — the "Bootstrap feel."
116
+ Intense borders compete with the surface ladder and create visual "grid noise" if overused, so use them sparingly. Overusing them flattens everything into "outlined boxes" with reduced perceived elevation — the "Bootstrap feel."
115
117
 
116
- The default **alpha** borders are ideal for:
118
+ The default **`contour`** borders are ideal for:
117
119
 
118
120
  - Cards
119
121
  - Panels
120
- - Inputs
121
122
  - Subtle separators
122
123
 
123
- The **solid** borders are ideal for:
124
+ The intense **`shade`** borders are ideal for:
124
125
 
125
126
  - Layout definition (sidebar vs. content)
126
127
  - Component grouping
@@ -129,8 +130,8 @@ The **solid** borders are ideal for:
129
130
 
130
131
  **Rule of thumb:**
131
132
 
132
- - If it separates **surface from surface** → alpha border
133
- - If it separates **layout regions** → solid border
133
+ - If it separates **surface from surface** → `contour`
134
+ - If it separates **layout regions** → `shade`
134
135
  - If it indicates **interaction / state** → colored alpha border
135
136
 
136
137
  ---
package/dist/accordion.js CHANGED
@@ -14,7 +14,7 @@ function Accordion({ className, ...props }) {
14
14
  function AccordionItem({ className, ...props }) {
15
15
  return /* @__PURE__ */ jsx(Accordion$1.Item, {
16
16
  "data-slot": "accordion-item",
17
- className: cn("not-last:border-b border-edge", className),
17
+ className: cn("not-last:border-b border-shade", className),
18
18
  ...props
19
19
  });
20
20
  }
@@ -24,7 +24,7 @@ function AccordionTrigger({ className, children, ...props }) {
24
24
  className: "flex",
25
25
  children: /* @__PURE__ */ jsxs(Accordion$1.Trigger, {
26
26
  "data-slot": "accordion-trigger",
27
- className: cn("cursor-clickable focus-visible:ring-focus/50 focus-visible:border-focus focus-visible:after:border-focus **:data-[slot=accordion-trigger-icon]:text-muted group/accordion-trigger relative flex flex-1 items-start justify-between rounded-md border border-transparent py-2.5 text-left text-sm font-medium motion-color outline-hidden hover:underline focus-visible:ring-3 aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4", className),
27
+ className: cn("cursor-clickable focus-visible:ring-focus/50 focus-visible:border-focus focus-visible:after:border-focus **:data-[slot=accordion-trigger-icon]:text-muted group/accordion-trigger relative flex flex-1 items-start justify-between rounded-md border border-transparent py-2.5 text-left text-sm font-medium motion-color outline-hidden hover:underline focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4", className),
28
28
  ...props,
29
29
  children: [
30
30
  children,
@@ -209,10 +209,10 @@ function ActionBarProvider({ children, message = "You have unsaved changes", plu
209
209
  className: "fixed bottom-6 left-1/2 z-50",
210
210
  children: /* @__PURE__ */ jsxs("div", {
211
211
  "data-slot": "action-bar-content",
212
- className: cn("flex items-center gap-6 rounded-lg border border-line/60 bg-surface px-5 py-2.5 shadow-lg ring-1 ring-line", className),
212
+ className: cn("flex items-center gap-6 rounded-lg border border-contour/60 bg-surface px-5 py-2.5 shadow-lg ring-1 ring-contour", className),
213
213
  children: [/* @__PURE__ */ jsx("span", {
214
214
  "data-slot": "action-bar-message",
215
- className: cn("whitespace-nowrap text-sm font-medium", saveError ? "text-destructive" : "text-contrast"),
215
+ className: cn("whitespace-nowrap text-sm font-medium", saveError ? "text-danger" : "text-contrast"),
216
216
  children: saveError ? text.saveError : displayMessage
217
217
  }), /* @__PURE__ */ jsxs("div", {
218
218
  "data-slot": "action-bar-actions",
@@ -222,7 +222,7 @@ function ActionBarProvider({ children, message = "You have unsaved changes", plu
222
222
  variant: "ghost",
223
223
  disabled: anySaving,
224
224
  onClick: handleResetAll,
225
- className: "h-9 px-3 text-sm hover:text-destructive",
225
+ className: "h-9 px-3 text-sm",
226
226
  children: text.reset
227
227
  }), /* @__PURE__ */ jsx(Button, {
228
228
  type: "button",
@@ -231,7 +231,7 @@ function ActionBarProvider({ children, message = "You have unsaved changes", plu
231
231
  onClick: handleSaveAll,
232
232
  className: "h-9 px-4 text-sm",
233
233
  children: anySaving ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Spinner, { className: "mr-1.5 h-3.5 w-3.5" }), text.saving] }) : /* @__PURE__ */ jsxs(Fragment, { children: [text.save, /* @__PURE__ */ jsx(Kbd, {
234
- className: "ml-1.5",
234
+ className: "ms-1.5 bg-transparent text-current",
235
235
  children: isMac ? "⌘S" : "Ctrl+S"
236
236
  })] })
237
237
  })]
@@ -33,35 +33,35 @@ function AlertDialogContent({ className, size = "default", ...props }) {
33
33
  return /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [/* @__PURE__ */ jsx(AlertDialogOverlay, {}), /* @__PURE__ */ jsx(AlertDialog$1.Popup, {
34
34
  "data-slot": "alert-dialog-content",
35
35
  "data-size": size,
36
- className: cn("motion-scale-lg bg-foundation ring-contrast/10 group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg p-4 ring-1 outline-hidden data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=lg]:max-w-lg data-[size=xl]:max-w-xl data-[size=default]:sm:max-w-sm data-[size=lg]:sm:max-w-lg data-[size=xl]:sm:max-w-xl", className),
36
+ className: cn("motion-scale-lg bg-foundation ring-contrast/10 group/alert-dialog-content fixed top-1/2 start-1/2 z-50 grid w-[calc(100%-2rem)] -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 gap-6 rounded-lg p-6 ring-1 outline-hidden data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=lg]:max-w-lg data-[size=xl]:max-w-xl data-[size=default]:sm:max-w-sm data-[size=lg]:sm:max-w-lg data-[size=xl]:sm:max-w-xl shadow-lg", className),
37
37
  ...props
38
38
  })] });
39
39
  }
40
40
  function AlertDialogHeader({ className, ...props }) {
41
41
  return /* @__PURE__ */ jsx("div", {
42
42
  "data-slot": "alert-dialog-header",
43
- className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr] group-data-[size=lg]/alert-dialog-content:place-items-start group-data-[size=lg]/alert-dialog-content:text-left group-data-[size=xl]/alert-dialog-content:place-items-start group-data-[size=xl]/alert-dialog-content:text-left", className),
43
+ className: cn("grid grid-rows-[auto_1fr] place-items-center gap-3 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-start sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr] group-data-[size=lg]/alert-dialog-content:place-items-start group-data-[size=lg]/alert-dialog-content:text-start group-data-[size=xl]/alert-dialog-content:place-items-start group-data-[size=xl]/alert-dialog-content:text-start", className),
44
44
  ...props
45
45
  });
46
46
  }
47
47
  function AlertDialogFooter({ className, ...props }) {
48
48
  return /* @__PURE__ */ jsx("div", {
49
49
  "data-slot": "alert-dialog-footer",
50
- className: cn("bg-secondary/50 -mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-lg border-t border-line p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end", className),
50
+ className: cn("flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end", className),
51
51
  ...props
52
52
  });
53
53
  }
54
54
  function AlertDialogMedia({ className, ...props }) {
55
55
  return /* @__PURE__ */ jsx("div", {
56
56
  "data-slot": "alert-dialog-media",
57
- className: cn("bg-secondary mb-2 inline-flex size-10 items-center justify-center rounded-md sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6", className),
57
+ className: cn("bg-secondary mb-2 inline-flex size-16 items-center justify-center rounded-md sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8", className),
58
58
  ...props
59
59
  });
60
60
  }
61
61
  function AlertDialogTitle({ className, ...props }) {
62
62
  return /* @__PURE__ */ jsx(AlertDialog$1.Title, {
63
63
  "data-slot": "alert-dialog-title",
64
- className: cn("text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className),
64
+ className: cn("text-lg font-medium leading-none sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className),
65
65
  ...props
66
66
  });
67
67
  }
package/dist/alert.d.ts CHANGED
@@ -2,12 +2,19 @@ import * as React from "react";
2
2
  import { VariantProps } from "class-variance-authority";
3
3
  //#region src/alert.d.ts
4
4
  declare const alertVariants: (props?: ({
5
- variant?: "default" | "destructive" | null | undefined;
5
+ variant?: "danger" | "default" | "info" | "success" | "warning" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  type AlertProps = React.ComponentProps<"div"> & VariantProps<typeof alertVariants>;
8
8
  type AlertTitleProps = React.ComponentProps<"div">;
9
9
  type AlertDescriptionProps = React.ComponentProps<"div">;
10
10
  type AlertActionProps = React.ComponentProps<"div">;
11
+ /**
12
+ * A callout for information the reader should notice. It has no live role
13
+ * by default: pass `role="alert"` for an urgent message that appears while
14
+ * someone is using the page (an error after an action), which screen readers
15
+ * announce at once, or `role="status"` for a polite update. A static callout
16
+ * needs neither.
17
+ */
11
18
  declare function Alert({ className, variant, ...props }: AlertProps): React.JSX.Element;
12
19
  declare function AlertTitle({ className, ...props }: AlertTitleProps): React.JSX.Element;
13
20
  declare function AlertDescription({ className, ...props }: AlertDescriptionProps): React.JSX.Element;
package/dist/alert.js CHANGED
@@ -2,17 +2,26 @@ import { cn } from "./lib/utils.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { cva } from "class-variance-authority";
4
4
  //#region src/alert.tsx
5
- const alertVariants = cva("grid gap-0.5 rounded-md border border-edge px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-data-[icon]:grid-cols-[auto_1fr] has-data-[icon]:gap-x-2 *:data-[icon]:col-start-1 *:data-[icon]:row-span-2 *:data-[icon]:translate-y-0.5 *:data-[icon]:text-current *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert", {
5
+ const alertVariants = cva("grid gap-0.5 rounded-md border border-shade px-4 py-3 text-start text-sm has-data-[slot=alert-action]:pe-18 has-data-[icon]:grid-cols-[auto_1fr] has-data-[icon]:gap-x-2.5 *:data-[icon]:col-start-1 *:data-[icon]:row-span-2 *:data-[icon]:translate-y-0.5 *:data-[icon]:text-current *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert", {
6
6
  variants: { variant: {
7
7
  default: "bg-surface text-contrast",
8
- destructive: "text-destructive bg-surface *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current"
8
+ info: "bg-surface text-contrast *:data-[icon]:text-info *:[svg]:text-info",
9
+ success: "bg-surface text-contrast *:data-[icon]:text-success *:[svg]:text-success",
10
+ warning: "bg-surface text-contrast *:data-[icon]:text-warning *:[svg]:text-warning",
11
+ danger: "bg-surface text-contrast *:data-[icon]:text-danger *:[svg]:text-danger"
9
12
  } },
10
13
  defaultVariants: { variant: "default" }
11
14
  });
15
+ /**
16
+ * A callout for information the reader should notice. It has no live role
17
+ * by default: pass `role="alert"` for an urgent message that appears while
18
+ * someone is using the page (an error after an action), which screen readers
19
+ * announce at once, or `role="status"` for a polite update. A static callout
20
+ * needs neither.
21
+ */
12
22
  function Alert({ className, variant, ...props }) {
13
23
  return /* @__PURE__ */ jsx("div", {
14
24
  "data-slot": "alert",
15
- role: "alert",
16
25
  className: cn(alertVariants({ variant }), className),
17
26
  ...props
18
27
  });
@@ -34,7 +43,7 @@ function AlertDescription({ className, ...props }) {
34
43
  function AlertAction({ className, ...props }) {
35
44
  return /* @__PURE__ */ jsx("div", {
36
45
  "data-slot": "alert-action",
37
- className: cn("absolute top-2 right-2", className),
46
+ className: cn("absolute top-2.5 end-3", className),
38
47
  ...props
39
48
  });
40
49
  }
package/dist/animate.d.ts CHANGED
@@ -138,7 +138,7 @@ declare function Stagger({ children, interval, baseDelay }: StaggerProps): impor
138
138
  * @example
139
139
  * ```tsx
140
140
  * <Pulse>
141
- * <span className="size-3 rounded-full bg-green-500" />
141
+ * <span className="size-3 rounded-full bg-success" />
142
142
  * </Pulse>
143
143
  * ```
144
144
  */
package/dist/animate.js CHANGED
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { mergeRefs } from "./lib/merge-refs.js";
2
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
4
  import { Children, cloneElement, isValidElement, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
4
5
  import { useInView, useReducedMotion } from "motion/react";
@@ -76,14 +77,6 @@ function buildStyles(opts) {
76
77
  hasFilter: blurPx > 0
77
78
  };
78
79
  }
79
- function mergeRefs(...refs) {
80
- return (el) => {
81
- refs.forEach((ref) => {
82
- if (typeof ref === "function") ref(el);
83
- else if (ref && typeof ref === "object") ref.current = el;
84
- });
85
- };
86
- }
87
80
  function getTransitionParams(transition, useSpring, fallbackDuration = .15) {
88
81
  return {
89
82
  duration: transition?.duration ?? fallbackDuration,
@@ -256,7 +249,7 @@ function Stagger({ children, interval = .08, baseDelay = 0 }) {
256
249
  * @example
257
250
  * ```tsx
258
251
  * <Pulse>
259
- * <span className="size-3 rounded-full bg-green-500" />
252
+ * <span className="size-3 rounded-full bg-success" />
260
253
  * </Pulse>
261
254
  * ```
262
255
  */
@@ -69,7 +69,7 @@ function AutocompletePositioner({ className, ...props }) {
69
69
  function AutocompletePopup({ className, ...props }) {
70
70
  return /* @__PURE__ */ jsx(Autocomplete$1.Popup, {
71
71
  "data-slot": "autocomplete-popup",
72
- className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 group/autocomplete-content relative max-h-(--available-height) min-w-(--anchor-width) max-w-(--available-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md shadow-md ring-1", className),
72
+ className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 group/autocomplete-content relative max-h-(--available-height) min-w-(--anchor-width) max-w-(--available-width) overflow-x-hidden overflow-y-auto rounded-md shadow-md ring-1", className),
73
73
  ...props
74
74
  });
75
75
  }
@@ -111,14 +111,14 @@ function AutocompleteRow({ className, ...props }) {
111
111
  function AutocompleteItem({ className, ...props }) {
112
112
  return /* @__PURE__ */ jsx(Autocomplete$1.Item, {
113
113
  "data-slot": "autocomplete-item",
114
- className: cn("data-highlighted:bg-primary data-highlighted:text-white relative flex w-full cursor-clickable items-center gap-2 rounded-sm py-1 pl-1.5 pr-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
114
+ className: cn("data-highlighted:bg-highlight relative flex w-full cursor-clickable items-center gap-2 rounded-sm py-1 pl-1.5 pr-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
115
115
  ...props
116
116
  });
117
117
  }
118
118
  function AutocompleteSeparator({ className, ...props }) {
119
119
  return /* @__PURE__ */ jsx(Autocomplete$1.Separator, {
120
120
  "data-slot": "autocomplete-separator",
121
- className: cn("bg-line -mx-1 my-1 h-px", className),
121
+ className: cn("bg-contour -mx-1 my-1 h-px", className),
122
122
  ...props
123
123
  });
124
124
  }
package/dist/avatar.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { Avatar as Avatar$1 } from "@base-ui/react/avatar";
3
3
  //#region src/avatar.d.ts
4
4
  type AvatarProps = Avatar$1.Root.Props & {
5
- size?: "default" | "sm" | "lg";
5
+ size?: "xs" | "sm" | "default" | "lg";
6
6
  };
7
7
  type AvatarImageProps = Avatar$1.Image.Props;
8
8
  type AvatarFallbackProps = Avatar$1.Fallback.Props;
package/dist/avatar.js CHANGED
@@ -7,7 +7,7 @@ function Avatar({ className, size = "default", ...props }) {
7
7
  return /* @__PURE__ */ jsx(Avatar$1.Root, {
8
8
  "data-slot": "avatar",
9
9
  "data-size": size,
10
- className: cn("after:border-line group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", className),
10
+ className: cn("after:border-contour group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border data-[size=lg]:size-10 data-[size=sm]:size-6 data-[size=xs]:size-5", className),
11
11
  ...props
12
12
  });
13
13
  }
@@ -21,14 +21,14 @@ function AvatarImage({ className, ...props }) {
21
21
  function AvatarFallback({ className, ...props }) {
22
22
  return /* @__PURE__ */ jsx(Avatar$1.Fallback, {
23
23
  "data-slot": "avatar-fallback",
24
- className: cn("bg-secondary text-muted flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs", className),
24
+ className: cn("bg-secondary text-contrast flex size-full items-center justify-center rounded-full text-sm group-data-[size=xs]/avatar:text-[10px] group-data-[size=sm]/avatar:text-xs group-data-[size=lg]/avatar:text-base", className),
25
25
  ...props
26
26
  });
27
27
  }
28
28
  function AvatarBadge({ className, ...props }) {
29
29
  return /* @__PURE__ */ jsx("span", {
30
30
  "data-slot": "avatar-badge",
31
- className: cn("bg-primary text-white ring-foundation absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full ring-2 select-none", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className),
31
+ className: cn("bg-primary text-white ring-foundation absolute end-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full ring-2 select-none", "group-data-[size=xs]/avatar:size-1.5 group-data-[size=xs]/avatar:[&>svg]:hidden", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className),
32
32
  ...props
33
33
  });
34
34
  }
@@ -42,7 +42,7 @@ function AvatarGroup({ className, ...props }) {
42
42
  function AvatarGroupCount({ className, ...props }) {
43
43
  return /* @__PURE__ */ jsx("div", {
44
44
  "data-slot": "avatar-group-count",
45
- className: cn("bg-secondary text-muted ring-foundation relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3", className),
45
+ className: cn("bg-secondary text-contrast ring-foundation relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=xs]/avatar-group:size-5 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=xs]/avatar-group:[&>svg]:size-3 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3", className),
46
46
  ...props
47
47
  });
48
48
  }
package/dist/badge.d.ts CHANGED
@@ -2,7 +2,7 @@ import { VariantProps } from "class-variance-authority";
2
2
  import { useRender } from "@base-ui/react/use-render";
3
3
  //#region src/badge.d.ts
4
4
  declare const badgeVariants: (props?: ({
5
- variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | "success" | "warning" | null | undefined;
5
+ variant?: "danger" | "default" | "ghost" | "link" | "outline" | "secondary" | "success" | "warning" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  type BadgeProps = useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>;
8
8
  declare function Badge({ className, variant, render, ...props }: BadgeProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
package/dist/badge.js CHANGED
@@ -4,15 +4,15 @@ import { cva } from "class-variance-authority";
4
4
  import { mergeProps } from "@base-ui/react/merge-props";
5
5
  import { useRender } from "@base-ui/react/use-render";
6
6
  //#region src/badge.tsx
7
- const badgeVariants = cva("h-5 gap-1 rounded-full border border-transparent px-2 py-0.5 text-xs font-medium motion-color has-data-[icon=inline-start]:ps-1.5 has-data-[icon=inline-end]:pe-1.5 [&_svg:not([class*='size-'])]:size-3 inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&_svg]:shrink-0 [&_svg]:pointer-events-none focus-visible:border-focus focus-visible:ring-focus/50 focus-visible:ring-3 aria-invalid:ring-destructive/30 aria-invalid:border-destructive overflow-hidden group/badge", {
7
+ const badgeVariants = cva("h-5 gap-1 rounded-full border border-transparent px-2 py-0.5 text-xs font-medium motion-color has-data-[icon=inline-start]:ps-1.5 has-data-[icon=inline-end]:pe-1.5 [&_svg:not([class*='size-'])]:size-3 inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&_svg]:shrink-0 [&_svg]:pointer-events-none focus-visible:border-focus focus-visible:ring-focus/50 focus-visible:ring-3 aria-invalid:ring-danger/30 aria-invalid:border-danger overflow-hidden group/badge", {
8
8
  variants: { variant: {
9
9
  default: "bg-primary text-white [a]:hover:bg-primary/80",
10
- success: "bg-success text-contrast dark:text-foundation [a]:hover:bg-success/80",
11
- destructive: "bg-destructive text-white [a]:hover:bg-destructive/80 [a]:focus-visible:ring-destructive/50",
12
- warning: "bg-warning text-contrast dark:text-foundation [a]:hover:bg-warning/80",
10
+ success: "bg-success text-white [a]:hover:bg-success/80",
11
+ danger: "bg-danger text-white [a]:hover:bg-danger/80 [a]:focus-visible:ring-danger/50",
12
+ warning: "bg-warning text-white [a]:hover:bg-warning/80",
13
13
  secondary: "bg-secondary text-contrast [a]:hover:bg-secondary/80",
14
- outline: "border-edge bg-foundation [a]:hover:bg-secondary/80 [a]:hover:text-contrast dark:bg-edge/30",
15
- ghost: "text-muted [a]:hover:bg-secondary/80",
14
+ outline: "border-shade bg-foundation [a]:hover:bg-highlight [a]:hover:text-contrast",
15
+ ghost: "text-muted [a]:hover:bg-highlight",
16
16
  link: "text-primary [a]:underline-offset-4 [a]:hover:underline"
17
17
  } },
18
18
  defaultVariants: { variant: "default" }
@@ -6,10 +6,12 @@ import { useRender } from "@base-ui/react/use-render";
6
6
  declare const buttonGroupVariants: (props?: ({
7
7
  orientation?: "horizontal" | "vertical" | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
- type ButtonGroupProps = React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>;
9
+ type ButtonGroupProps = React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants> & {
10
+ size?: "xs" | "sm" | "default" | "lg";
11
+ };
10
12
  type ButtonGroupTextProps = useRender.ComponentProps<"div">;
11
13
  type ButtonGroupSeparatorProps = React.ComponentProps<typeof Separator>;
12
- declare function ButtonGroup({ className, orientation, ...props }: ButtonGroupProps): React.JSX.Element;
14
+ declare function ButtonGroup({ className, orientation, size, ...props }: ButtonGroupProps): React.JSX.Element;
13
15
  declare function ButtonGroupText({ className, render, ...props }: ButtonGroupTextProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
14
16
  declare function ButtonGroupSeparator({ className, orientation, ...props }: ButtonGroupSeparatorProps): React.JSX.Element;
15
17
  //#endregion
@@ -6,18 +6,19 @@ import { cva } from "class-variance-authority";
6
6
  import { mergeProps } from "@base-ui/react/merge-props";
7
7
  import { useRender } from "@base-ui/react/use-render";
8
8
  //#region src/button-group.tsx
9
- const buttonGroupVariants = cva("has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md flex w-fit items-stretch *:focus-visible:z-10 *:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1", {
9
+ const buttonGroupVariants = cva("group/button-group has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md flex w-fit items-stretch *:focus-visible:z-10 *:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[>[data-variant=outline]]:*:data-[slot=input-group]:border-shade has-[>[data-variant=outline]]:*:data-[slot=select-trigger]:border-shade has-[>[data-variant=outline]]:[&>input]:border-shade has-[>[data-variant=outline]]:[&>[data-slot=input-group]:has(:focus-visible)]:border-focus has-[>[data-variant=outline]]:[&>[data-slot=select-trigger]:focus-visible]:border-focus has-[>[data-variant=outline]]:[&>input:focus-visible]:border-focus [&>[data-variant=default]]:border-primary [&>[data-variant=secondary]]:border-secondary [&>[data-variant=danger]]:border-danger", {
10
10
  variants: { orientation: {
11
11
  horizontal: "[&>[data-slot]:has(~[data-slot])]:rounded-r-none [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0",
12
12
  vertical: "flex-col [&>[data-slot]:has(~[data-slot])]:rounded-b-none [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0"
13
13
  } },
14
14
  defaultVariants: { orientation: "horizontal" }
15
15
  });
16
- function ButtonGroup({ className, orientation, ...props }) {
16
+ function ButtonGroup({ className, orientation, size = "default", ...props }) {
17
17
  return /* @__PURE__ */ jsx("div", {
18
18
  role: "group",
19
19
  "data-slot": "button-group",
20
20
  "data-orientation": orientation,
21
+ "data-size": size,
21
22
  className: cn(buttonGroupVariants({ orientation }), className),
22
23
  ...props
23
24
  });
@@ -25,7 +26,7 @@ function ButtonGroup({ className, orientation, ...props }) {
25
26
  function ButtonGroupText({ className, render, ...props }) {
26
27
  return useRender({
27
28
  defaultTagName: "div",
28
- props: mergeProps({ className: cn("bg-secondary gap-2 rounded-md border border-edge px-2.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none", className) }, props),
29
+ props: mergeProps({ className: cn("bg-secondary gap-2 rounded-md border border-shade px-3 text-base font-medium group-data-[size=xs]/button-group:px-2 group-data-[size=xs]/button-group:text-xs group-data-[size=sm]/button-group:text-sm group-data-[size=lg]/button-group:px-4 group-data-[size=lg]/button-group:text-lg [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none", className) }, props),
29
30
  render,
30
31
  state: { slot: "button-group-text" }
31
32
  });
@@ -34,7 +35,7 @@ function ButtonGroupSeparator({ className, orientation = "vertical", ...props })
34
35
  return /* @__PURE__ */ jsx(Separator, {
35
36
  "data-slot": "button-group-separator",
36
37
  orientation,
37
- className: cn("bg-edge relative self-stretch data-[orientation=horizontal]:mx-px data-[orientation=horizontal]:w-auto data-[orientation=vertical]:my-px data-[orientation=vertical]:h-auto", className),
38
+ className: cn("bg-contour relative self-stretch data-[orientation=horizontal]:w-auto data-[orientation=vertical]:h-auto", className),
38
39
  ...props
39
40
  });
40
41
  }
package/dist/button.d.ts CHANGED
@@ -3,7 +3,7 @@ import { Button as Button$1 } from "@base-ui/react/button";
3
3
  import { VariantProps } from "class-variance-authority";
4
4
  //#region src/button.d.ts
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
6
+ variant?: "danger" | "default" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
7
7
  size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
9
  type ButtonProps = React.ComponentProps<typeof Button$1> & VariantProps<typeof buttonVariants>;
package/dist/button.js CHANGED
@@ -4,14 +4,14 @@ 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/30 aria-invalid:border-destructive rounded-md border border-transparent bg-clip-padding 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-30 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-hidden group/button select-none active:not-aria-[haspopup]:scale-[0.97]", {
7
+ const buttonVariants = cva("cursor-clickable focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger rounded-md border border-transparent bg-clip-padding 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 data-disabled:pointer-events-none data-disabled:opacity-30 [&_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
- default: "bg-primary text-white hover:bg-primary/80",
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
- secondary: "bg-secondary text-contrast hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-contrast",
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",
10
+ default: "bg-primary text-white hover:bg-primary/80 not-supports-backdrop-filter:hover:bg-primary/90 hover:backdrop-blur-xl hover:backdrop-saturate-150",
11
+ outline: "border-shade bg-foundation hover:bg-highlight hover:text-contrast aria-expanded:bg-highlight aria-expanded:text-contrast",
12
+ secondary: "bg-secondary text-contrast hover:bg-secondary/80 not-supports-backdrop-filter:hover:bg-secondary/90 hover:backdrop-blur-xl hover:backdrop-saturate-150 aria-expanded:bg-secondary aria-expanded:text-contrast",
13
+ ghost: "text-contrast hover:bg-highlight aria-expanded:bg-highlight aria-expanded:text-contrast",
14
+ danger: "bg-danger text-white hover:bg-danger/80 not-supports-backdrop-filter:hover:bg-danger/90 hover:backdrop-blur-xl hover:backdrop-saturate-150 focus-visible:ring-danger/50",
15
15
  link: "text-primary underline-offset-4 hover:underline"
16
16
  },
17
17
  size: {
package/dist/card.d.ts CHANGED
@@ -1,17 +1,24 @@
1
1
  import * as React from "react";
2
+ import { useRender } from "@base-ui/react/use-render";
2
3
  //#region src/card.d.ts
3
- type CardProps = React.ComponentProps<"div"> & {
4
+ type CardProps = useRender.ComponentProps<"div"> & {
4
5
  size?: "default" | "sm";
5
6
  };
6
7
  type CardHeaderProps = React.ComponentProps<"div">;
7
- type CardTitleProps = React.ComponentProps<"div">;
8
+ type CardTitleProps = useRender.ComponentProps<"div">;
8
9
  type CardDescriptionProps = React.ComponentProps<"div">;
9
10
  type CardActionProps = React.ComponentProps<"div">;
10
11
  type CardContentProps = React.ComponentProps<"div">;
11
12
  type CardFooterProps = React.ComponentProps<"div">;
12
- declare function Card({ className, size, ...props }: CardProps): React.JSX.Element;
13
+ /**
14
+ * A surface that groups related content. `render` changes the element: an
15
+ * `article` or `section` for semantics, or a link or button to make the whole
16
+ * card interactive, which adds a hover, a clickable cursor and a focus ring.
17
+ */
18
+ declare function Card({ className, size, render, ...props }: CardProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
13
19
  declare function CardHeader({ className, ...props }: CardHeaderProps): React.JSX.Element;
14
- declare function CardTitle({ className, ...props }: CardTitleProps): React.JSX.Element;
20
+ /** `render={<h3 />}` makes the title a real heading for screen readers. */
21
+ declare function CardTitle({ className, render, ...props }: CardTitleProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
15
22
  declare function CardDescription({ className, ...props }: CardDescriptionProps): React.JSX.Element;
16
23
  declare function CardAction({ className, ...props }: CardActionProps): React.JSX.Element;
17
24
  declare function CardContent({ className, ...props }: CardContentProps): React.JSX.Element;
package/dist/card.js CHANGED
@@ -1,26 +1,39 @@
1
+ "use client";
1
2
  import { cn } from "./lib/utils.js";
2
3
  import { jsx } from "react/jsx-runtime";
4
+ import { mergeProps } from "@base-ui/react/merge-props";
5
+ import { useRender } from "@base-ui/react/use-render";
3
6
  //#region src/card.tsx
4
- function Card({ className, size = "default", ...props }) {
5
- return /* @__PURE__ */ jsx("div", {
6
- "data-slot": "card",
7
- "data-size": size,
8
- className: cn("ring-contrast/10 bg-surface text-contrast group/card flex flex-col gap-4 overflow-hidden rounded-lg py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg", className),
9
- ...props
7
+ /**
8
+ * A surface that groups related content. `render` changes the element: an
9
+ * `article` or `section` for semantics, or a link or button to make the whole
10
+ * card interactive, which adds a hover, a clickable cursor and a focus ring.
11
+ */
12
+ function Card({ className, size = "default", render, ...props }) {
13
+ return useRender({
14
+ defaultTagName: "div",
15
+ props: mergeProps({ className: cn("ring-contrast/10 bg-surface text-contrast group/card flex flex-col gap-6 overflow-hidden rounded-lg py-6 text-sm ring-1 has-[>img:first-child]:pt-0 has-[>img:last-child]:pb-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg", "[a,button]:cursor-clickable [a,button]:hover:bg-elevated [button]:text-start motion-color outline-hidden focus-visible:ring-3 focus-visible:ring-focus/50 disabled:pointer-events-none disabled:opacity-30 aria-disabled:pointer-events-none aria-disabled:opacity-30", className) }, props),
16
+ render,
17
+ state: {
18
+ slot: "card",
19
+ size
20
+ }
10
21
  });
11
22
  }
12
23
  function CardHeader({ className, ...props }) {
13
24
  return /* @__PURE__ */ jsx("div", {
14
25
  "data-slot": "card-header",
15
- className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3", className),
26
+ className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1.5 px-6 group-data-[size=sm]/card:px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-6 group-data-[size=sm]/card:[.border-b]:pb-4", className),
16
27
  ...props
17
28
  });
18
29
  }
19
- function CardTitle({ className, ...props }) {
20
- return /* @__PURE__ */ jsx("div", {
21
- "data-slot": "card-title",
22
- className: cn("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className),
23
- ...props
30
+ /** `render={<h3 />}` makes the title a real heading for screen readers. */
31
+ function CardTitle({ className, render, ...props }) {
32
+ return useRender({
33
+ defaultTagName: "div",
34
+ props: mergeProps({ className: cn("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className) }, props),
35
+ render,
36
+ state: { slot: "card-title" }
24
37
  });
25
38
  }
26
39
  function CardDescription({ className, ...props }) {
@@ -40,14 +53,14 @@ function CardAction({ className, ...props }) {
40
53
  function CardContent({ className, ...props }) {
41
54
  return /* @__PURE__ */ jsx("div", {
42
55
  "data-slot": "card-content",
43
- className: cn("px-4 group-data-[size=sm]/card:px-3", className),
56
+ className: cn("px-6 group-data-[size=sm]/card:px-4", className),
44
57
  ...props
45
58
  });
46
59
  }
47
60
  function CardFooter({ className, ...props }) {
48
61
  return /* @__PURE__ */ jsx("div", {
49
62
  "data-slot": "card-footer",
50
- className: cn("bg-secondary/50 flex items-center rounded-b-lg border-t border-line p-4 group-data-[size=sm]/card:p-3", className),
63
+ className: cn("flex items-center px-6 group-data-[size=sm]/card:px-4 [.border-t]:pt-6 group-data-[size=sm]/card:[.border-t]:pt-4", className),
51
64
  ...props
52
65
  });
53
66
  }
package/dist/checkbox.js CHANGED
@@ -7,11 +7,11 @@ 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 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),
10
+ className: cn("cursor-clickable bg-shade border-transparent not-data-disabled:data-unchecked:hover:border-focus not-data-disabled:data-unchecked:group-hover/field:border-focus data-checked:bg-primary data-indeterminate:bg-primary data-checked:text-white data-indeterminate:text-white data-checked:border-primary data-indeterminate:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-danger focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 peer relative flex size-6 shrink-0 items-center justify-center rounded-sm border motion-color outline-hidden group-has-disabled/field:opacity-30 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3", className),
11
11
  ...props,
12
12
  children: /* @__PURE__ */ jsxs(Checkbox$1.Indicator, {
13
13
  "data-slot": "checkbox-indicator",
14
- className: "group/indicator grid place-content-center text-current transition-none [&>svg]:size-3.5",
14
+ className: "group/indicator grid place-content-center text-current transition-none [&>svg]:size-5",
15
15
  children: [/* @__PURE__ */ jsx(CheckIcon, { className: "col-start-1 row-start-1 group-data-indeterminate/indicator:hidden" }), /* @__PURE__ */ jsx(MinusIcon, { className: "col-start-1 row-start-1 hidden group-data-indeterminate/indicator:block" })]
16
16
  })
17
17
  });