@robomous/ui-core 0.1.0 → 0.2.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 (135) hide show
  1. package/README.md +19 -7
  2. package/dist/{primitives → components}/alert.js +1 -1
  3. package/dist/{primitives → components}/badge.js +1 -1
  4. package/dist/{primitives → components}/button.d.ts +1 -1
  5. package/dist/{primitives → components}/button.js +4 -1
  6. package/dist/{primitives → components}/card.d.ts +1 -1
  7. package/dist/{primitives → components}/card.js +2 -2
  8. package/dist/{primitives → components}/combobox.js +4 -4
  9. package/dist/{primitives → components}/dialog.js +1 -1
  10. package/dist/{primitives → components}/dropdown-menu.js +12 -7
  11. package/dist/{primitives → components}/field.js +2 -4
  12. package/dist/{primitives → components}/input-group.js +1 -1
  13. package/dist/{primitives → components}/input.js +1 -1
  14. package/dist/{primitives → components}/label.js +1 -1
  15. package/dist/components/progress.js +7 -0
  16. package/dist/{primitives → components}/select.d.ts +3 -1
  17. package/dist/{primitives → components}/select.js +7 -4
  18. package/dist/{primitives → components}/separator.js +1 -1
  19. package/dist/{primitives → components}/sheet.js +1 -1
  20. package/dist/{primitives → components}/skeleton.js +1 -1
  21. package/dist/{primitives → components}/sonner.js +17 -12
  22. package/dist/{primitives → components}/table.d.ts +1 -1
  23. package/dist/{primitives → components}/table.js +3 -3
  24. package/dist/{primitives → components}/tabs.js +1 -1
  25. package/dist/{primitives → components}/textarea.js +1 -1
  26. package/dist/{primitives → components}/tooltip.js +1 -1
  27. package/dist/gates/index.d.ts +28 -0
  28. package/dist/gates/index.js +142 -0
  29. package/dist/index.d.ts +31 -32
  30. package/dist/index.js +32 -33
  31. package/dist/{tokens.d.ts → theme/tokens.d.ts} +5 -5
  32. package/dist/{tokens.js → theme/tokens.js} +12 -12
  33. package/package.json +23 -12
  34. package/{shadcn → src/components}/alert.tsx +14 -21
  35. package/src/{primitives → components}/badge.tsx +15 -21
  36. package/src/{primitives → components}/button.tsx +13 -10
  37. package/{shadcn → src/components}/card.tsx +16 -31
  38. package/src/{primitives → components}/combobox.test.tsx +15 -2
  39. package/src/{primitives → components}/combobox.tsx +45 -74
  40. package/src/{primitives/primitives.test.tsx → components/components.test.tsx} +106 -69
  41. package/src/{primitives → components}/dialog.tsx +31 -54
  42. package/src/{primitives → components}/dropdown-menu.tsx +51 -65
  43. package/src/{primitives → components}/field.tsx +48 -62
  44. package/src/{primitives → components}/input-group.tsx +37 -49
  45. package/{shadcn → src/components}/input.tsx +5 -5
  46. package/{shadcn → src/components}/label.tsx +7 -10
  47. package/src/{primitives → components}/progress.tsx +7 -6
  48. package/{shadcn → src/components}/select.tsx +40 -40
  49. package/{shadcn → src/components}/separator.tsx +7 -7
  50. package/src/{primitives → components}/sheet.tsx +27 -44
  51. package/{shadcn → src/components}/skeleton.tsx +3 -3
  52. package/src/{primitives → components}/sonner.test.tsx +12 -4
  53. package/src/components/sonner.tsx +67 -0
  54. package/{shadcn → src/components}/table.tsx +17 -44
  55. package/{shadcn → src/components}/tabs.tsx +16 -26
  56. package/{shadcn → src/components}/textarea.tsx +5 -5
  57. package/{shadcn → src/components}/tooltip.tsx +12 -16
  58. package/src/gates/design.test.ts +188 -0
  59. package/src/gates/index.test.ts +11 -0
  60. package/src/gates/index.ts +165 -0
  61. package/src/gates/tokens.test.ts +215 -0
  62. package/src/harness.test.tsx +1 -1
  63. package/src/index.ts +63 -33
  64. package/src/theme/imports.test.ts +160 -0
  65. package/src/{statusTone.test.ts → theme/statusTone.test.ts} +5 -1
  66. package/src/{styles.css → theme/styles.css} +45 -31
  67. package/src/theme/tailwind.css +646 -0
  68. package/src/{tokens.test.ts → theme/tokens.test.ts} +30 -23
  69. package/src/{tokens.ts → theme/tokens.ts} +12 -12
  70. package/components.json +0 -13
  71. package/dist/lib/button.d.ts +0 -1
  72. package/dist/lib/button.js +0 -4
  73. package/dist/lib/cn.d.ts +0 -18
  74. package/dist/lib/cn.js +0 -21
  75. package/dist/lib/menu.d.ts +0 -1
  76. package/dist/lib/menu.js +0 -16
  77. package/dist/lib/progress.d.ts +0 -3
  78. package/dist/lib/progress.js +0 -6
  79. package/dist/lib/select.d.ts +0 -1
  80. package/dist/lib/select.js +0 -3
  81. package/dist/primitives/progress.js +0 -7
  82. package/gates/canonical.test.mjs +0 -71
  83. package/gates/extensions.test.mjs +0 -373
  84. package/gates/index.d.mts +0 -51
  85. package/gates/index.mjs +0 -514
  86. package/gates/tokens.test.mjs +0 -276
  87. package/shadcn/README.md +0 -13
  88. package/shadcn/badge.tsx +0 -49
  89. package/shadcn/button.tsx +0 -67
  90. package/shadcn/combobox.tsx +0 -299
  91. package/shadcn/dialog.tsx +0 -166
  92. package/shadcn/dropdown-menu.tsx +0 -267
  93. package/shadcn/field.tsx +0 -236
  94. package/shadcn/input-group.tsx +0 -154
  95. package/shadcn/progress.tsx +0 -29
  96. package/shadcn/sheet.tsx +0 -145
  97. package/shadcn/sonner.tsx +0 -49
  98. package/src/lib/button.ts +0 -4
  99. package/src/lib/cn.test.ts +0 -33
  100. package/src/lib/cn.ts +0 -23
  101. package/src/lib/menu.ts +0 -16
  102. package/src/lib/progress.ts +0 -6
  103. package/src/lib/select.ts +0 -4
  104. package/src/primitives/alert.tsx +0 -76
  105. package/src/primitives/card.tsx +0 -103
  106. package/src/primitives/input.tsx +0 -19
  107. package/src/primitives/label.tsx +0 -22
  108. package/src/primitives/select.tsx +0 -190
  109. package/src/primitives/separator.tsx +0 -28
  110. package/src/primitives/skeleton.tsx +0 -13
  111. package/src/primitives/sonner.tsx +0 -65
  112. package/src/primitives/table.tsx +0 -114
  113. package/src/primitives/tabs.tsx +0 -88
  114. package/src/primitives/textarea.tsx +0 -18
  115. package/src/primitives/tooltip.tsx +0 -57
  116. /package/dist/{primitives → components}/alert.d.ts +0 -0
  117. /package/dist/{primitives → components}/badge.d.ts +0 -0
  118. /package/dist/{primitives → components}/combobox.d.ts +0 -0
  119. /package/dist/{primitives → components}/dialog.d.ts +0 -0
  120. /package/dist/{primitives → components}/dropdown-menu.d.ts +0 -0
  121. /package/dist/{primitives → components}/field.d.ts +0 -0
  122. /package/dist/{primitives → components}/input-group.d.ts +0 -0
  123. /package/dist/{primitives → components}/input.d.ts +0 -0
  124. /package/dist/{primitives → components}/label.d.ts +0 -0
  125. /package/dist/{primitives → components}/progress.d.ts +0 -0
  126. /package/dist/{primitives → components}/separator.d.ts +0 -0
  127. /package/dist/{primitives → components}/sheet.d.ts +0 -0
  128. /package/dist/{primitives → components}/skeleton.d.ts +0 -0
  129. /package/dist/{primitives → components}/sonner.d.ts +0 -0
  130. /package/dist/{primitives → components}/tabs.d.ts +0 -0
  131. /package/dist/{primitives → components}/textarea.d.ts +0 -0
  132. /package/dist/{primitives → components}/tooltip.d.ts +0 -0
  133. /package/dist/{statusTone.d.ts → theme/statusTone.d.ts} +0 -0
  134. /package/dist/{statusTone.js → theme/statusTone.js} +0 -0
  135. /package/src/{statusTone.ts → theme/statusTone.ts} +0 -0
