@cosmicdrift/kumiko-renderer-web 0.65.0 → 0.66.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 (47) hide show
  1. package/package.json +6 -4
  2. package/src/__tests__/form-action-bar.test.tsx +50 -15
  3. package/src/__tests__/nav-tree.test.tsx +250 -16
  4. package/src/__tests__/primitives.test.tsx +9 -6
  5. package/src/__tests__/render-edit.test.tsx +6 -6
  6. package/src/__tests__/test-utils.tsx +21 -0
  7. package/src/__tests__/workspace-shell.test.tsx +21 -66
  8. package/src/app/__tests__/qualify-nav-provider-key.test.ts +27 -0
  9. package/src/app/client-plugin.tsx +12 -27
  10. package/src/app/create-app.tsx +31 -19
  11. package/src/app/nav-providers-context.tsx +56 -0
  12. package/src/index.ts +8 -0
  13. package/src/layout/app-layout.tsx +9 -2
  14. package/src/layout/default-app-shell.tsx +116 -33
  15. package/src/layout/nav-tree.tsx +491 -125
  16. package/src/layout/sidebar-brand.tsx +40 -0
  17. package/src/layout/sidebar-user.tsx +46 -0
  18. package/src/layout/sidebar.tsx +1 -1
  19. package/src/layout/target-resolver-stub.tsx +3 -5
  20. package/src/layout/workspace-shell.tsx +32 -34
  21. package/src/primitives/file-upload.tsx +118 -0
  22. package/src/primitives/index.tsx +314 -175
  23. package/src/styles.css +76 -50
  24. package/src/ui/avatar.tsx +110 -0
  25. package/src/ui/badge.tsx +49 -0
  26. package/src/ui/breadcrumb.tsx +110 -0
  27. package/src/ui/button.tsx +65 -0
  28. package/src/ui/card.tsx +93 -0
  29. package/src/ui/checkbox.tsx +33 -0
  30. package/src/ui/collapsible.tsx +34 -0
  31. package/src/ui/dropdown-menu.tsx +258 -0
  32. package/src/ui/input.tsx +22 -0
  33. package/src/ui/label.tsx +25 -0
  34. package/src/ui/select.tsx +191 -0
  35. package/src/ui/separator.tsx +29 -0
  36. package/src/ui/sheet.tsx +144 -0
  37. package/src/ui/sidebar.tsx +727 -0
  38. package/src/ui/skeleton.tsx +14 -0
  39. package/src/ui/table.tsx +117 -0
  40. package/src/ui/textarea.tsx +19 -0
  41. package/src/ui/tooltip.tsx +58 -0
  42. package/src/ui/use-mobile.ts +20 -0
  43. package/src/__tests__/visual-tree-integration.test.tsx +0 -314
  44. package/src/app/tree-providers-context.tsx +0 -68
  45. package/src/layout/__tests__/visual-tree.test.tsx +0 -303
  46. package/src/layout/tree-node-renderer.tsx +0 -386
  47. package/src/layout/visual-tree.tsx +0 -398
