@octanejs/shadcn 0.0.37 → 0.0.39

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 (119) hide show
  1. package/{LICENSE → LICENSE.upstream} +1 -1
  2. package/README.md +22 -19
  3. package/package.json +17 -11
  4. package/src/bases/base-ui/ui/accordion.tsrx +1 -1
  5. package/src/bases/base-ui/ui/alert-dialog.tsrx +1 -1
  6. package/src/bases/base-ui/ui/alert.tsrx +1 -1
  7. package/src/bases/base-ui/ui/aspect-ratio.tsrx +1 -1
  8. package/src/bases/base-ui/ui/avatar.tsrx +1 -1
  9. package/src/bases/base-ui/ui/badge.tsrx +1 -1
  10. package/src/bases/base-ui/ui/breadcrumb.tsrx +1 -1
  11. package/src/bases/base-ui/ui/button.tsrx +1 -1
  12. package/src/bases/base-ui/ui/card.tsrx +1 -1
  13. package/src/bases/base-ui/ui/checkbox.tsrx +1 -1
  14. package/src/bases/base-ui/ui/context-menu.tsrx +22 -17
  15. package/src/bases/base-ui/ui/dialog.tsrx +31 -40
  16. package/src/bases/base-ui/ui/dropdown-menu.tsrx +22 -17
  17. package/src/bases/base-ui/ui/empty.tsrx +1 -1
  18. package/src/bases/base-ui/ui/field.tsrx +1 -1
  19. package/src/bases/base-ui/ui/hover-card.tsrx +18 -16
  20. package/src/bases/base-ui/ui/input.tsrx +1 -1
  21. package/src/bases/base-ui/ui/item.tsrx +1 -1
  22. package/src/bases/base-ui/ui/kbd.tsrx +1 -1
  23. package/src/bases/base-ui/ui/label.tsrx +1 -1
  24. package/src/bases/base-ui/ui/menubar.tsrx +22 -17
  25. package/src/bases/base-ui/ui/native-select.tsrx +1 -1
  26. package/src/bases/base-ui/ui/navigation-menu.tsrx +137 -0
  27. package/src/bases/base-ui/ui/pagination.tsrx +1 -1
  28. package/src/bases/base-ui/ui/popover.tsrx +18 -16
  29. package/src/bases/base-ui/ui/progress.tsrx +1 -1
  30. package/src/bases/base-ui/ui/radio-group.tsrx +1 -1
  31. package/src/bases/base-ui/ui/scroll-area.tsrx +44 -0
  32. package/src/bases/base-ui/ui/select.tsrx +157 -0
  33. package/src/bases/base-ui/ui/separator.tsrx +1 -1
  34. package/src/bases/base-ui/ui/sheet.tsrx +1 -1
  35. package/src/bases/base-ui/ui/sidebar.tsrx +1 -1
  36. package/src/bases/base-ui/ui/skeleton.tsrx +1 -1
  37. package/src/bases/base-ui/ui/slider.tsrx +41 -52
  38. package/src/bases/base-ui/ui/spinner.tsrx +1 -1
  39. package/src/bases/base-ui/ui/switch.tsrx +1 -1
  40. package/src/bases/base-ui/ui/table.tsrx +1 -1
  41. package/src/bases/base-ui/ui/tabs.tsrx +8 -17
  42. package/src/bases/base-ui/ui/textarea.tsrx +1 -1
  43. package/src/bases/base-ui/ui/toggle-group.tsrx +22 -32
  44. package/src/bases/base-ui/ui/toggle.tsrx +1 -1
  45. package/src/bases/base-ui/ui/tooltip.tsrx +18 -16
  46. package/src/bases/radix/ui/accordion.tsrx +1 -1
  47. package/src/bases/radix/ui/alert-dialog.tsrx +1 -1
  48. package/src/bases/radix/ui/alert.tsrx +1 -1
  49. package/src/bases/radix/ui/avatar.tsrx +1 -1
  50. package/src/bases/radix/ui/badge.tsrx +1 -1
  51. package/src/bases/radix/ui/breadcrumb.tsrx +1 -1
  52. package/src/bases/radix/ui/button.tsrx +1 -1
  53. package/src/bases/radix/ui/card.tsrx +1 -1
  54. package/src/bases/radix/ui/checkbox.tsrx +1 -1
  55. package/src/bases/radix/ui/context-menu.tsrx +1 -1
  56. package/src/bases/radix/ui/dialog.tsrx +1 -1
  57. package/src/bases/radix/ui/dropdown-menu.tsrx +1 -1
  58. package/src/bases/radix/ui/empty.tsrx +1 -1
  59. package/src/bases/radix/ui/field.tsrx +1 -1
  60. package/src/bases/radix/ui/hover-card.tsrx +1 -1
  61. package/src/bases/radix/ui/input.tsrx +1 -1
  62. package/src/bases/radix/ui/item.tsrx +1 -1
  63. package/src/bases/radix/ui/kbd.tsrx +1 -1
  64. package/src/bases/radix/ui/label.tsrx +1 -1
  65. package/src/bases/radix/ui/menubar.tsrx +1 -1
  66. package/src/bases/radix/ui/native-select.tsrx +1 -1
  67. package/src/bases/radix/ui/navigation-menu.tsrx +1 -1
  68. package/src/bases/radix/ui/pagination.tsrx +1 -1
  69. package/src/bases/radix/ui/popover.tsrx +1 -1
  70. package/src/bases/radix/ui/progress.tsrx +1 -1
  71. package/src/bases/radix/ui/radio-group.tsrx +1 -1
  72. package/src/bases/radix/ui/scroll-area.tsrx +1 -1
  73. package/src/bases/radix/ui/select.tsrx +1 -1
  74. package/src/bases/radix/ui/separator.tsrx +1 -1
  75. package/src/bases/radix/ui/sheet.tsrx +1 -1
  76. package/src/bases/radix/ui/sidebar.tsrx +1 -1
  77. package/src/bases/radix/ui/skeleton.tsrx +1 -1
  78. package/src/bases/radix/ui/slider.tsrx +1 -1
  79. package/src/bases/radix/ui/spinner.tsrx +1 -1
  80. package/src/bases/radix/ui/switch.tsrx +1 -1
  81. package/src/bases/radix/ui/table.tsrx +1 -1
  82. package/src/bases/radix/ui/tabs.tsrx +1 -1
  83. package/src/bases/radix/ui/textarea.tsrx +1 -1
  84. package/src/bases/radix/ui/toggle-group.tsrx +1 -1
  85. package/src/bases/radix/ui/toggle.tsrx +1 -1
  86. package/src/bases/radix/ui/tooltip.tsrx +1 -1
  87. package/src/bases/react-aria/ui/accordion.tsrx +1 -1
  88. package/src/bases/react-aria/ui/alert-dialog.tsrx +1 -1
  89. package/src/bases/react-aria/ui/alert.tsrx +1 -1
  90. package/src/bases/react-aria/ui/aspect-ratio.tsrx +1 -1
  91. package/src/bases/react-aria/ui/avatar.tsrx +1 -1
  92. package/src/bases/react-aria/ui/badge.tsrx +1 -1
  93. package/src/bases/react-aria/ui/breadcrumb.tsrx +1 -1
  94. package/src/bases/react-aria/ui/button.tsrx +1 -1
  95. package/src/bases/react-aria/ui/card.tsrx +1 -1
  96. package/src/bases/react-aria/ui/checkbox.tsrx +1 -1
  97. package/src/bases/react-aria/ui/dialog.tsrx +1 -1
  98. package/src/bases/react-aria/ui/empty.tsrx +1 -1
  99. package/src/bases/react-aria/ui/field.tsrx +1 -1
  100. package/src/bases/react-aria/ui/input.tsrx +1 -1
  101. package/src/bases/react-aria/ui/item.tsrx +1 -1
  102. package/src/bases/react-aria/ui/kbd.tsrx +1 -1
  103. package/src/bases/react-aria/ui/label.tsrx +1 -1
  104. package/src/bases/react-aria/ui/native-select.tsrx +1 -1
  105. package/src/bases/react-aria/ui/pagination.tsrx +1 -1
  106. package/src/bases/react-aria/ui/popover.tsrx +1 -1
  107. package/src/bases/react-aria/ui/radio-group.tsrx +1 -1
  108. package/src/bases/react-aria/ui/scroll-area.tsrx +1 -1
  109. package/src/bases/react-aria/ui/separator.tsrx +1 -1
  110. package/src/bases/react-aria/ui/sheet.tsrx +1 -1
  111. package/src/bases/react-aria/ui/skeleton.tsrx +1 -1
  112. package/src/bases/react-aria/ui/slider.tsrx +1 -1
  113. package/src/bases/react-aria/ui/spinner.tsrx +1 -1
  114. package/src/bases/react-aria/ui/switch.tsrx +1 -1
  115. package/src/bases/react-aria/ui/table.tsrx +1 -1
  116. package/src/bases/react-aria/ui/tabs.tsrx +1 -1
  117. package/src/bases/react-aria/ui/textarea.tsrx +1 -1
  118. package/src/bases/react-aria/ui/toggle.tsrx +1 -1
  119. package/src/lib/utils.ts +1 -8