package/README.md CHANGED
@@ -1,8 +1,12 @@
1
+ <img src="https://cdn.robomous.ai/public-images/robomous-banner.svg" alt="Robomous.ai" width=300 />
2
+
3
+ -----
4
+
1
5
  # @robomous/ui-core
2
6
 
3
- The Robomous design system: shadcn Nova primitives under Radix behaviour, the foundation design
4
- tokens, and the gates that keep them canonical. Extracted from
5
- [Robomous/VisionSet](https://github.com/Robomous/VisionSet), where it grew up.
7
+ The Robomous design system: twenty-one React components this package owns outright, the design
8
+ tokens they resolve through, and the gates that hold the rules the design system is made of.
9
+ Extracted from [Robomous/VisionSet](https://github.com/Robomous/VisionSet), where it grew up.
6
10
 
7
11
  ## Install
8
12
 
@@ -23,13 +27,21 @@ The stylesheet is the contract: Tailwind v4 reads its `@theme` block, so `bg-pri
23
27
  component here and `bg-primary` in a consuming app are the same colour by construction. A
24
28
  consumer adds its own extensions in its own stylesheet after importing this one.
25
29
 
30
+ ## Adding a component
31
+
32
+ Write it. A component is a file in `src/components/` that wraps Radix or Base UI behaviour,
33
+ spells colour only through the tokens, keeps its own geometry, and is exported by name from
34
+ `src/index.ts`. [DESIGN.md](DESIGN.md) has the checklist and the reasoning behind each item; the
35
+ gates hold the parts of it that a review would otherwise have to catch by eye.
36
+
26
37
  ## The gates
27
38
 
28
39
  The rules that keep the design system honest are published alongside it:
29
- `import { ... } from "@robomous/ui-core/gates"` gives a consumer the same pure scan helpers and
30
- foundation facts this repo's own gate tests run — canonical-plus-additive primitives, one status
31
- palette with one home, no colour in a class string, brand as identity only. The governance, and
32
- what each gate holds, is [DESIGN.md](DESIGN.md).
40
+ `import { ... } from "@robomous/ui-core/gates"` gives a consumer the same eight pure scan helpers
41
+ and token facts this repo's own gates run — no colour in a class string, one status palette with
42
+ one home, no rival colour family standing in for it, brand as identity only, and the token names
43
+ read off the shipped stylesheet so a consumer can prove none of its own extensions shadows one.
44
+ The rules themselves, and which gate holds each, are in [DESIGN.md](DESIGN.md).
33
45
 
34
46
  ## Release
35
47
 
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
- import { cn } from "../lib/cn.js";
3
+ import { cn } from "cn";
4
4
  const alertVariants = cva("group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", {
5
5
  variants: {
6
6
  variant: {
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
3
  import { Slot } from "radix-ui";
4
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
5
5
  const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", {
6
6
  variants: {
7
7
  variant: {
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const buttonVariants: (props?: ({
4
4
  variant?: "secondary" | "destructive" | "default" | "outline" | "ghost" | "link" | null | undefined;
5
- size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
5
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "inline" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
8
8
  asChild?: boolean;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
3
  import { Slot } from "radix-ui";
4
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
5
5
  const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
6
6
  variants: {
7
7
  variant: {
@@ -21,6 +21,9 @@ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justi
21
21
  "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
22
22
  "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
23
23
  "icon-lg": "size-9",
24
+ // A link button is inline prose, not a boxed control: no height of its
25
+ // own and no padding, so it sits inside a sentence or a table cell.
26
+ inline: "h-auto p-0",
24
27
  },
25
28
  },
26
29
  defaultVariants: {
@@ -8,4 +8,4 @@ declare function CardDescription({ className, ...props }: React.ComponentProps<"
8
8
  declare function CardAction({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
9
9
  declare function CardContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
10
10
  declare function CardFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
11
- export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, };
11
+ export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from "../lib/cn.js";
2
+ import { cn } from "cn";
3
3
  function Card({ className, size = "default", ...props }) {
4
4
  return (_jsx("div", { "data-slot": "card", "data-size": size, className: cn("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", className), ...props }));
5
5
  }
@@ -21,4 +21,4 @@ function CardContent({ className, ...props }) {
21
21
  function CardFooter({ className, ...props }) {
22
22
  return (_jsx("div", { "data-slot": "card-footer", className: cn("flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)", className), ...props }));
23
23
  }
24
- export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, };
24
+ export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
@@ -2,9 +2,9 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Combobox as ComboboxPrimitive } from "@base-ui/react";
5
- import { cn } from "../lib/cn.js";
5
+ import { cn } from "cn";
6
6
  import { Button } from "./button.js";
7
- import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, } from "./input-group.js";
7
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "./input-group.js";
8
8
  import { ChevronDownIcon, XIcon, CheckIcon } from "lucide-react";
9
9
  const Combobox = ComboboxPrimitive.Root;
10
10
  function ComboboxValue({ ...props }) {
@@ -20,7 +20,7 @@ function ComboboxInput({ className, children, disabled = false, showTrigger = tr
20
20
  return (_jsxs(InputGroup, { className: cn("w-auto", className), children: [_jsx(ComboboxPrimitive.Input, { render: _jsx(InputGroupInput, { disabled: disabled }), ...props }), _jsxs(InputGroupAddon, { align: "inline-end", children: [showTrigger && (_jsx(InputGroupButton, { size: "icon-xs", variant: "ghost", asChild: true, "data-slot": "input-group-button", className: "group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent", disabled: disabled, children: _jsx(ComboboxTrigger, {}) })), showClear && _jsx(ComboboxClear, { disabled: disabled })] }), children] }));
21
21
  }
22
22
  function ComboboxContent({ className, side = "bottom", sideOffset = 6, align = "start", alignOffset = 0, anchor, ...props }) {
23
- return (_jsx(ComboboxPrimitive.Portal, { children: _jsx(ComboboxPrimitive.Positioner, { side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, anchor: anchor, className: "isolate z-50", children: _jsx(ComboboxPrimitive.Popup, { "data-slot": "combobox-content", "data-chips": !!anchor, className: cn("dark group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props }) }) }));
23
+ return (_jsx(ComboboxPrimitive.Portal, { children: _jsx(ComboboxPrimitive.Positioner, { side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, anchor: anchor, className: "isolate z-50", children: _jsx(ComboboxPrimitive.Popup, { "data-slot": "combobox-content", "data-chips": !!anchor, className: cn("group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props }) }) }));
24
24
  }
25
25
  function ComboboxList({ className, ...props }) {
26
26
  return (_jsx(ComboboxPrimitive.List, { "data-slot": "combobox-list", className: cn("no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0", className), ...props }));
@@ -35,7 +35,7 @@ function ComboboxLabel({ className, ...props }) {
35
35
  return (_jsx(ComboboxPrimitive.GroupLabel, { "data-slot": "combobox-label", className: cn("px-2 py-1.5 text-xs text-muted-foreground", className), ...props }));
36
36
  }
37
37
  function ComboboxCollection({ ...props }) {
38
- return (_jsx(ComboboxPrimitive.Collection, { "data-slot": "combobox-collection", ...props }));
38
+ return _jsx(ComboboxPrimitive.Collection, { "data-slot": "combobox-collection", ...props });
39
39
  }
40
40
  function ComboboxEmpty({ className, ...props }) {
41
41
  return (_jsx(ComboboxPrimitive.Empty, { "data-slot": "combobox-empty", className: cn("hidden w-full justify-center py-2 text-center text-sm text-muted-foreground group-data-empty/combobox-content:flex", className), ...props }));
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Dialog as DialogPrimitive } from "radix-ui";
3
- import { cn } from "../lib/cn.js";
3
+ import { cn } from "cn";
4
4
  import { Button } from "./button.js";
5
5
  import { XIcon } from "lucide-react";
6
6
  function Dialog({ ...props }) {
@@ -1,21 +1,26 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
3
- import { cn } from "../lib/cn.js";
3
+ import { cn } from "cn";
4
4
  import { CheckIcon, ChevronRightIcon } from "lucide-react";
5
5
  function DropdownMenu({ ...props }) {
6
6
  return _jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
7
7
  }
8
8
  function DropdownMenuPortal({ ...props }) {
9
- return (_jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props }));
9
+ return _jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
10
10
  }
11
11
  function DropdownMenuTrigger({ ...props }) {
12
- return (_jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props }));
12
+ return _jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
13
13
  }
14
+ // A menu sizes to its items, not to its trigger — behind an icon-sized button
15
+ // the trigger width is a 128px ceiling that wraps every longer item; min-w-32
16
+ // survives as the floor it was meant to be. And it leaves on the frame it is
17
+ // dismissed: while an exit animation runs, the dismissable layer stays mounted
18
+ // and swallows the press that should open the next menu.
14
19
  function DropdownMenuContent({ className, align = "start", sideOffset = 4, ...props }) {
15
- return (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { "data-slot": "dropdown-menu-content", sideOffset: sideOffset, align: align, className: cn("dark z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props }) }));
20
+ return (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { "data-slot": "dropdown-menu-content", sideOffset: sideOffset, align: align, className: cn("z-50 max-h-(--radix-dropdown-menu-content-available-height) w-auto min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95", className), ...props }) }));
16
21
  }
17
22
  function DropdownMenuGroup({ ...props }) {
18
- return (_jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props }));
23
+ return _jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
19
24
  }
20
25
  function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
21
26
  return (_jsx(DropdownMenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: cn("group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive", className), ...props }));
@@ -24,7 +29,7 @@ function DropdownMenuCheckboxItem({ className, children, checked, inset, ...prop
24
29
  return (_jsxs(DropdownMenuPrimitive.CheckboxItem, { "data-slot": "dropdown-menu-checkbox-item", "data-inset": inset, className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), checked: checked, ...props, children: [_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-checkbox-item-indicator", children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
25
30
  }
26
31
  function DropdownMenuRadioGroup({ ...props }) {
27
- return (_jsx(DropdownMenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props }));
32
+ return _jsx(DropdownMenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
28
33
  }
29
34
  function DropdownMenuRadioItem({ className, children, inset, ...props }) {
30
35
  return (_jsxs(DropdownMenuPrimitive.RadioItem, { "data-slot": "dropdown-menu-radio-item", "data-inset": inset, className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-radio-item-indicator", children: _jsx(DropdownMenuPrimitive.ItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
@@ -45,6 +50,6 @@ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
45
50
  return (_jsxs(DropdownMenuPrimitive.SubTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn("flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(ChevronRightIcon, { className: "ml-auto" })] }));
46
51
  }
47
52
  function DropdownMenuSubContent({ className, ...props }) {
48
- return (_jsx(DropdownMenuPrimitive.SubContent, { "data-slot": "dropdown-menu-sub-content", className: cn("dark z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props }));
53
+ return (_jsx(DropdownMenuPrimitive.SubContent, { "data-slot": "dropdown-menu-sub-content", className: cn("z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props }));
49
54
  }
50
55
  export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useMemo } from "react";
3
3
  import { cva } from "class-variance-authority";
4
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
5
5
  import { Label } from "./label.js";
6
6
  import { Separator } from "./separator.js";
7
7
  function FieldSet({ className, ...props }) {
@@ -51,9 +51,7 @@ function FieldError({ className, children, errors, ...props }) {
51
51
  if (!errors?.length) {
52
52
  return null;
53
53
  }
54
- const uniqueErrors = [
55
- ...new Map(errors.map((error) => [error?.message, error])).values(),
56
- ];
54
+ const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()];
57
55
  if (uniqueErrors?.length == 1) {
58
56
  return uniqueErrors[0]?.message;
59
57
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
- import { cn } from "../lib/cn.js";
3
+ import { cn } from "cn";
4
4
  import { Button } from "./button.js";
5
5
  import { Input } from "./input.js";
6
6
  import { Textarea } from "./textarea.js";
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from "../lib/cn.js";
2
+ import { cn } from "cn";
3
3
  function Input({ className, type, ...props }) {
4
4
  return (_jsx("input", { type: type, "data-slot": "input", className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props }));
5
5
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Label as LabelPrimitive } from "radix-ui";
3
- import { cn } from "../lib/cn.js";
3
+ import { cn } from "cn";
4
4
  function Label({ className, ...props }) {
5
5
  return (_jsx(LabelPrimitive.Root, { "data-slot": "label", className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className), ...props }));
6
6
  }
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Progress as ProgressPrimitive } from "radix-ui";
3
+ import { cn } from "cn";
4
+ function Progress({ className, value, ...props }) {
5
+ return (_jsx(ProgressPrimitive.Root, { "data-slot": "progress", value: value, className: cn("relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted", className), ...props, children: _jsx(ProgressPrimitive.Indicator, { "data-slot": "progress-indicator", className: "size-full flex-1 bg-primary transition-all", style: { transform: `translateX(-${100 - (value || 0)}%)` } }) }));
6
+ }
7
+ export { Progress };
@@ -3,8 +3,10 @@ import { Select as SelectPrimitive } from "radix-ui";
3
3
  declare function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>): React.JSX.Element;
4
4
  declare function SelectGroup({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Group>): React.JSX.Element;
5
5
  declare function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>): React.JSX.Element;
6
- declare function SelectTrigger({ className, size, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
6
+ declare function SelectTrigger({ className, size, multiline, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
7
7
  size?: "sm" | "default";
8
+ /** Let the closed trigger grow to its value instead of clamping it to one line. */
9
+ multiline?: boolean;
8
10
  }): React.JSX.Element;
9
11
  declare function SelectContent({ className, children, position, align, ...props }: React.ComponentProps<typeof SelectPrimitive.Content>): React.JSX.Element;
10
12
  declare function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>): React.JSX.Element;
@@ -1,6 +1,7 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { Select as SelectPrimitive } from "radix-ui";
3
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
4
5
  import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
5
6
  function Select({ ...props }) {
6
7
  return _jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
@@ -11,11 +12,13 @@ function SelectGroup({ className, ...props }) {
11
12
  function SelectValue({ ...props }) {
12
13
  return _jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
13
14
  }
14
- function SelectTrigger({ className, size = "default", children, ...props }) {
15
- return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *: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 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" }) })] }));
15
+ function SelectTrigger({ className, size = "default", multiline = false, children, ...props }) {
16
+ return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *: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 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", multiline &&
17
+ "data-[size=default]:h-auto min-h-8 *:data-[slot=select-value]:line-clamp-none", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" }) })] }));
16
18
  }
17
19
  function SelectContent({ className, children, position = "item-aligned", align = "center", ...props }) {
18
- return (_jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { "data-slot": "select-content", "data-align-trigger": position === "item-aligned", className: cn("dark relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className), position: position, align: align, ...props, children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.Viewport, { "data-position": position, className: cn("data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)", position === "popper" && ""), children: children }), _jsx(SelectScrollDownButton, {})] }) }));
20
+ return (_jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { "data-slot": "select-content", "data-align-trigger": position === "item-aligned", className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position === "popper" &&
21
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className), position: position, align: align, ...props, children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.Viewport, { "data-position": position, className: cn("data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)", position === "popper" && ""), children: children }), _jsx(SelectScrollDownButton, {})] }) }));
19
22
  }
20
23
  function SelectLabel({ className, ...props }) {
21
24
  return (_jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn("px-1.5 py-1 text-xs text-muted-foreground", className), ...props }));
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Separator as SeparatorPrimitive } from "radix-ui";
4
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
5
5
  function Separator({ className, orientation = "horizontal", decorative = true, ...props }) {
6
6
  return (_jsx(SeparatorPrimitive.Root, { "data-slot": "separator", decorative: decorative, orientation: orientation, className: cn("shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch", className), ...props }));
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Dialog as SheetPrimitive } from "radix-ui";
3
- import { cn } from "../lib/cn.js";
3
+ import { cn } from "cn";
4
4
  import { Button } from "./button.js";
5
5
  import { XIcon } from "lucide-react";
6
6
  function Sheet({ ...props }) {
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from "../lib/cn.js";
2
+ import { cn } from "cn";
3
3
  function Skeleton({ className, ...props }) {
4
4
  return (_jsx("div", { "data-slot": "skeleton", className: cn("animate-pulse rounded-md bg-muted", className), ...props }));
5
5
  }
@@ -2,14 +2,19 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Toaster as Sonner } from "sonner";
5
- import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react";
6
- // SHADCN FRAMEWORK ADAPTER: shadcn's sonner reads next-themes (a Next.js
7
- // integration). VisionSet is Vite with one theme source, `.dark` on <html>
8
- // (styles.css `@custom-variant dark`). This hook is the only difference from
9
- // frontend/ui-core/shadcn/sonner.tsx; drop it if the app ever adopts a
10
- // provider that shadcn's file can read.
5
+ import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon, } from "lucide-react";
6
+ // The theme this package runs on has one source: the `dark` class on <html>,
7
+ // which is what `styles.css`'s `@custom-variant dark` keys off and therefore
8
+ // what every other component in here already follows. A toast is portalled
9
+ // outside the tree but reads the same page, so it has to answer to the same
10
+ // source hence this hook rather than a `next-themes` `useTheme`, which asks
11
+ // for a React provider none of this runs under. Sonner needs the answer as a
12
+ // value, not a class, which is the only reason the class has to be observed
13
+ // at all.
11
14
  function useTheme() {
12
- const read = () => (typeof document !== "undefined" && document.documentElement.classList.contains("dark") ? "dark" : "light");
15
+ const read = () => typeof document !== "undefined" && document.documentElement.classList.contains("dark")
16
+ ? "dark"
17
+ : "light";
13
18
  const [theme, setTheme] = React.useState(read);
14
19
  React.useEffect(() => {
15
20
  const observer = new MutationObserver(() => setTheme(read()));
@@ -21,11 +26,11 @@ function useTheme() {
21
26
  const Toaster = ({ ...props }) => {
22
27
  const { theme = "system" } = useTheme();
23
28
  return (_jsx(Sonner, { theme: theme, className: "toaster group", icons: {
24
- success: (_jsx(CircleCheckIcon, { className: "size-4" })),
25
- info: (_jsx(InfoIcon, { className: "size-4" })),
26
- warning: (_jsx(TriangleAlertIcon, { className: "size-4" })),
27
- error: (_jsx(OctagonXIcon, { className: "size-4" })),
28
- loading: (_jsx(Loader2Icon, { className: "size-4 animate-spin" })),
29
+ success: _jsx(CircleCheckIcon, { className: "size-4" }),
30
+ info: _jsx(InfoIcon, { className: "size-4" }),
31
+ warning: _jsx(TriangleAlertIcon, { className: "size-4" }),
32
+ error: _jsx(OctagonXIcon, { className: "size-4" }),
33
+ loading: _jsx(Loader2Icon, { className: "size-4 animate-spin" }),
29
34
  }, style: {
30
35
  "--normal-bg": "var(--popover)",
31
36
  "--normal-text": "var(--popover-foreground)",
@@ -7,4 +7,4 @@ declare function TableRow({ className, ...props }: React.ComponentProps<"tr">):
7
7
  declare function TableHead({ className, ...props }: React.ComponentProps<"th">): React.JSX.Element;
8
8
  declare function TableCell({ className, ...props }: React.ComponentProps<"td">): React.JSX.Element;
9
9
  declare function TableCaption({ className, ...props }: React.ComponentProps<"caption">): React.JSX.Element;
10
- export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, };
10
+ export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from "../lib/cn.js";
2
+ import { cn } from "cn";
3
3
  function Table({ className, ...props }) {
4
4
  return (_jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: _jsx("table", { "data-slot": "table", className: cn("w-full caption-bottom text-sm", className), ...props }) }));
5
5
  }
6
6
  function TableHeader({ className, ...props }) {
7
- return (_jsx("thead", { "data-slot": "table-header", className: cn("[&_tr]:border-b", className), ...props }));
7
+ return _jsx("thead", { "data-slot": "table-header", className: cn("[&_tr]:border-b", className), ...props });
8
8
  }
9
9
  function TableBody({ className, ...props }) {
10
10
  return (_jsx("tbody", { "data-slot": "table-body", className: cn("[&_tr:last-child]:border-0", className), ...props }));
@@ -24,4 +24,4 @@ function TableCell({ className, ...props }) {
24
24
  function TableCaption({ className, ...props }) {
25
25
  return (_jsx("caption", { "data-slot": "table-caption", className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
26
26
  }
27
- export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, };
27
+ export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
3
  import { Tabs as TabsPrimitive } from "radix-ui";
4
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
5
5
  function Tabs({ className, orientation = "horizontal", ...props }) {
6
6
  return (_jsx(TabsPrimitive.Root, { "data-slot": "tabs", "data-orientation": orientation, className: cn("group/tabs flex gap-2 data-horizontal:flex-col", className), ...props }));
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from "../lib/cn.js";
2
+ import { cn } from "cn";
3
3
  function Textarea({ className, ...props }) {
4
4
  return (_jsx("textarea", { "data-slot": "textarea", className: cn("flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props }));
5
5
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Tooltip as TooltipPrimitive } from "radix-ui";
4
- import { cn } from "../lib/cn.js";
4
+ import { cn } from "cn";
5
5
  function TooltipProvider({ delayDuration = 0, ...props }) {
6
6
  return (_jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration: delayDuration, ...props }));
7
7
  }
@@ -0,0 +1,28 @@
1
+ /** Every `file:line` in `text` painting with the status palette, outside a comment. */
2
+ export declare function statusPaletteIn(file: string, text: string): string[];
3
+ /** Every `file:line` in `text` reaching for a colour family that competes with the status palette. */
4
+ export declare function competingStatusPaletteIn(file: string, text: string): string[];
5
+ /** Every `file:line` in `text` that puts a colour inside a Tailwind class. */
6
+ export declare function colouredClassesIn(file: string, text: string): string[];
7
+ /** Every line in `text` that paints with the brand colour. */
8
+ export declare function brandUsagesIn(file: string, text: string): {
9
+ file: string;
10
+ at: number;
11
+ text: string;
12
+ }[];
13
+ /**
14
+ * The `{ … }` body belonging to the block whose header (e.g. `:root {` or
15
+ * `.dark {`) appears first in the file, matched by brace depth rather than by
16
+ * the next `\n}` so a nested `calc(...)` or `color-mix(...)` cannot fool it.
17
+ */
18
+ export declare function blockBody(css: string, header: string): string;
19
+ /** Every `--name: value;` declaration in a block, keyed WITH the leading `--`. */
20
+ export declare function rawDeclarations(block: string): Map<string, string>;
21
+ /** The same, keyed WITHOUT the leading `--` — the shape `LIGHT_THEME` uses. */
22
+ export declare function declarations(block: string): Map<string, string>;
23
+ /**
24
+ * The foundation token names, read off the shipped stylesheet's `:root` so
25
+ * they can never drift from what actually runs. `radius` is a geometry
26
+ * setting, not a colour token, and is excluded — it matches LIGHT_THEME's keys.
27
+ */
28
+ export declare function foundationTokenNames(): string[];