@@ -0,0 +1,258 @@
1
+ // @ts-nocheck — vendored shadcn, regenerate via scripts/sync-shadcn.ts
2
+ "use client"
3
+
4
+ import * as React from "react"
5
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
6
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
7
+
8
+ import { cn } from "../lib/cn"
9
+
10
+ function DropdownMenu({
11
+ ...props
12
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
13
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
14
+ }
15
+
16
+ function DropdownMenuPortal({
17
+ ...props
18
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
19
+ return (
20
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
21
+ )
22
+ }
23
+
24
+ function DropdownMenuTrigger({
25
+ ...props
26
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
27
+ return (
28
+ <DropdownMenuPrimitive.Trigger
29
+ data-slot="dropdown-menu-trigger"
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ function DropdownMenuContent({
36
+ className,
37
+ sideOffset = 4,
38
+ ...props
39
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
40
+ return (
41
+ <DropdownMenuPrimitive.Portal>
42
+ <DropdownMenuPrimitive.Content
43
+ data-slot="dropdown-menu-content"
44
+ sideOffset={sideOffset}
45
+ className={cn(
46
+ "z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
47
+ className
48
+ )}
49
+ {...props}
50
+ />
51
+ </DropdownMenuPrimitive.Portal>
52
+ )
53
+ }
54
+
55
+ function DropdownMenuGroup({
56
+ ...props
57
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
58
+ return (
59
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
60
+ )
61
+ }
62
+
63
+ function DropdownMenuItem({
64
+ className,
65
+ inset,
66
+ variant = "default",
67
+ ...props
68
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
69
+ inset?: boolean
70
+ variant?: "default" | "destructive"
71
+ }) {
72
+ return (
73
+ <DropdownMenuPrimitive.Item
74
+ data-slot="dropdown-menu-item"
75
+ data-inset={inset}
76
+ data-variant={variant}
77
+ className={cn(
78
+ "relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 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 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!",
79
+ className
80
+ )}
81
+ {...props}
82
+ />
83
+ )
84
+ }
85
+
86
+ function DropdownMenuCheckboxItem({
87
+ className,
88
+ children,
89
+ checked,
90
+ ...props
91
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
92
+ return (
93
+ <DropdownMenuPrimitive.CheckboxItem
94
+ data-slot="dropdown-menu-checkbox-item"
95
+ className={cn(
96
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
97
+ className
98
+ )}
99
+ checked={checked}
100
+ {...props}
101
+ >
102
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
103
+ <DropdownMenuPrimitive.ItemIndicator>
104
+ <CheckIcon className="size-4" />
105
+ </DropdownMenuPrimitive.ItemIndicator>
106
+ </span>
107
+ {children}
108
+ </DropdownMenuPrimitive.CheckboxItem>
109
+ )
110
+ }
111
+
112
+ function DropdownMenuRadioGroup({
113
+ ...props
114
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
115
+ return (
116
+ <DropdownMenuPrimitive.RadioGroup
117
+ data-slot="dropdown-menu-radio-group"
118
+ {...props}
119
+ />
120
+ )
121
+ }
122
+
123
+ function DropdownMenuRadioItem({
124
+ className,
125
+ children,
126
+ ...props
127
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
128
+ return (
129
+ <DropdownMenuPrimitive.RadioItem
130
+ data-slot="dropdown-menu-radio-item"
131
+ className={cn(
132
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
133
+ className
134
+ )}
135
+ {...props}
136
+ >
137
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
138
+ <DropdownMenuPrimitive.ItemIndicator>
139
+ <CircleIcon className="size-2 fill-current" />
140
+ </DropdownMenuPrimitive.ItemIndicator>
141
+ </span>
142
+ {children}
143
+ </DropdownMenuPrimitive.RadioItem>
144
+ )
145
+ }
146
+
147
+ function DropdownMenuLabel({
148
+ className,
149
+ inset,
150
+ ...props
151
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
152
+ inset?: boolean
153
+ }) {
154
+ return (
155
+ <DropdownMenuPrimitive.Label
156
+ data-slot="dropdown-menu-label"
157
+ data-inset={inset}
158
+ className={cn(
159
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
160
+ className
161
+ )}
162
+ {...props}
163
+ />
164
+ )
165
+ }
166
+
167
+ function DropdownMenuSeparator({
168
+ className,
169
+ ...props
170
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
171
+ return (
172
+ <DropdownMenuPrimitive.Separator
173
+ data-slot="dropdown-menu-separator"
174
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
175
+ {...props}
176
+ />
177
+ )
178
+ }
179
+
180
+ function DropdownMenuShortcut({
181
+ className,
182
+ ...props
183
+ }: React.ComponentProps<"span">) {
184
+ return (
185
+ <span
186
+ data-slot="dropdown-menu-shortcut"
187
+ className={cn(
188
+ "ml-auto text-xs tracking-widest text-muted-foreground",
189
+ className
190
+ )}
191
+ {...props}
192
+ />
193
+ )
194
+ }
195
+
196
+ function DropdownMenuSub({
197
+ ...props
198
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
199
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
200
+ }
201
+
202
+ function DropdownMenuSubTrigger({
203
+ className,
204
+ inset,
205
+ children,
206
+ ...props
207
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
208
+ inset?: boolean
209
+ }) {
210
+ return (
211
+ <DropdownMenuPrimitive.SubTrigger
212
+ data-slot="dropdown-menu-sub-trigger"
213
+ data-inset={inset}
214
+ className={cn(
215
+ "flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
216
+ className
217
+ )}
218
+ {...props}
219
+ >
220
+ {children}
221
+ <ChevronRightIcon className="ml-auto size-4" />
222
+ </DropdownMenuPrimitive.SubTrigger>
223
+ )
224
+ }
225
+
226
+ function DropdownMenuSubContent({
227
+ className,
228
+ ...props
229
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
230
+ return (
231
+ <DropdownMenuPrimitive.SubContent
232
+ data-slot="dropdown-menu-sub-content"
233
+ className={cn(
234
+ "z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
235
+ className
236
+ )}
237
+ {...props}
238
+ />
239
+ )
240
+ }
241
+
242
+ export {
243
+ DropdownMenu,
244
+ DropdownMenuPortal,
245
+ DropdownMenuTrigger,
246
+ DropdownMenuContent,
247
+ DropdownMenuGroup,
248
+ DropdownMenuLabel,
249
+ DropdownMenuItem,
250
+ DropdownMenuCheckboxItem,
251
+ DropdownMenuRadioGroup,
252
+ DropdownMenuRadioItem,
253
+ DropdownMenuSeparator,
254
+ DropdownMenuShortcut,
255
+ DropdownMenuSub,
256
+ DropdownMenuSubTrigger,
257
+ DropdownMenuSubContent,
258
+ }
@@ -0,0 +1,22 @@
1
+ // @ts-nocheck — vendored shadcn, regenerate via scripts/sync-shadcn.ts
2
+ import * as React from "react"
3
+
4
+ import { cn } from "../lib/cn"
5
+
6
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
7
+ return (
8
+ <input
9
+ type={type}
10
+ data-slot="input"
11
+ className={cn(
12
+ "h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
13
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
14
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ export { Input }
@@ -0,0 +1,25 @@
1
+ // @ts-nocheck — vendored shadcn, regenerate via scripts/sync-shadcn.ts
2
+ "use client"
3
+
4
+ import * as React from "react"
5
+ import { Label as LabelPrimitive } from "radix-ui"
6
+
7
+ import { cn } from "../lib/cn"
8
+
9
+ function Label({
10
+ className,
11
+ ...props
12
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
13
+ return (
14
+ <LabelPrimitive.Root
15
+ data-slot="label"
16
+ className={cn(
17
+ "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",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ export { Label }
@@ -0,0 +1,191 @@
1
+ // @ts-nocheck — vendored shadcn, regenerate via scripts/sync-shadcn.ts
2
+ "use client"
3
+
4
+ import * as React from "react"
5
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
6
+ import { Select as SelectPrimitive } from "radix-ui"
7
+
8
+ import { cn } from "../lib/cn"
9
+
10
+ function Select({
11
+ ...props
12
+ }: React.ComponentProps<typeof SelectPrimitive.Root>) {
13
+ return <SelectPrimitive.Root data-slot="select" {...props} />
14
+ }
15
+
16
+ function SelectGroup({
17
+ ...props
18
+ }: React.ComponentProps<typeof SelectPrimitive.Group>) {
19
+ return <SelectPrimitive.Group data-slot="select-group" {...props} />
20
+ }
21
+
22
+ function SelectValue({
23
+ ...props
24
+ }: React.ComponentProps<typeof SelectPrimitive.Value>) {
25
+ return <SelectPrimitive.Value data-slot="select-value" {...props} />
26
+ }
27
+
28
+ function SelectTrigger({
29
+ className,
30
+ size = "default",
31
+ children,
32
+ ...props
33
+ }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
34
+ size?: "sm" | "default"
35
+ }) {
36
+ return (
37
+ <SelectPrimitive.Trigger
38
+ data-slot="select-trigger"
39
+ data-size={size}
40
+ className={cn(
41
+ "flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
42
+ className
43
+ )}
44
+ {...props}
45
+ >
46
+ {children}
47
+ <SelectPrimitive.Icon asChild>
48
+ <ChevronDownIcon className="size-4 opacity-50" />
49
+ </SelectPrimitive.Icon>
50
+ </SelectPrimitive.Trigger>
51
+ )
52
+ }
53
+
54
+ function SelectContent({
55
+ className,
56
+ children,
57
+ position = "item-aligned",
58
+ align = "center",
59
+ ...props
60
+ }: React.ComponentProps<typeof SelectPrimitive.Content>) {
61
+ return (
62
+ <SelectPrimitive.Portal>
63
+ <SelectPrimitive.Content
64
+ data-slot="select-content"
65
+ className={cn(
66
+ "relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md 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]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
67
+ position === "popper" &&
68
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
69
+ className
70
+ )}
71
+ position={position}
72
+ align={align}
73
+ {...props}
74
+ >
75
+ <SelectScrollUpButton />
76
+ <SelectPrimitive.Viewport
77
+ className={cn(
78
+ "p-1",
79
+ position === "popper" &&
80
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
81
+ )}
82
+ >
83
+ {children}
84
+ </SelectPrimitive.Viewport>
85
+ <SelectScrollDownButton />
86
+ </SelectPrimitive.Content>
87
+ </SelectPrimitive.Portal>
88
+ )
89
+ }
90
+
91
+ function SelectLabel({
92
+ className,
93
+ ...props
94
+ }: React.ComponentProps<typeof SelectPrimitive.Label>) {
95
+ return (
96
+ <SelectPrimitive.Label
97
+ data-slot="select-label"
98
+ className={cn("px-2 py-1.5 text-xs text-muted-foreground", className)}
99
+ {...props}
100
+ />
101
+ )
102
+ }
103
+
104
+ function SelectItem({
105
+ className,
106
+ children,
107
+ ...props
108
+ }: React.ComponentProps<typeof SelectPrimitive.Item>) {
109
+ return (
110
+ <SelectPrimitive.Item
111
+ data-slot="select-item"
112
+ className={cn(
113
+ "relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
114
+ className
115
+ )}
116
+ {...props}
117
+ >
118
+ <span
119
+ data-slot="select-item-indicator"
120
+ className="absolute right-2 flex size-3.5 items-center justify-center"
121
+ >
122
+ <SelectPrimitive.ItemIndicator>
123
+ <CheckIcon className="size-4" />
124
+ </SelectPrimitive.ItemIndicator>
125
+ </span>
126
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
127
+ </SelectPrimitive.Item>
128
+ )
129
+ }
130
+
131
+ function SelectSeparator({
132
+ className,
133
+ ...props
134
+ }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
135
+ return (
136
+ <SelectPrimitive.Separator
137
+ data-slot="select-separator"
138
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
139
+ {...props}
140
+ />
141
+ )
142
+ }
143
+
144
+ function SelectScrollUpButton({
145
+ className,
146
+ ...props
147
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
148
+ return (
149
+ <SelectPrimitive.ScrollUpButton
150
+ data-slot="select-scroll-up-button"
151
+ className={cn(
152
+ "flex cursor-default items-center justify-center py-1",
153
+ className
154
+ )}
155
+ {...props}
156
+ >
157
+ <ChevronUpIcon className="size-4" />
158
+ </SelectPrimitive.ScrollUpButton>
159
+ )
160
+ }
161
+
162
+ function SelectScrollDownButton({
163
+ className,
164
+ ...props
165
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
166
+ return (
167
+ <SelectPrimitive.ScrollDownButton
168
+ data-slot="select-scroll-down-button"
169
+ className={cn(
170
+ "flex cursor-default items-center justify-center py-1",
171
+ className
172
+ )}
173
+ {...props}
174
+ >
175
+ <ChevronDownIcon className="size-4" />
176
+ </SelectPrimitive.ScrollDownButton>
177
+ )
178
+ }
179
+
180
+ export {
181
+ Select,
182
+ SelectContent,
183
+ SelectGroup,
184
+ SelectItem,
185
+ SelectLabel,
186
+ SelectScrollDownButton,
187
+ SelectScrollUpButton,
188
+ SelectSeparator,
189
+ SelectTrigger,
190
+ SelectValue,
191
+ }
@@ -0,0 +1,29 @@
1
+ // @ts-nocheck — vendored shadcn, regenerate via scripts/sync-shadcn.ts
2
+ "use client"
3
+
4
+ import * as React from "react"
5
+ import { Separator as SeparatorPrimitive } from "radix-ui"
6
+
7
+ import { cn } from "../lib/cn"
8
+
9
+ function Separator({
10
+ className,
11
+ orientation = "horizontal",
12
+ decorative = true,
13
+ ...props
14
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
15
+ return (
16
+ <SeparatorPrimitive.Root
17
+ data-slot="separator"
18
+ decorative={decorative}
19
+ orientation={orientation}
20
+ className={cn(
21
+ "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
22
+ className
23
+ )}
24
+ {...props}
25
+ />
26
+ )
27
+ }
28
+
29
+ export { Separator }
@@ -0,0 +1,144 @@
1
+ // @ts-nocheck — vendored shadcn, regenerate via scripts/sync-shadcn.ts
2
+ "use client"
3
+
4
+ import * as React from "react"
5
+ import { XIcon } from "lucide-react"
6
+ import { Dialog as SheetPrimitive } from "radix-ui"
7
+
8
+ import { cn } from "../lib/cn"
9
+
10
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
11
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
12
+ }
13
+
14
+ function SheetTrigger({
15
+ ...props
16
+ }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
17
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
18
+ }
19
+
20
+ function SheetClose({
21
+ ...props
22
+ }: React.ComponentProps<typeof SheetPrimitive.Close>) {
23
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
24
+ }
25
+
26
+ function SheetPortal({
27
+ ...props
28
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
29
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
30
+ }
31
+
32
+ function SheetOverlay({
33
+ className,
34
+ ...props
35
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
36
+ return (
37
+ <SheetPrimitive.Overlay
38
+ data-slot="sheet-overlay"
39
+ className={cn(
40
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
41
+ className
42
+ )}
43
+ {...props}
44
+ />
45
+ )
46
+ }
47
+
48
+ function SheetContent({
49
+ className,
50
+ children,
51
+ side = "right",
52
+ showCloseButton = true,
53
+ ...props
54
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
55
+ side?: "top" | "right" | "bottom" | "left"
56
+ showCloseButton?: boolean
57
+ }) {
58
+ return (
59
+ <SheetPortal>
60
+ <SheetOverlay />
61
+ <SheetPrimitive.Content
62
+ data-slot="sheet-content"
63
+ className={cn(
64
+ "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
65
+ side === "right" &&
66
+ "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
67
+ side === "left" &&
68
+ "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
69
+ side === "top" &&
70
+ "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
71
+ side === "bottom" &&
72
+ "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
73
+ className
74
+ )}
75
+ {...props}
76
+ >
77
+ {children}
78
+ {showCloseButton && (
79
+ <SheetPrimitive.Close className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary">
80
+ <XIcon className="size-4" />
81
+ <span className="sr-only">Close</span>
82
+ </SheetPrimitive.Close>
83
+ )}
84
+ </SheetPrimitive.Content>
85
+ </SheetPortal>
86
+ )
87
+ }
88
+
89
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
90
+ return (
91
+ <div
92
+ data-slot="sheet-header"
93
+ className={cn("flex flex-col gap-1.5 p-4", className)}
94
+ {...props}
95
+ />
96
+ )
97
+ }
98
+
99
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
100
+ return (
101
+ <div
102
+ data-slot="sheet-footer"
103
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
104
+ {...props}
105
+ />
106
+ )
107
+ }
108
+
109
+ function SheetTitle({
110
+ className,
111
+ ...props
112
+ }: React.ComponentProps<typeof SheetPrimitive.Title>) {
113
+ return (
114
+ <SheetPrimitive.Title
115
+ data-slot="sheet-title"
116
+ className={cn("font-semibold text-foreground", className)}
117
+ {...props}
118
+ />
119
+ )
120
+ }
121
+
122
+ function SheetDescription({
123
+ className,
124
+ ...props
125
+ }: React.ComponentProps<typeof SheetPrimitive.Description>) {
126
+ return (
127
+ <SheetPrimitive.Description
128
+ data-slot="sheet-description"
129
+ className={cn("text-sm text-muted-foreground", className)}
130
+ {...props}
131
+ />
132
+ )
133
+ }
134
+
135
+ export {
136
+ Sheet,
137
+ SheetTrigger,
138
+ SheetClose,
139
+ SheetContent,
140
+ SheetHeader,
141
+ SheetFooter,
142
+ SheetTitle,
143
+ SheetDescription,
144
+ }