@@ -16,7 +16,7 @@
16
16
  // rather than upstream's Base UI source.
17
17
  import { Switch as SwitchPrimitive } from '@octanejs/base-ui/switch';
18
18
 
19
- import { cn } from '../../../lib/utils';
19
+ import { cn } from 'cn';
20
20
 
21
21
  export interface SwitchProps extends Record<string, unknown> {
22
22
  className?: string;
@@ -7,7 +7,7 @@
7
7
  // `data-[state=selected]` on the row is written by the CONSUMER — a data-table library setting
8
8
  // selection state — not emitted by anything underneath, so unlike checkbox or toggle it is not a
9
9
  // Radix-ism that needs translating.
10
- import { cn } from '../../../lib/utils';
10
+ import { cn } from 'cn';
11
11
 
12
12
  // Multi-host family (div/table/thead/tbody/tr/th/td/caption): no single host
13
13
  // prop table applies, so the shared alias stays structural.
@@ -2,17 +2,8 @@
2
2
  // class strings verbatim. Runs on @octanejs/base-ui's `Tabs`, which was ported for this family:
3
3
  // Root / List / Tab / Panel.
4
4
  //
5
- // ONE DEPARTURE FROM THE SOURCE, FORCED BY A VERSION SKEW. Upstream writes its orientation variants
6
- // as `data-horizontal:` / `data-vertical:` bare attributes. The pinned @octanejs/base-ui (v1.6.0)
7
- // converts the orientation state to `data-orientation="horizontal" | "vertical"` instead, so those
8
- // utilities would match nothing: the root would never switch to a column, and every
9
- // `group-data-horizontal/tabs:` and `group-data-vertical/tabs:` selector on the trigger would be
10
- // dead. They are written as `data-[orientation=…]:` here.
11
- //
12
- // This is the SAME skew the slider hit, and it is not a porting mistake in either layer — shadcn's
13
- // Base UI sources target a newer Base UI than the pin this package binds. The primitive stays
14
- // faithful to its pin; the adaptation belongs here. When the binding moves to a release that emits
15
- // the bare attributes, these revert to upstream's spelling.
5
+ // Base UI 1.8 emits `data-orientation="horizontal" | "vertical"`, so orientation
6
+ // selectors target the attribute value on the root, list, trigger, and panel.
16
7
  //
17
8
  // `data-active` on the trigger needs no such treatment: the pin emits it exactly as upstream's
18
9
  // classes expect (verified by rendering).
@@ -21,11 +12,11 @@
21
12
  import { cva, type VariantProps } from 'class-variance-authority';
22
13
  import { Tabs as TabsPrimitive } from '@octanejs/base-ui/tabs';
23
14
 
24
- import { cn } from '../../../lib/utils';
15
+ import { cn } from 'cn';
25
16
 
26
- type Props = { className?: string } & Record<string, unknown>;
17
+ type StyledProps<P> = Omit<P, 'className'> & { className?: string };
27
18
 
28
- export interface TabsProps extends Props {
19
+ export interface TabsProps extends StyledProps<TabsPrimitive.Root.Props> {
29
20
  orientation?: 'horizontal' | 'vertical';
30
21
  }
31
22
 
@@ -54,7 +45,7 @@ export const tabsListVariants = cva(
54
45
  },
55
46
  );
56
47
 
57
- export interface TabsListProps extends Props {
48
+ export interface TabsListProps extends StyledProps<TabsPrimitive.List.Props> {
58
49
  variant?: VariantProps<typeof tabsListVariants>['variant'];
59
50
  }
60
51
 
@@ -67,7 +58,7 @@ export function TabsList({ className, variant = 'default', ...props }: TabsListP
67
58
  />
68
59
  }
69
60
 
70
- export function TabsTrigger({ className, ...props }: Props) @{
61
+ export function TabsTrigger({ className, ...props }: StyledProps<TabsPrimitive.Tab.Props>) @{
71
62
  <TabsPrimitive.Tab
72
63
  data-slot="tabs-trigger"
73
64
  className={cn(
@@ -81,7 +72,7 @@ export function TabsTrigger({ className, ...props }: Props) @{
81
72
  />
82
73
  }
83
74
 
84
- export function TabsContent({ className, ...props }: Props) @{
75
+ export function TabsContent({ className, ...props }: StyledProps<TabsPrimitive.Panel.Props>) @{
85
76
  <TabsPrimitive.Panel
86
77
  data-slot="tabs-content"
87
78
  className={cn('flex-1 text-sm outline-none', className)}
@@ -7,7 +7,7 @@
7
7
  //
8
8
  // Octane divergence (shadcn-native-input-events): per-keystroke handling is the native `onInput` event, not a synthetic
9
9
  // `onChange`; native `change` keeps its commit-on-blur meaning.
10
- import { cn } from '../../../lib/utils';
10
+ import { cn } from 'cn';
11
11
  import type { HostProps } from '../../../lib/types';
12
12
 
13
13
  export function Textarea({ className, ...props }: HostProps<'textarea'>) @{
@@ -20,18 +20,14 @@
20
20
  // The pressed dialect is `data-pressed`, not radix's `data-[state=on]` — see toggle.tsrx, whose
21
21
  // `toggleVariants` this file reuses, so the two bases cannot drift apart.
22
22
  //
23
- // ToggleGroup is composed with createElement: the consumer's children must sit INSIDE the context
24
- // Provider, and opaque compiled .tsrx children can only flow through the props.children channel
25
- // (see breadcrumb.tsrx's comment).
26
- //
27
23
  // UNVERIFIED PROVENANCE: class strings come from this package's radix base rather than
28
24
  // transcribed from upstream's Base UI source.
29
- import { createContext, createElement, useContext, type OctaneNode } from 'octane';
25
+ import { createContext, useContext, type CSSProperties, type OctaneNode } from 'octane';
30
26
  import { type VariantProps } from 'class-variance-authority';
31
27
  import { ToggleGroup as ToggleGroupPrimitive } from '@octanejs/base-ui/toggle-group';
32
28
  import { Toggle as TogglePrimitive } from '@octanejs/base-ui/toggle';
33
29
 
34
- import { cn } from '../../../lib/utils';
30
+ import { cn } from 'cn';
35
31
  import { toggleVariants } from './toggle.tsrx';
36
32
 
37
33
  const ToggleGroupContext = createContext<
@@ -65,32 +61,26 @@ export function ToggleGroup({
65
61
  type,
66
62
  children,
67
63
  ...props
68
- }: ToggleGroupProps) {
69
- return createElement(
70
- ToggleGroupPrimitive,
71
- {
72
- 'data-slot': 'toggle-group',
73
- 'data-variant': variant,
74
- 'data-size': size,
75
- 'data-spacing': spacing,
76
- // Forwarded to the primitive: it drives the arrow-key axis (a vertical group must
77
- // ignore left/right and use up/down). The primitive also emits `data-orientation`
78
- // itself, so unlike the radix base this is not set by hand.
79
- orientation,
80
- multiple: type === 'multiple',
81
- style: { '--gap': spacing },
82
- className: cn(
83
- 'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',
84
- className,
85
- ),
86
- ...props,
87
- },
88
- createElement(
89
- ToggleGroupContext.Provider,
90
- { value: { variant, size, spacing, orientation } },
91
- children,
92
- ),
93
- );
64
+ }: ToggleGroupProps) @{
65
+ const style: CSSProperties & { '--gap': number } = { '--gap': spacing };
66
+ <ToggleGroupPrimitive
67
+ data-slot="toggle-group"
68
+ data-variant={variant}
69
+ data-size={size}
70
+ data-spacing={spacing}
71
+ orientation={orientation}
72
+ multiple={type === 'multiple'}
73
+ style={style}
74
+ className={cn(
75
+ 'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',
76
+ className,
77
+ )}
78
+ {...props}
79
+ >
80
+ <ToggleGroupContext.Provider
81
+ value={{ variant, size, spacing, orientation }}
82
+ >{children}</ToggleGroupContext.Provider>
83
+ </ToggleGroupPrimitive>
94
84
  }
95
85
 
96
86
  export interface ToggleGroupItemProps extends Record<string, unknown> {
@@ -14,7 +14,7 @@
14
14
  import { cva, type VariantProps } from 'class-variance-authority';
15
15
  import { Toggle as TogglePrimitive } from '@octanejs/base-ui/toggle';
16
16
 
17
- import { cn } from '../../../lib/utils';
17
+ import { cn } from 'cn';
18
18
 
19
19
  export const toggleVariants = cva(
20
20
  'inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-pressed:bg-accent data-pressed:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
@@ -15,7 +15,7 @@
15
15
  import { createElement, Fragment, type OctaneNode } from 'octane';
16
16
  import { Tooltip as TooltipPrimitive } from '@octanejs/base-ui/tooltip';
17
17
 
18
- import { cn } from '../../../lib/utils';
18
+ import { cn } from 'cn';
19
19
 
20
20
  export interface TooltipProviderProps extends Record<string, unknown> {
21
21
  delay?: number;
@@ -39,21 +39,23 @@ export interface TooltipContentProps extends Record<string, unknown> {
39
39
  children?: OctaneNode;
40
40
  }
41
41
 
42
- export interface BaseUiPositioningProps {
43
- /** Forwarded to the Positioner; see the note at the top of this file. */
44
- side?: 'top' | 'right' | 'bottom' | 'left';
45
- sideOffset?: number;
46
- align?: 'start' | 'center' | 'end';
47
- alignOffset?: number;
48
- anchor?: unknown;
49
- positionMethod?: 'absolute' | 'fixed';
50
- collisionBoundary?: unknown;
51
- collisionPadding?: unknown;
52
- collisionAvoidance?: unknown;
53
- arrowPadding?: number;
54
- sticky?: boolean;
55
- disableAnchorTracking?: boolean;
56
- }
42
+ /** Props routed to the Positioner rather than the popup. */
43
+ export type BaseUiPositioningProps =
44
+ Pick<
45
+ TooltipPrimitive.Positioner.Props,
46
+ | 'side'
47
+ | 'sideOffset'
48
+ | 'align'
49
+ | 'alignOffset'
50
+ | 'anchor'
51
+ | 'positionMethod'
52
+ | 'collisionBoundary'
53
+ | 'collisionPadding'
54
+ | 'collisionAvoidance'
55
+ | 'arrowPadding'
56
+ | 'sticky'
57
+ | 'disableAnchorTracking'
58
+ >;
57
59
 
58
60
  export function TooltipContent({
59
61
  className,
@@ -9,7 +9,7 @@ import { Accordion as AccordionPrimitive } from '@octanejs/radix';
9
9
  import { ChevronDownIcon, ChevronUpIcon } from '@octanejs/lucide';
10
10
  import type { OctaneNode } from 'octane';
11
11
 
12
- import { cn } from '../../../lib/utils';
12
+ import { cn } from 'cn';
13
13
 
14
14
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
15
15
 
@@ -6,7 +6,7 @@
6
6
  import { createElement, type OctaneNode } from 'octane';
7
7
  import { AlertDialog as AlertDialogPrimitive } from '@octanejs/radix';
8
8
 
9
- import { cn } from '../../../lib/utils';
9
+ import { cn } from 'cn';
10
10
  import { Button, type ButtonProps } from './button.tsrx';
11
11
 
12
12
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
@@ -2,7 +2,7 @@
2
2
  // cva strings verbatim. Pure template JSX (no consumer-children interleave).
3
3
  import { cva, type VariantProps } from 'class-variance-authority';
4
4
 
5
- import { cn } from '../../../lib/utils';
5
+ import { cn } from 'cn';
6
6
  import type { DivProps } from '../../../lib/types';
7
7
 
8
8
  export const alertVariants = cva(
@@ -3,7 +3,7 @@
3
3
  // @octanejs/radix; pure template JSX.
4
4
  import { Avatar as AvatarPrimitive } from '@octanejs/radix';
5
5
 
6
- import { cn } from '../../../lib/utils';
6
+ import { cn } from 'cn';
7
7
 
8
8
  type Props = { className?: string } & Record<string, unknown>;
9
9
 
@@ -4,7 +4,7 @@
4
4
  import { cva, type VariantProps } from 'class-variance-authority';
5
5
  import { Slot } from '@octanejs/radix';
6
6
 
7
- import { cn } from '../../../lib/utils';
7
+ import { cn } from 'cn';
8
8
  import type { HostProps } from '../../../lib/types';
9
9
 
10
10
  export const badgeVariants = cva(
@@ -7,7 +7,7 @@ import { Slot } from '@octanejs/radix';
7
7
  import { ChevronRightIcon, MoreHorizontalIcon } from '@octanejs/lucide';
8
8
  import { createElement, type OctaneNode } from 'octane';
9
9
 
10
- import { cn } from '../../../lib/utils';
10
+ import { cn } from 'cn';
11
11
 
12
12
  type Props = { className?: string } & Record<string, unknown>;
13
13
 
@@ -7,7 +7,7 @@
7
7
  import { cva, type VariantProps } from 'class-variance-authority';
8
8
  import { Slot } from '@octanejs/radix';
9
9
 
10
- import { cn } from '../../../lib/utils';
10
+ import { cn } from 'cn';
11
11
  import type { HostProps } from '../../../lib/types';
12
12
 
13
13
  export const buttonVariants = cva(
@@ -1,6 +1,6 @@
1
1
  // Default-Tailwind (package canonical) card — user-supplied flavor, class strings verbatim (uses the
2
2
  // --card-spacing custom-property pattern and the nova cn-font-heading hook).
3
- import { cn } from '../../../lib/utils';
3
+ import { cn } from 'cn';
4
4
  import type { DivProps } from '../../../lib/types';
5
5
 
6
6
  type Props = DivProps;
@@ -6,7 +6,7 @@
6
6
  import { Checkbox as CheckboxPrimitive } from '@octanejs/radix';
7
7
  import { CheckIcon } from '@octanejs/lucide';
8
8
 
9
- import { cn } from '../../../lib/utils';
9
+ import { cn } from 'cn';
10
10
 
11
11
  export interface CheckboxProps extends Record<string, unknown> {
12
12
  className?: string;
@@ -8,7 +8,7 @@ import { createElement, type OctaneNode } from 'octane';
8
8
  import { ContextMenu as ContextMenuPrimitive } from '@octanejs/radix';
9
9
  import { CheckIcon, ChevronRightIcon } from '@octanejs/lucide';
10
10
 
11
- import { cn } from '../../../lib/utils';
11
+ import { cn } from 'cn';
12
12
 
13
13
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
14
14
 
@@ -9,7 +9,7 @@ import { createElement, type OctaneNode } from 'octane';
9
9
  import { Dialog as DialogPrimitive } from '@octanejs/radix';
10
10
  import { XIcon } from '@octanejs/lucide';
11
11
 
12
- import { cn } from '../../../lib/utils';
12
+ import { cn } from 'cn';
13
13
  import { Button } from './button.tsrx';
14
14
 
15
15
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
@@ -8,7 +8,7 @@ import { createElement, type OctaneNode } from 'octane';
8
8
  import { DropdownMenu as DropdownMenuPrimitive } from '@octanejs/radix';
9
9
  import { CheckIcon, ChevronRightIcon } from '@octanejs/lucide';
10
10
 
11
- import { cn } from '../../../lib/utils';
11
+ import { cn } from 'cn';
12
12
 
13
13
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
14
14
 
@@ -3,7 +3,7 @@
3
3
  // as a <div> (typed as "p") — both preserved as-is.
4
4
  import { cva, type VariantProps } from 'class-variance-authority';
5
5
 
6
- import { cn } from '../../../lib/utils';
6
+ import { cn } from 'cn';
7
7
 
8
8
  type DivProps = { className?: string } & Record<string, unknown>;
9
9
 
@@ -6,7 +6,7 @@
6
6
  import { createElement, useMemo, type OctaneNode } from 'octane';
7
7
  import { cva, type VariantProps } from 'class-variance-authority';
8
8
 
9
- import { cn } from '../../../lib/utils';
9
+ import { cn } from 'cn';
10
10
  import { Label } from './label.tsrx';
11
11
  import { Separator } from './separator.tsrx';
12
12
 
@@ -10,7 +10,7 @@
10
10
  import { createElement } from 'octane';
11
11
  import { HoverCard as HoverCardPrimitive } from '@octanejs/radix';
12
12
 
13
- import { cn } from '../../../lib/utils';
13
+ import { cn } from 'cn';
14
14
 
15
15
  export function HoverCard(props: Record<string, unknown>) @{
16
16
  <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
@@ -1,6 +1,6 @@
1
1
  // Default-Tailwind (package canonical) input — user-supplied flavor, class string verbatim.
2
2
  // Octane divergence (shadcn-native-input-events): per-keystroke handling is the native onInput event.
3
- import { cn } from '../../../lib/utils';
3
+ import { cn } from 'cn';
4
4
  import type { HostProps } from '../../../lib/types';
5
5
 
6
6
  export interface InputProps extends HostProps<'input'> {}
@@ -4,7 +4,7 @@
4
4
  import { cva, type VariantProps } from 'class-variance-authority';
5
5
  import { Slot } from '@octanejs/radix';
6
6
 
7
- import { cn } from '../../../lib/utils';
7
+ import { cn } from 'cn';
8
8
  import { Separator } from './separator.tsrx';
9
9
 
10
10
  type DivProps = { className?: string } & Record<string, unknown>;
@@ -1,7 +1,7 @@
1
1
  // Ported from shadcn-ui/ui@4baadbc6517070ae8f8feb2c97037adc2b305544
2
2
  // apps/v4/registry/bases/radix/ui/kbd.tsx. Note: upstream renders KbdGroup as
3
3
  // a <kbd> host too — preserved as-is.
4
- import { cn } from '../../../lib/utils';
4
+ import { cn } from 'cn';
5
5
  import type { HostProps } from '../../../lib/types';
6
6
 
7
7
  export interface KbdProps extends HostProps<'kbd'> {}
@@ -3,7 +3,7 @@
3
3
  // dropped — octane has no RSC axis).
4
4
  import { Label as LabelPrimitive } from '@octanejs/radix';
5
5
 
6
- import { cn } from '../../../lib/utils';
6
+ import { cn } from 'cn';
7
7
 
8
8
  export interface LabelProps extends Record<string, unknown> {
9
9
  className?: string;
@@ -8,7 +8,7 @@ import { createElement, type OctaneNode } from 'octane';
8
8
  import { Menubar as MenubarPrimitive } from '@octanejs/radix';
9
9
  import { CheckIcon, ChevronRightIcon } from '@octanejs/lucide';
10
10
 
11
- import { cn } from '../../../lib/utils';
11
+ import { cn } from 'cn';
12
12
 
13
13
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
14
14
 
@@ -5,7 +5,7 @@
5
5
  // <select> and the chevron keep their fixed classes.
6
6
  import { ChevronDownIcon } from '@octanejs/lucide';
7
7
 
8
- import { cn } from '../../../lib/utils';
8
+ import { cn } from 'cn';
9
9
 
10
10
  export interface NativeSelectProps extends Record<string, unknown> {
11
11
  className?: string;
@@ -7,7 +7,7 @@ import { cva } from 'class-variance-authority';
7
7
  import { NavigationMenu as NavigationMenuPrimitive } from '@octanejs/radix';
8
8
  import { ChevronDownIcon } from '@octanejs/lucide';
9
9
 
10
- import { cn } from '../../../lib/utils';
10
+ import { cn } from 'cn';
11
11
 
12
12
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
13
13
 
@@ -6,7 +6,7 @@
6
6
  import { createElement, type OctaneNode } from 'octane';
7
7
  import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from '@octanejs/lucide';
8
8
 
9
- import { cn } from '../../../lib/utils';
9
+ import { cn } from 'cn';
10
10
  import { Button, type ButtonProps } from './button.tsrx';
11
11
 
12
12
  type Props = { className?: string } & Record<string, unknown>;
@@ -10,7 +10,7 @@
10
10
  import { createElement } from 'octane';
11
11
  import { Popover as PopoverPrimitive } from '@octanejs/radix';
12
12
 
13
- import { cn } from '../../../lib/utils';
13
+ import { cn } from 'cn';
14
14
 
15
15
  type Props = { className?: string } & Record<string, unknown>;
16
16
 
@@ -5,7 +5,7 @@
5
5
  // Root, whose role/aria-valuemax/data-state contract comes from its defaults.
6
6
  import { Progress as ProgressPrimitive } from '@octanejs/radix';
7
7
 
8
- import { cn } from '../../../lib/utils';
8
+ import { cn } from 'cn';
9
9
 
10
10
  export interface ProgressProps extends Record<string, unknown> {
11
11
  className?: string;
@@ -4,7 +4,7 @@
4
4
  import { RadioGroup as RadioGroupPrimitive } from '@octanejs/radix';
5
5
  import { CircleIcon } from '@octanejs/lucide';
6
6
 
7
- import { cn } from '../../../lib/utils';
7
+ import { cn } from 'cn';
8
8
 
9
9
  type Props = { className?: string } & Record<string, unknown>;
10
10
 
@@ -5,7 +5,7 @@
5
5
  import type { OctaneNode } from 'octane';
6
6
  import { ScrollArea as ScrollAreaPrimitive } from '@octanejs/radix';
7
7
 
8
- import { cn } from '../../../lib/utils';
8
+ import { cn } from 'cn';
9
9
 
10
10
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
11
11
 
@@ -7,7 +7,7 @@ import { createElement, type OctaneNode } from 'octane';
7
7
  import { Select as SelectPrimitive } from '@octanejs/radix';
8
8
  import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from '@octanejs/lucide';
9
9
 
10
- import { cn } from '../../../lib/utils';
10
+ import { cn } from 'cn';
11
11
 
12
12
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
13
13
 
@@ -3,7 +3,7 @@
3
3
  // is dropped — octane has no RSC axis).
4
4
  import { Separator as SeparatorPrimitive } from '@octanejs/radix';
5
5
 
6
- import { cn } from '../../../lib/utils';
6
+ import { cn } from 'cn';
7
7
 
8
8
  export interface SeparatorProps extends Record<string, unknown> {
9
9
  className?: string;
@@ -8,7 +8,7 @@ import { createElement, type OctaneNode } from 'octane';
8
8
  import { Dialog as SheetPrimitive } from '@octanejs/radix';
9
9
  import { XIcon } from '@octanejs/lucide';
10
10
 
11
- import { cn } from '../../../lib/utils';
11
+ import { cn } from 'cn';
12
12
  import { Button } from './button.tsrx';
13
13
 
14
14
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
@@ -18,7 +18,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
18
18
  import { Slot } from '@octanejs/radix';
19
19
  import { PanelLeftIcon } from '@octanejs/lucide';
20
20
 
21
- import { cn } from '../../../lib/utils';
21
+ import { cn } from 'cn';
22
22
  import { useIsMobile } from '../../../hooks/use-mobile';
23
23
  import { Button } from './button.tsrx';
24
24
  import { Input } from './input.tsrx';
@@ -1,6 +1,6 @@
1
1
  // Default-Tailwind flavor (package canonical) — utilities-inlined upstream styling.
2
2
  // apps/v4/registry/bases/radix/ui/skeleton.tsx.
3
- import { cn } from '../../../lib/utils';
3
+ import { cn } from 'cn';
4
4
  import type { HostProps } from '../../../lib/types';
5
5
 
6
6
  export interface SkeletonProps extends HostProps<'div'> {}
@@ -9,7 +9,7 @@
9
9
  import { createElement, useMemo } from 'octane';
10
10
  import { Slider as SliderPrimitive } from '@octanejs/radix';
11
11
 
12
- import { cn } from '../../../lib/utils';
12
+ import { cn } from 'cn';
13
13
 
14
14
  export interface SliderProps extends Record<string, unknown> {
15
15
  className?: string;
@@ -6,7 +6,7 @@
6
6
  // @octanejs/lucide. Other icon libraries are a registry-emit concern.
7
7
  import { Loader2Icon } from '@octanejs/lucide';
8
8
 
9
- import { cn } from '../../../lib/utils';
9
+ import { cn } from 'cn';
10
10
 
11
11
  export interface SpinnerProps extends Record<string, unknown> {
12
12
  className?: string;
@@ -3,7 +3,7 @@
3
3
  // @octanejs/radix; pure template JSX.
4
4
  import { Switch as SwitchPrimitive } from '@octanejs/radix';
5
5
 
6
- import { cn } from '../../../lib/utils';
6
+ import { cn } from 'cn';
7
7
 
8
8
  export interface SwitchProps extends Record<string, unknown> {
9
9
  className?: string;
@@ -2,7 +2,7 @@
2
2
  // apps/v4/registry/bases/radix/ui/table.tsx (the `"use client"` directive is
3
3
  // dropped — octane has no RSC axis). Table renders inside the upstream
4
4
  // table-container wrapper div.
5
- import { cn } from '../../../lib/utils';
5
+ import { cn } from 'cn';
6
6
 
7
7
  // Multi-host family (div/table/thead/tbody/tr/th/td/caption): no single host
8
8
  // prop table applies, so the shared alias stays structural.
@@ -4,7 +4,7 @@
4
4
  import { cva, type VariantProps } from 'class-variance-authority';
5
5
  import { Tabs as TabsPrimitive } from '@octanejs/radix';
6
6
 
7
- import { cn } from '../../../lib/utils';
7
+ import { cn } from 'cn';
8
8
 
9
9
  type Props = { className?: string } & Record<string, unknown>;
10
10
 
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // Octane divergence (shadcn-native-input-events): per-keystroke handling is the native `onInput` event, not
5
5
  // a synthetic `onChange`; native `change` keeps its commit-on-blur meaning.
6
- import { cn } from '../../../lib/utils';
6
+ import { cn } from 'cn';
7
7
  import type { HostProps } from '../../../lib/types';
8
8
 
9
9
  export interface TextareaProps extends HostProps<'textarea'> {}
@@ -10,7 +10,7 @@ import { createContext, createElement, useContext, type OctaneNode } from 'octan
10
10
  import { type VariantProps } from 'class-variance-authority';
11
11
  import { ToggleGroup as ToggleGroupPrimitive } from '@octanejs/radix';
12
12
 
13
- import { cn } from '../../../lib/utils';
13
+ import { cn } from 'cn';
14
14
  import { toggleVariants } from './toggle.tsrx';
15
15
 
16
16
  const ToggleGroupContext = createContext<