@octanejs/shadcn 0.0.38 → 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 +15 -11
  3. package/package.json +13 -7
  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 +1 -1
  15. package/src/bases/base-ui/ui/dialog.tsrx +1 -1
  16. package/src/bases/base-ui/ui/dropdown-menu.tsrx +1 -1
  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 +1 -1
  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 +1 -1
  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 +1 -1
  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 +1 -1
  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 +1 -1
  42. package/src/bases/base-ui/ui/textarea.tsrx +1 -1
  43. package/src/bases/base-ui/ui/toggle-group.tsrx +1 -1
  44. package/src/bases/base-ui/ui/toggle.tsrx +1 -1
  45. package/src/bases/base-ui/ui/tooltip.tsrx +1 -1
  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
@@ -0,0 +1,157 @@
1
+ // Adapted from shadcn/ui 4.21.0 (7c9eaba1), Base UI with the Nova style.
2
+ // MIT: see LICENSE.upstream. Octane uses native events and refs as props.
3
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from '@octanejs/lucide';
4
+ import * as React from 'octane';
5
+ import { Select as SelectPrimitive } from '@octanejs/base-ui/select';
6
+ import { cn } from 'cn';
7
+
8
+ const Select = SelectPrimitive.Root;
9
+
10
+ function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
11
+ return <SelectPrimitive.Group
12
+ data-slot="select-group"
13
+ className={cn('scroll-my-1 p-1', className)}
14
+ {...props}
15
+ />;
16
+ }
17
+
18
+ function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
19
+ return <SelectPrimitive.Value
20
+ data-slot="select-value"
21
+ className={cn('flex flex-1 text-left', className)}
22
+ {...props}
23
+ />;
24
+ }
25
+
26
+ function SelectTrigger({
27
+ className,
28
+ size = 'default',
29
+ children,
30
+ ...props
31
+ }: SelectPrimitive.Trigger.Props & {
32
+ size?: 'sm' | 'default';
33
+ }) {
34
+ return <SelectPrimitive.Trigger
35
+ data-slot="select-trigger"
36
+ data-size={size}
37
+ className={cn(
38
+ 'border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*=\'size-\'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0',
39
+ className,
40
+ )}
41
+ {...props}
42
+ >
43
+ {children}
44
+ <SelectPrimitive.Icon
45
+ render={<ChevronDownIcon className="text-muted-foreground size-4 pointer-events-none" />}
46
+ />
47
+ </SelectPrimitive.Trigger>;
48
+ }
49
+
50
+ function SelectContent({
51
+ className,
52
+ children,
53
+ side = 'bottom',
54
+ sideOffset = 4,
55
+ align = 'center',
56
+ alignOffset = 0,
57
+ alignItemWithTrigger = true,
58
+ ...props
59
+ }: SelectPrimitive.Popup.Props & Pick<
60
+ SelectPrimitive.Positioner.Props,
61
+ 'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger'
62
+ >) {
63
+ return <SelectPrimitive.Portal>
64
+ <SelectPrimitive.Positioner
65
+ side={side}
66
+ sideOffset={sideOffset}
67
+ align={align}
68
+ alignOffset={alignOffset}
69
+ alignItemWithTrigger={alignItemWithTrigger}
70
+ className="isolate z-50"
71
+ >
72
+ <SelectPrimitive.Popup
73
+ data-slot="select-content"
74
+ data-align-trigger={alignItemWithTrigger}
75
+ className={cn(
76
+ 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 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 ring-foreground/10 min-w-36 rounded-lg shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 cn-menu-target cn-menu-translucent relative isolate z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto data-[align-trigger=true]:animate-none',
77
+ className,
78
+ )}
79
+ {...props}
80
+ >
81
+ <SelectScrollUpButton />
82
+ <SelectPrimitive.List>{children}</SelectPrimitive.List>
83
+ <SelectScrollDownButton />
84
+ </SelectPrimitive.Popup>
85
+ </SelectPrimitive.Positioner>
86
+ </SelectPrimitive.Portal>;
87
+ }
88
+
89
+ function SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {
90
+ return <SelectPrimitive.GroupLabel
91
+ data-slot="select-label"
92
+ className={cn('text-muted-foreground px-1.5 py-1 text-xs', className)}
93
+ {...props}
94
+ />;
95
+ }
96
+
97
+ function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props) {
98
+ return <SelectPrimitive.Item
99
+ data-slot="select-item"
100
+ className={cn(
101
+ 'focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*=\'size-\'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
102
+ className,
103
+ )}
104
+ {...props}
105
+ >
106
+ <SelectPrimitive.ItemText
107
+ className="flex flex-1 gap-2 shrink-0 whitespace-nowrap"
108
+ >{children}</SelectPrimitive.ItemText>
109
+ <SelectPrimitive.ItemIndicator
110
+ render={<span
111
+ className="pointer-events-none absolute right-2 flex size-4 items-center justify-center"
112
+ />}
113
+ >
114
+ <CheckIcon className="pointer-events-none" />
115
+ </SelectPrimitive.ItemIndicator>
116
+ </SelectPrimitive.Item>;
117
+ }
118
+
119
+ function SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {
120
+ return <SelectPrimitive.Separator
121
+ data-slot="select-separator"
122
+ className={cn('bg-border -mx-1 my-1 h-px pointer-events-none', className)}
123
+ {...props}
124
+ />;
125
+ }
126
+
127
+ function SelectScrollUpButton({ className, ...props }: React.ComponentProps<
128
+ typeof SelectPrimitive.ScrollUpArrow
129
+ >) {
130
+ return <SelectPrimitive.ScrollUpArrow
131
+ data-slot="select-scroll-up-button"
132
+ className={cn(
133
+ 'bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*=\'size-\'])]:size-4 top-0 w-full',
134
+ className,
135
+ )}
136
+ {...props}
137
+ >
138
+ <ChevronUpIcon />
139
+ </SelectPrimitive.ScrollUpArrow>;
140
+ }
141
+
142
+ function SelectScrollDownButton({ className, ...props }: React.ComponentProps<
143
+ typeof SelectPrimitive.ScrollDownArrow
144
+ >) {
145
+ return <SelectPrimitive.ScrollDownArrow
146
+ data-slot="select-scroll-down-button"
147
+ className={cn(
148
+ 'bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*=\'size-\'])]:size-4 bottom-0 w-full',
149
+ className,
150
+ )}
151
+ {...props}
152
+ >
153
+ <ChevronDownIcon />
154
+ </SelectPrimitive.ScrollDownArrow>;
155
+ }
156
+
157
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue };
@@ -14,7 +14,7 @@
14
14
  // exactly this reason. The non-conditional utilities stay in step with the other bases.
