@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/dist/item.js CHANGED
@@ -2,21 +2,22 @@
2
2
  import { cn } from "./lib/utils.js";
3
3
  import { Separator } from "./separator.js";
4
4
  import { jsx } from "react/jsx-runtime";
5
+ import * as React from "react";
5
6
  import { cva } from "class-variance-authority";
6
7
  import { mergeProps } from "@base-ui/react/merge-props";
7
8
  import { useRender } from "@base-ui/react/use-render";
8
9
  //#region src/item.tsx
9
- const itemVariants = cva("[a]:hover:bg-secondary rounded-md border text-sm w-full group/item focus-visible:border-focus focus-visible:ring-focus/50 flex items-center flex-wrap outline-hidden motion-color focus-visible:ring-3", {
10
+ const itemVariants = cva("[a,button]:hover:bg-highlight [a,button]:cursor-clickable rounded-md border text-sm w-full group/item focus-visible:border-focus focus-visible:ring-focus/50 flex items-center flex-wrap outline-hidden motion-color focus-visible:ring-3 disabled:pointer-events-none disabled:opacity-30 aria-disabled:pointer-events-none aria-disabled:opacity-30", {
10
11
  variants: {
11
12
  variant: {
12
13
  default: "border-transparent",
13
- outline: "border-line",
14
- muted: "bg-secondary/50 border-transparent"
14
+ outline: "border-contour",
15
+ muted: "bg-secondary/50 border-transparent [a,button]:hover:bg-secondary"
15
16
  },
16
17
  size: {
17
- default: "gap-2.5 px-3 py-2.5",
18
- sm: "gap-2 px-3 py-2",
19
- xs: "gap-2 px-2.5 py-2 in-data-[slot=menu-content]:p-0"
18
+ default: "gap-3.5 px-4 py-3.5",
19
+ sm: "gap-3.5 px-3.5 py-3",
20
+ xs: "gap-2.5 px-3 py-2.5 in-data-[slot=menu-content]:p-0"
20
21
  }
21
22
  },
22
23
  defaultVariants: {
@@ -77,21 +78,26 @@ function ItemMedia({ className, variant = "default", ...props }) {
77
78
  function ItemContent({ className, ...props }) {
78
79
  return /* @__PURE__ */ jsx("div", {
79
80
  "data-slot": "item-content",
80
- className: cn("flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0 [&+[data-slot=item-content]]:flex-none", className),
81
+ className: cn("flex min-w-0 flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0.5 [&+[data-slot=item-content]]:flex-none", className),
81
82
  ...props
82
83
  });
83
84
  }
84
- function ItemTitle({ className, ...props }) {
85
+ function ItemTitle({ className, children, ...props }) {
85
86
  return /* @__PURE__ */ jsx("div", {
86
87
  "data-slot": "item-title",
87
- className: cn("line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4", className),
88
- ...props
88
+ className: cn("line-clamp-1 flex w-fit max-w-full min-w-0 items-center gap-2 text-sm leading-snug font-medium underline-offset-4 [&>:not([data-slot=item-title-text])]:shrink-0", className),
89
+ ...props,
90
+ children: React.Children.map(children, (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx("span", {
91
+ "data-slot": "item-title-text",
92
+ className: "truncate",
93
+ children: child
94
+ }) : child)
89
95
  });
90
96
  }
91
97
  function ItemDescription({ className, ...props }) {
92
98
  return /* @__PURE__ */ jsx("p", {
93
99
  "data-slot": "item-description",
94
- className: cn("text-muted [&>a:hover]:text-primary line-clamp-2 text-left text-sm leading-normal font-normal group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4", className),
100
+ className: cn("text-muted [&>a:hover]:text-primary line-clamp-2 text-start text-sm leading-normal font-normal group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4", className),
95
101
  ...props
96
102
  });
97
103
  }
package/dist/kbd.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  //#region src/kbd.d.ts
3
3
  type KbdProps = React.ComponentProps<"kbd">;
4
- type KbdGroupProps = React.ComponentProps<"div">;
4
+ type KbdGroupProps = React.ComponentProps<"kbd">;
5
5
  declare function Kbd({ className, ...props }: KbdProps): React.JSX.Element;
6
6
  declare function KbdGroup({ className, ...props }: KbdGroupProps): React.JSX.Element;
7
7
  //#endregion
package/dist/kbd.js CHANGED
@@ -4,12 +4,12 @@ import { jsx } from "react/jsx-runtime";
4
4
  function Kbd({ className, ...props }) {
5
5
  return /* @__PURE__ */ jsx("kbd", {
6
6
  "data-slot": "kbd",
7
- className: cn("bg-secondary text-muted in-data-[slot=tooltip-content]:bg-foundation/20 in-data-[slot=tooltip-content]:text-foundation dark:in-data-[slot=tooltip-content]:bg-foundation/10 pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none [&_svg:not([class*='size-'])]:size-3", className),
7
+ className: cn("bg-secondary text-contrast in-data-[slot=tooltip-content]:bg-contrast-inverse/10 in-data-[slot=tooltip-content]:text-contrast-inverse pointer-events-none inline-flex h-5.5 w-fit min-w-5.5 items-center justify-center gap-1 rounded-sm px-1.5 font-sans text-xs font-medium select-none [&_svg:not([class*='size-'])]:size-3 in-data-[slot=input-group]:bg-contrast-inverse/50", className),
8
8
  ...props
9
9
  });
10
10
  }
11
11
  function KbdGroup({ className, ...props }) {
12
- return /* @__PURE__ */ jsx("div", {
12
+ return /* @__PURE__ */ jsx("kbd", {
13
13
  "data-slot": "kbd-group",
14
14
  className: cn("inline-flex items-center gap-1", className),
15
15
  ...props
package/dist/label.js CHANGED
@@ -4,7 +4,7 @@ import { jsx } from "react/jsx-runtime";
4
4
  function Label({ className, ...props }) {
5
5
  return /* @__PURE__ */ jsx("label", {
6
6
  "data-slot": "label",
7
- className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled]:pointer-events-none group-data-[disabled]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
7
+ className: cn("flex items-center gap-2 text-sm leading-snug font-medium select-none [&[for]]:cursor-clickable", "in-data-disabled:pointer-events-none in-data-disabled:opacity-30", "peer-data-disabled:pointer-events-none peer-data-disabled:opacity-30", "has-[+:is(:disabled,[data-disabled])]:pointer-events-none has-[+:is(:disabled,[data-disabled])]:opacity-30", className),
8
8
  ...props
9
9
  });
10
10
  }
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ //#region src/lib/merge-refs.d.ts
3
+ /**
4
+ * Combines refs so one element can feed several of them: a component's own
5
+ * ref and the one a consumer passes. Takes object refs, callback refs and
6
+ * `undefined`.
7
+ */
8
+ export declare function mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): (el: T | null) => void;
9
+ //#endregion
@@ -0,0 +1,16 @@
1
+ //#region src/lib/merge-refs.ts
2
+ /**
3
+ * Combines refs so one element can feed several of them: a component's own
4
+ * ref and the one a consumer passes. Takes object refs, callback refs and
5
+ * `undefined`.
6
+ */
7
+ function mergeRefs(...refs) {
8
+ return (el) => {
9
+ refs.forEach((ref) => {
10
+ if (typeof ref === "function") ref(el);
11
+ else if (ref && typeof ref === "object") ref.current = el;
12
+ });
13
+ };
14
+ }
15
+ //#endregion
16
+ export { mergeRefs };
package/dist/lib/utils.js CHANGED
@@ -8,6 +8,8 @@ import { extendTailwindMerge } from "tailwind-merge";
8
8
  * exclusive — the last one applied wins (e.g. a consumer overriding a
9
9
  * component's default animation). `motion-color` / `motion-scrim` are left out
10
10
  * on purpose: they compose with an enter recipe on the same element.
11
+ * - the spin speeds (`motion-spin-*`) are mutually exclusive too, so a
12
+ * consumer's `motion-spin-lg` replaces a component's `motion-spin-sm`.
11
13
  * - `cursor-clickable` joins the built-in `cursor` group.
12
14
  */
13
15
  const twMerge = extendTailwindMerge({ extend: { classGroups: {
@@ -23,6 +25,11 @@ const twMerge = extendTailwindMerge({ extend: { classGroups: {
23
25
  "motion-fade-lg",
24
26
  "motion-pop-md"
25
27
  ],
28
+ "motion-spin": [
29
+ "motion-spin-sm",
30
+ "motion-spin-md",
31
+ "motion-spin-lg"
32
+ ],
26
33
  cursor: ["cursor-clickable"]
27
34
  } } });
28
35
  function cn(...inputs) {
package/dist/masonry.d.ts CHANGED
@@ -10,7 +10,7 @@ type MasonryItemProps = Omit<HTMLMotionProps<"div">, "children"> & {
10
10
  span?: number;
11
11
  children?: React.ReactNode;
12
12
  };
13
- declare function Masonry({ columns, columnWidth, gap, className, children, ...props }: MasonryProps): React.JSX.Element;
13
+ declare function Masonry({ columns, columnWidth, gap, className, children, ref, ...props }: MasonryProps): React.JSX.Element;
14
14
  declare function MasonryItem({ className, span, children, ...props }: MasonryItemProps): React.JSX.Element;
15
15
  //#endregion
16
16
  export { Masonry, MasonryItem, type MasonryItemProps, type MasonryProps };
package/dist/masonry.js CHANGED
@@ -1,14 +1,16 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/utils.js";
3
3
  import { StarIcon } from "./lib/internal-icons.js";
4
+ import { mergeRefs } from "./lib/merge-refs.js";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import * as React from "react";
6
7
  import { AnimatePresence, motion, useReducedMotion } from "motion/react";
7
8
  //#region src/masonry.tsx
8
9
  const STAGGER_STEP = .05;
9
10
  const MasonryStaggerContext = React.createContext(null);
10
- function Masonry({ columns, columnWidth, gap = 4, className, children, ...props }) {
11
+ function Masonry({ columns, columnWidth, gap = 4, className, children, ref, ...props }) {
11
12
  const containerRef = React.useRef(null);
13
+ const mergedRef = React.useMemo(() => mergeRefs(containerRef, ref), [ref]);
12
14
  const rafRef = React.useRef(0);
13
15
  const staggerCounterRef = React.useRef(0);
14
16
  staggerCounterRef.current = 0;
@@ -134,7 +136,7 @@ function Masonry({ columns, columnWidth, gap = 4, className, children, ...props
134
136
  return /* @__PURE__ */ jsx(MasonryStaggerContext.Provider, {
135
137
  value: getStaggerIndex,
136
138
  children: /* @__PURE__ */ jsx("div", {
137
- ref: containerRef,
139
+ ref: mergedRef,
138
140
  "data-slot": "masonry",
139
141
  className: cn("relative", className),
140
142
  ...props,
package/dist/menu.d.ts CHANGED
@@ -20,7 +20,8 @@ type MenuLabelProps = React.ComponentProps<typeof Menu$1.GroupLabel> & {
20
20
  };
21
21
  type MenuItemProps = React.ComponentProps<typeof Menu$1.Item> & {
22
22
  inset?: boolean;
23
- variant?: "default" | "destructive";
23
+ /** `danger` turns the item's text and leading icon red. */
24
+ variant?: "default" | "danger";
24
25
  };
25
26
  type MenuSubProps = React.ComponentProps<typeof Menu$1.SubmenuRoot>;
26
27
  type MenuSubTriggerProps = React.ComponentProps<typeof Menu$1.SubmenuTrigger> & {
package/dist/menu.js CHANGED
@@ -33,7 +33,7 @@ function MenuContent({ align = "start", alignOffset = 0, side = "bottom", sideOf
33
33
  sideOffset,
34
34
  children: /* @__PURE__ */ jsx(Menu$1.Popup, {
35
35
  "data-slot": "menu-content",
36
- className: cn("motion-pop-md ring-contrast/10 bg-elevated text-contrast z-50 max-h-(--available-height) max-w-(--available-width) w-auto min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md p-1 shadow-md ring-1 outline-hidden data-closed:overflow-hidden", className),
36
+ className: cn("motion-pop-md ring-contrast/10 bg-elevated text-contrast z-50 max-h-(--available-height) max-w-(--available-width) w-auto min-w-32 overflow-x-hidden overflow-y-auto rounded-md p-1 shadow-md ring-1 outline-hidden data-closed:overflow-hidden", className),
37
37
  finalFocus: resolveFinalFocus(restoreFocusOnClose, finalFocus),
38
38
  ...props
39
39
  })
@@ -58,7 +58,7 @@ function MenuItem({ className, inset, variant = "default", ...props }) {
58
58
  "data-slot": "menu-item",
59
59
  "data-inset": inset,
60
60
  "data-variant": variant,
61
- className: cn("focus:bg-primary focus:text-white data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-white group/menu-item relative flex cursor-clickable items-center gap-1.5 rounded-sm px-1.5 py-1 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
61
+ className: cn("focus:bg-highlight data-[variant=danger]:text-danger data-[variant=danger]:*:[svg]:text-danger data-[variant=danger]:focus:bg-danger data-[variant=danger]:focus:text-white data-[variant=danger]:focus:**:text-white group/menu-item relative flex cursor-clickable items-center gap-1.5 rounded-sm px-1.5 py-1 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
62
62
  ...props
63
63
  });
64
64
  }
@@ -72,7 +72,7 @@ function MenuSubTrigger({ className, inset, children, ...props }) {
72
72
  return /* @__PURE__ */ jsxs(Menu$1.SubmenuTrigger, {
73
73
  "data-slot": "menu-sub-trigger",
74
74
  "data-inset": inset,
75
- className: cn("focus:bg-primary focus:text-white focus:**:text-white data-popup-open:bg-primary data-popup-open:text-white flex cursor-clickable items-center gap-1.5 rounded-sm px-1.5 py-1 text-sm outline-hidden select-none data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
75
+ className: cn("focus:bg-highlight data-popup-open:bg-highlight flex cursor-clickable items-center gap-1.5 rounded-sm px-1.5 py-1 text-sm outline-hidden select-none data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
76
76
  ...props,
77
77
  children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })]
78
78
  });
@@ -92,7 +92,7 @@ function MenuCheckboxItem({ className, children, checked, inset, ...props }) {
92
92
  return /* @__PURE__ */ jsxs(Menu$1.CheckboxItem, {
93
93
  "data-slot": "menu-checkbox-item",
94
94
  "data-inset": inset,
95
- className: cn("focus:bg-primary focus:text-white focus:**:text-white relative flex cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
95
+ className: cn("focus:bg-highlight relative flex cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
96
96
  checked,
97
97
  ...props,
98
98
  children: [/* @__PURE__ */ jsx("span", {
@@ -112,7 +112,7 @@ function MenuRadioItem({ className, children, inset, ...props }) {
112
112
  return /* @__PURE__ */ jsxs(Menu$1.RadioItem, {
113
113
  "data-slot": "menu-radio-item",
114
114
  "data-inset": inset,
115
- className: cn("focus:bg-primary focus:text-white focus:**:text-white relative flex cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
115
+ className: cn("focus:bg-highlight relative flex cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-30 data-inset:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
116
116
  ...props,
117
117
  children: [/* @__PURE__ */ jsx("span", {
118
118
  "data-slot": "menu-radio-item-indicator",
@@ -124,14 +124,14 @@ function MenuRadioItem({ className, children, inset, ...props }) {
124
124
  function MenuSeparator({ className, ...props }) {
125
125
  return /* @__PURE__ */ jsx(Menu$1.Separator, {
126
126
  "data-slot": "menu-separator",
127
- className: cn("bg-line -mx-1 my-1 h-px", className),
127
+ className: cn("bg-contour -mx-1 my-1 h-px", className),
128
128
  ...props
129
129
  });
130
130
  }
131
131
  function MenuShortcut({ className, ...props }) {
132
132
  return /* @__PURE__ */ jsx("span", {
133
133
  "data-slot": "menu-shortcut",
134
- className: cn("text-muted group-focus/menu-item:text-white ml-auto text-xs tracking-widest", className),
134
+ className: cn("text-muted ml-auto text-xs tracking-widest", className),
135
135
  ...props
136
136
  });
137
137
  }
package/dist/menubar.js CHANGED
@@ -7,7 +7,7 @@ import { Menubar as Menubar$1 } from "@base-ui/react/menubar";
7
7
  function Menubar({ className, ...props }) {
8
8
  return /* @__PURE__ */ jsx(Menubar$1, {
9
9
  "data-slot": "menubar",
10
- className: cn("bg-foundation flex h-9 items-center gap-0.5 rounded-md border border-edge p-1", className),
10
+ className: cn("bg-foundation flex h-9 items-center gap-0.5 rounded-md border border-shade p-1", className),
11
11
  ...props
12
12
  });
13
13
  }
@@ -26,7 +26,7 @@ function PaginationItem(props) {
26
26
  }
27
27
  function PaginationLink({ className, isActive, disabled, size = "icon", ...props }) {
28
28
  return /* @__PURE__ */ jsx(Button, {
29
- variant: isActive ? "outline" : "ghost",
29
+ variant: isActive ? "default" : "ghost",
30
30
  size,
31
31
  className: cn(disabled && "pointer-events-none opacity-50", className),
32
32
  render: /* @__PURE__ */ jsx("a", {
package/dist/popover.js CHANGED
@@ -46,7 +46,7 @@ function PopoverContent({ className, positionerClassName, align = "center", alig
46
46
  className: cn("isolate z-50", positionerClassName),
47
47
  children: /* @__PURE__ */ jsx(Popover$1.Popup, {
48
48
  "data-slot": "popover-content",
49
- className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-md p-2.5 text-sm shadow-md ring-1 outline-hidden", className),
49
+ className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 flex w-72 flex-col gap-2.5 rounded-md p-2.5 text-sm shadow-md ring-1 outline-hidden", className),
50
50
  finalFocus: resolveFinalFocus(restoreFocusOnClose, finalFocus),
51
51
  ...props
52
52
  })
@@ -38,7 +38,7 @@ function PreviewCardContent({ className, positionerClassName, side = "bottom", s
38
38
  className: cn("isolate z-50", positionerClassName),
39
39
  children: /* @__PURE__ */ jsx(PreviewCard$1.Popup, {
40
40
  "data-slot": "preview-card-content",
41
- className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 w-64 origin-(--transform-origin) rounded-md p-2.5 text-sm shadow-md ring-1 outline-hidden", className),
41
+ className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 z-50 w-64 rounded-md p-2.5 text-sm shadow-md ring-1 outline-hidden", className),
42
42
  ...props
43
43
  })
44
44
  }) });
package/dist/progress.js CHANGED
@@ -14,7 +14,7 @@ function Progress({ className, children, value = null, ...props }) {
14
14
  }
15
15
  function ProgressTrack({ className, ...props }) {
16
16
  return /* @__PURE__ */ jsx(Progress$1.Track, {
17
- className: cn("bg-secondary relative flex h-1 w-full items-center overflow-x-hidden rounded-full", className),
17
+ className: cn("bg-secondary relative flex h-3 w-full items-center overflow-x-hidden rounded-full", className),
18
18
  "data-slot": "progress-track",
19
19
  ...props
20
20
  });
@@ -35,7 +35,7 @@ function ProgressLabel({ className, ...props }) {
35
35
  }
36
36
  function ProgressValue({ className, ...props }) {
37
37
  return /* @__PURE__ */ jsx(Progress$1.Value, {
38
- className: cn("text-muted ml-auto text-sm tabular-nums", className),
38
+ className: cn("text-muted ms-auto text-sm tabular-nums", className),
39
39
  "data-slot": "progress-value",
40
40
  ...props
41
41
  });
@@ -7,7 +7,7 @@ import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
7
7
  function RadioGroup({ className, ...props }) {
8
8
  return /* @__PURE__ */ jsx(RadioGroup$1, {
9
9
  "data-slot": "radio-group",
10
- className: cn("grid w-full gap-2", className),
10
+ className: cn("grid w-full gap-3", className),
11
11
  ...props
12
12
  });
13
13
  }
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/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),
9
+ 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-checked:text-white data-checked: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 group/radio peer relative flex aspect-square size-6 shrink-0 rounded-full 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),
10
10
  ...props,
11
11
  children: /* @__PURE__ */ jsx(RadioIndicator, {})
12
12
  });
@@ -14,7 +14,7 @@ function Radio({ className, ...props }) {
14
14
  function RadioIndicator({ className, ...props }) {
15
15
  return /* @__PURE__ */ jsx(Radio$1.Indicator, {
16
16
  "data-slot": "radio-indicator",
17
- className: cn("group-aria-invalid/radio:text-destructive text-white absolute inset-0 flex items-center justify-center data-unchecked:opacity-0", "after:block after:size-2 after:rounded-full after:bg-current", className),
17
+ className: cn("text-white absolute inset-0 flex items-center justify-center data-unchecked:opacity-0", "after:block after:size-3 after:rounded-full after:bg-current", className),
18
18
  ...props
19
19
  });
20
20
  }
@@ -0,0 +1,43 @@
1
+ import * as React from "react";
2
+ import { Group, Panel, Separator } from "react-resizable-panels";
3
+ //#region src/resizable.d.ts
4
+ type ResizablePanelGroupProps = Omit<React.ComponentProps<typeof Group>, "elementRef"> & {
5
+ ref?: React.Ref<HTMLDivElement>;
6
+ };
7
+ type ResizablePanelProps = Omit<React.ComponentProps<typeof Panel>, "elementRef"> & {
8
+ ref?: React.Ref<HTMLDivElement>;
9
+ };
10
+ type ResizableHandleProps = Omit<React.ComponentProps<typeof Separator>, "elementRef"> & {
11
+ ref?: React.Ref<HTMLDivElement>;
12
+ /**
13
+ * Show a grip on the line, a visible hint that it can be dragged.
14
+ *
15
+ * @default false
16
+ */
17
+ grip?: boolean;
18
+ };
19
+ /**
20
+ * A row of panels the user resizes by dragging the handles between them, or
21
+ * from the keyboard once a handle has focus. Pass `orientation="vertical"` to
22
+ * stack them instead.
23
+ *
24
+ * The group fills its parent: it sets its own `width` and `height` to 100%
25
+ * inline, so a height class on the group has no effect. Size the parent, or
26
+ * pass `style`.
27
+ */
28
+ declare function ResizablePanelGroup({ ref, ...props }: ResizablePanelGroupProps): React.JSX.Element;
29
+ /**
30
+ * One resizable region. Numeric sizes are pixels; use strings for
31
+ * percentages (`defaultSize="25%"`). `className` lands on the panel's inner
32
+ * element, which scrolls when the content overflows.
33
+ */
34
+ declare function ResizablePanel({ ref, ...props }: ResizablePanelProps): React.JSX.Element;
35
+ /**
36
+ * The line between two panels. It lights up while the pointer is close
37
+ * enough to drag it: the library hit-tests a zone wider than the line itself
38
+ * and reports it in `data-separator` (`hover`, `active`, `focus`, `disabled`),
39
+ * which CSS `:hover` on a 1px line would miss.
40
+ */
41
+ declare function ResizableHandle({ className, grip, ref, ...props }: ResizableHandleProps): React.JSX.Element;
42
+ //#endregion
43
+ export { ResizableHandle, type ResizableHandleProps, ResizablePanel, ResizablePanelGroup, type ResizablePanelGroupProps, type ResizablePanelProps };
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { cn } from "./lib/utils.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { Group, Panel, Separator } from "react-resizable-panels";
5
+ //#region src/resizable.tsx
6
+ /**
7
+ * A row of panels the user resizes by dragging the handles between them, or
8
+ * from the keyboard once a handle has focus. Pass `orientation="vertical"` to
9
+ * stack them instead.
10
+ *
11
+ * The group fills its parent: it sets its own `width` and `height` to 100%
12
+ * inline, so a height class on the group has no effect. Size the parent, or
13
+ * pass `style`.
14
+ */
15
+ function ResizablePanelGroup({ ref, ...props }) {
16
+ return /* @__PURE__ */ jsx(Group, {
17
+ "data-slot": "resizable-panel-group",
18
+ elementRef: ref,
19
+ ...props
20
+ });
21
+ }
22
+ /**
23
+ * One resizable region. Numeric sizes are pixels; use strings for
24
+ * percentages (`defaultSize="25%"`). `className` lands on the panel's inner
25
+ * element, which scrolls when the content overflows.
26
+ */
27
+ function ResizablePanel({ ref, ...props }) {
28
+ return /* @__PURE__ */ jsx(Panel, {
29
+ "data-slot": "resizable-panel",
30
+ elementRef: ref,
31
+ ...props
32
+ });
33
+ }
34
+ /**
35
+ * The line between two panels. It lights up while the pointer is close
36
+ * enough to drag it: the library hit-tests a zone wider than the line itself
37
+ * and reports it in `data-separator` (`hover`, `active`, `focus`, `disabled`),
38
+ * which CSS `:hover` on a 1px line would miss.
39
+ */
40
+ function ResizableHandle({ className, grip = false, ref, ...props }) {
41
+ return /* @__PURE__ */ jsx(Separator, {
42
+ "data-slot": "resizable-handle",
43
+ elementRef: ref,
44
+ className: cn("group/resizable-handle bg-contour z-10 flex items-center justify-center motion-color outline-hidden focus-visible:ring-3 focus-visible:ring-focus/50 data-[separator=active]:bg-focus data-[separator=hover]:bg-focus data-[separator=disabled]:pointer-events-none aria-[orientation=horizontal]:h-px aria-[orientation=vertical]:w-px", className),
45
+ ...props,
46
+ children: grip && /* @__PURE__ */ jsx("div", {
47
+ "data-slot": "resizable-handle-grip",
48
+ className: "bg-shade h-6 w-1 shrink-0 rounded-full motion-color group-data-[separator=active]/resizable-handle:bg-focus group-data-[separator=hover]/resizable-handle:bg-focus group-data-[separator=disabled]/resizable-handle:opacity-30 group-aria-[orientation=horizontal]/resizable-handle:h-1 group-aria-[orientation=horizontal]/resizable-handle:w-6"
49
+ })
50
+ });
51
+ }
52
+ //#endregion
53
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
@@ -1,9 +1,20 @@
1
1
  import * as React from "react";
2
2
  import { ScrollArea as ScrollArea$1 } from "@base-ui/react/scroll-area";
3
3
  //#region src/scroll-area.d.ts
4
- type ScrollAreaProps = React.ComponentProps<typeof ScrollArea$1.Root>;
5
- declare function ScrollArea({ className, children, ...props }: ScrollAreaProps): React.JSX.Element;
4
+ type ScrollAreaProps = React.ComponentProps<typeof ScrollArea$1.Root> & {
5
+ /**
6
+ * Fade the content out toward any edge that has more to scroll to. On by
7
+ * default; the fade size follows `--scroll-area-fade` (default `2.5rem`).
8
+ */
9
+ fade?: boolean;
10
+ };
6
11
  type ScrollBarProps = React.ComponentProps<typeof ScrollArea$1.Scrollbar>;
12
+ /**
13
+ * A scrollable region with styled scrollbars. Both scrollbars are built in:
14
+ * Base UI only mounts one when its axis overflows, so pass content and the
15
+ * right bars appear. They fade in while the area is hovered or scrolling.
16
+ */
17
+ declare function ScrollArea({ className, children, fade, ...props }: ScrollAreaProps): React.JSX.Element;
7
18
  declare function ScrollBar({ className, orientation, ...props }: ScrollBarProps): React.JSX.Element;
8
19
  //#endregion
9
20
  export { ScrollArea, type ScrollAreaProps, ScrollBar, type ScrollBarProps };
@@ -3,18 +3,37 @@ import { cn } from "./lib/utils.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { ScrollArea as ScrollArea$1 } from "@base-ui/react/scroll-area";
5
5
  //#region src/scroll-area.tsx
6
- function ScrollArea({ className, children, ...props }) {
6
+ /**
7
+ * The edge fade is a mask, so the content itself turns transparent and
8
+ * whatever is behind it shows through: no shadow color to match, in any
9
+ * theme. Each edge has a fixed fade (`--scroll-area-fade`) that switches on
10
+ * when Base UI marks that edge as having more content (`data-overflow-*`):
11
+ * its edge opacity goes from 1 (none) to 0 (fully faded).
12
+ * The two axes are intersected; the horizontal one flips in right-to-left
13
+ * layouts, where Base UI's "start" is the right edge.
14
+ */
15
+ const FADE_MASK = "[--scroll-area-fade-x:to_right] rtl:[--scroll-area-fade-x:to_left] data-overflow-y-start:[--scroll-area-fade-top:0] data-overflow-y-end:[--scroll-area-fade-bottom:0] data-overflow-x-start:[--scroll-area-fade-start:0] data-overflow-x-end:[--scroll-area-fade-end:0] [mask-composite:intersect] [mask-image:linear-gradient(to_bottom,rgb(0_0_0/var(--scroll-area-fade-top,1)),#000_var(--scroll-area-fade,2.5rem),#000_calc(100%_-_var(--scroll-area-fade,2.5rem)),rgb(0_0_0/var(--scroll-area-fade-bottom,1))),linear-gradient(var(--scroll-area-fade-x),rgb(0_0_0/var(--scroll-area-fade-start,1)),#000_var(--scroll-area-fade,2.5rem),#000_calc(100%_-_var(--scroll-area-fade,2.5rem)),rgb(0_0_0/var(--scroll-area-fade-end,1)))]";
16
+ /**
17
+ * A scrollable region with styled scrollbars. Both scrollbars are built in:
18
+ * Base UI only mounts one when its axis overflows, so pass content and the
19
+ * right bars appear. They fade in while the area is hovered or scrolling.
20
+ */
21
+ function ScrollArea({ className, children, fade = true, ...props }) {
7
22
  return /* @__PURE__ */ jsxs(ScrollArea$1.Root, {
8
23
  "data-slot": "scroll-area",
9
- className: cn("relative", className),
24
+ className: cn("relative motion-color has-[>[data-slot=scroll-area-viewport]:focus-visible]:ring-3 has-[>[data-slot=scroll-area-viewport]:focus-visible]:ring-focus/50 has-[>[data-slot=scroll-area-viewport]:focus-visible]:outline-hidden", className),
10
25
  ...props,
11
26
  children: [
12
27
  /* @__PURE__ */ jsx(ScrollArea$1.Viewport, {
13
28
  "data-slot": "scroll-area-viewport",
14
- className: "focus-visible:ring-focus/50 size-full rounded-[inherit] motion-color outline-hidden focus-visible:ring-3 focus-visible:outline-1",
15
- children
29
+ className: cn("size-full rounded-[inherit] outline-hidden", fade && FADE_MASK),
30
+ children: /* @__PURE__ */ jsx(ScrollArea$1.Content, {
31
+ "data-slot": "scroll-area-content",
32
+ children
33
+ })
16
34
  }),
17
- /* @__PURE__ */ jsx(ScrollBar, {}),
35
+ /* @__PURE__ */ jsx(ScrollBar, { orientation: "vertical" }),
36
+ /* @__PURE__ */ jsx(ScrollBar, { orientation: "horizontal" }),
18
37
  /* @__PURE__ */ jsx(ScrollArea$1.Corner, { "data-slot": "scroll-area-corner" })
19
38
  ]
20
39
  });
@@ -23,11 +42,11 @@ function ScrollBar({ className, orientation = "vertical", ...props }) {
23
42
  return /* @__PURE__ */ jsx(ScrollArea$1.Scrollbar, {
24
43
  "data-slot": "scroll-area-scrollbar",
25
44
  orientation,
26
- className: cn("flex touch-none p-px transition-colors select-none data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-l data-[orientation=vertical]:border-l-transparent", className),
45
+ className: cn("pointer-events-none flex touch-none p-px opacity-0 transition-opacity duration-(--duration-md) ease-(--ease) select-none data-hovering:pointer-events-auto data-hovering:opacity-100 data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-scrolling:duration-0 data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-s data-[orientation=vertical]:border-s-transparent", className),
27
46
  ...props,
28
47
  children: /* @__PURE__ */ jsx(ScrollArea$1.Thumb, {
29
48
  "data-slot": "scroll-area-thumb",
30
- className: "bg-line relative flex-1 rounded-full"
49
+ className: "bg-shade relative flex-1 rounded-full"
31
50
  })
32
51
  });
33
52
  }
package/dist/select.js CHANGED
@@ -5,7 +5,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { cva } from "class-variance-authority";
6
6
  import { Select as Select$1 } from "@base-ui/react/select";
7
7
  //#region src/select.tsx
8
- const selectTriggerVariants = cva("data-placeholder:text-soft bg-edge hover:border-focus 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 border-transparent whitespace-nowrap motion-color outline-hidden select-none focus-visible:ring-3 disabled:pointer-events-none disabled:opacity-30 aria-invalid:ring-3 *: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", {
8
+ const selectTriggerVariants = cva("data-placeholder:text-soft bg-shade hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger flex w-fit items-center justify-between gap-1.5 rounded-md border border-transparent whitespace-nowrap motion-color outline-hidden select-none focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3 *: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", {
9
9
  variants: { size: {
10
10
  xs: "h-6 rounded-sm px-2 text-xs",
11
11
  sm: "h-8 px-3 text-sm",
@@ -76,7 +76,7 @@ function SelectContent({ className, children, side = "bottom", sideOffset = 4, a
76
76
  className: "isolate z-50",
77
77
  children: /* @__PURE__ */ jsxs(Select$1.Popup, {
78
78
  "data-slot": "select-content",
79
- className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 relative isolate z-50 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),
79
+ className: cn("motion-pop-md bg-elevated text-contrast ring-contrast/10 relative isolate z-50 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),
80
80
  ...props,
81
81
  children: [
82
82
  /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
@@ -96,7 +96,7 @@ function SelectLabel({ className, ...props }) {
96
96
  function SelectItem({ className, children, ...props }) {
97
97
  return /* @__PURE__ */ jsxs(Select$1.Item, {
98
98
  "data-slot": "select-item",
99
- className: cn("data-highlighted:bg-primary data-highlighted:text-white not-data-[variant=destructive]:data-highlighted:**:text-white relative flex w-full cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-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 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
99
+ className: cn("data-highlighted:bg-highlight relative flex w-full cursor-clickable items-center gap-1.5 rounded-sm py-1 pr-8 pl-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 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
100
100
  ...props,
101
101
  children: [/* @__PURE__ */ jsx(Select$1.ItemText, {
102
102
  "data-slot": "select-item-text",
@@ -114,7 +114,7 @@ function SelectItem({ className, children, ...props }) {
114
114
  function SelectSeparator({ className, ...props }) {
115
115
  return /* @__PURE__ */ jsx(Select$1.Separator, {
116
116
  "data-slot": "select-separator",
117
- className: cn("bg-line pointer-events-none -mx-1 my-1 h-px", className),
117
+ className: cn("bg-contour pointer-events-none -mx-1 my-1 h-px", className),
118
118
  ...props
119
119
  });
120
120
  }
package/dist/separator.js CHANGED
@@ -7,7 +7,7 @@ function Separator({ className, orientation = "horizontal", ...props }) {
7
7
  return /* @__PURE__ */ jsx(Separator$1, {
8
8
  "data-slot": "separator",
9
9
  orientation,
10
- className: cn("bg-line shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch", className),
10
+ className: cn("bg-contour shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch", className),
11
11
  ...props
12
12
  });
13
13
  }