15
15
  import { Separator as SeparatorPrimitive } from '@octanejs/base-ui/separator';
16
16
 
17
- import { cn } from '../../../lib/utils';
17
+ import { cn } from 'cn';
18
18
 
19
19
  export interface SeparatorProps extends Record<string, unknown> {
20
20
  className?: string;
@@ -27,7 +27,7 @@ import { type OctaneNode } from 'octane';
27
27
  import { Dialog as SheetPrimitive } from '@octanejs/base-ui/dialog';
28
28
  import { XIcon } from '@octanejs/lucide';
29
29
 
30
- import { cn } from '../../../lib/utils';
30
+ import { cn } from 'cn';
31
31
  import { Button } from './button.tsrx';
32
32
 
33
33
  type Props = { className?: string; children?: OctaneNode } & Record<string, unknown>;
@@ -35,7 +35,7 @@ import {
35
35
  import { cva, type VariantProps } from 'class-variance-authority';
36
36
  import { PanelLeftIcon } from '@octanejs/lucide';
37
37
 
38
- import { cn } from '../../../lib/utils';
38
+ import { cn } from 'cn';
39
39
  import { useIsMobile } from '../../../hooks/use-mobile';
40
40
  import { Button } from './button.tsrx';
41
41
  import { Input } from './input.tsrx';
@@ -5,7 +5,7 @@
5
5
  // Skeleton is the WORST case for this, and the reason the whole batch is labelled: the Radix
6
6
  // base renders `bg-accent` where the React Aria base renders `bg-muted`, so the one token that
7
7
  // matters here is known to differ ACROSS bases. Verify against the upstream source.
8
- import { cn } from '../../../lib/utils';
8
+ import { cn } from 'cn';
9
9
  import type { DivProps } from '../../../lib/types';
10
10
 
11
11
  export function Skeleton({ className, ...props }: DivProps) @{
@@ -27,7 +27,7 @@
27
27
  import { useMemo } from 'octane';
28
28
  import { Slider as SliderPrimitive } from '@octanejs/base-ui/slider';
29
29
 
30
- import { cn } from '../../../lib/utils';
30
+ import { cn } from 'cn';
31
31
 
32
32
  export interface SliderProps<
33
33
  Value extends number | readonly number[] = number | readonly number[],
@@ -13,7 +13,7 @@
13
13
  // describe them.
14
14
  import { Loader2Icon } from '@octanejs/lucide';
15
15
 
16
- import { cn } from '../../../lib/utils';
16
+ import { cn } from 'cn';
17
17
 
18
18
  export interface SpinnerProps extends Record<string, unknown> {
19
19
  className?: string;
@@ -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.
@@ -12,7 +12,7 @@
12
12
  import { cva, type VariantProps } from 'class-variance-authority';
13
13
  import { Tabs as TabsPrimitive } from '@octanejs/base-ui/tabs';
14
14
 
15
- import { cn } from '../../../lib/utils';
15
+ import { cn } from 'cn';
16
16
 
17
17
  type StyledProps<P> = Omit<P, 'className'> & { className?: string };
18
18
 
@@ -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'>) @{
@@ -27,7 +27,7 @@ import { type VariantProps } from 'class-variance-authority';
27
27
  import { ToggleGroup as ToggleGroupPrimitive } from '@octanejs/base-ui/toggle-group';
28
28
  import { Toggle as TogglePrimitive } from '@octanejs/base-ui/toggle';
29
29
 
30
- import { cn } from '../../../lib/utils';
30
+ import { cn } from 'cn';
31
31
  import { toggleVariants } from './toggle.tsrx';
32
32
 
33
33
  const ToggleGroupContext = createContext<
@@ -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;
@@ -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;