@multicomma/arkcn 0.1.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 (237) hide show
  1. package/README.md +78 -0
  2. package/bin/arkcn.mjs +78 -0
  3. package/cli/commands.mjs +251 -0
  4. package/cli/project.mjs +168 -0
  5. package/cli/registry.mjs +50 -0
  6. package/cli/ui.mjs +46 -0
  7. package/mcp/server.mjs +149 -0
  8. package/package.json +201 -0
  9. package/registry/base.css +680 -0
  10. package/registry/index.json +1833 -0
  11. package/registry/items/accordion.json +18 -0
  12. package/registry/items/activity-feed.json +18 -0
  13. package/registry/items/alert-dialog.json +18 -0
  14. package/registry/items/alert.json +17 -0
  15. package/registry/items/angle-slider.json +17 -0
  16. package/registry/items/app-shell.json +28 -0
  17. package/registry/items/aspect-ratio.json +13 -0
  18. package/registry/items/attachment.json +19 -0
  19. package/registry/items/avatar.json +17 -0
  20. package/registry/items/badge.json +18 -0
  21. package/registry/items/breadcrumb.json +18 -0
  22. package/registry/items/bubble.json +18 -0
  23. package/registry/items/button-group.json +19 -0
  24. package/registry/items/button.json +18 -0
  25. package/registry/items/calendar.json +19 -0
  26. package/registry/items/canvas.json +24 -0
  27. package/registry/items/card.json +15 -0
  28. package/registry/items/carousel.json +19 -0
  29. package/registry/items/cascader.json +23 -0
  30. package/registry/items/chart.json +17 -0
  31. package/registry/items/chat.json +23 -0
  32. package/registry/items/checkbox.json +18 -0
  33. package/registry/items/clipboard.json +19 -0
  34. package/registry/items/collapsible.json +15 -0
  35. package/registry/items/color-picker.json +19 -0
  36. package/registry/items/combobox.json +20 -0
  37. package/registry/items/command.json +21 -0
  38. package/registry/items/comment-thread.json +25 -0
  39. package/registry/items/context-menu.json +18 -0
  40. package/registry/items/controllable.json +14 -0
  41. package/registry/items/data-grid.json +24 -0
  42. package/registry/items/data-table-adapter.json +14 -0
  43. package/registry/items/data-table.json +32 -0
  44. package/registry/items/date-input.json +17 -0
  45. package/registry/items/dialog.json +19 -0
  46. package/registry/items/direction.json +13 -0
  47. package/registry/items/drag-preview.json +16 -0
  48. package/registry/items/drawer.json +18 -0
  49. package/registry/items/dropdown-menu.json +18 -0
  50. package/registry/items/editable.json +17 -0
  51. package/registry/items/empty.json +17 -0
  52. package/registry/items/field.json +19 -0
  53. package/registry/items/file-upload.json +19 -0
  54. package/registry/items/floating-panel.json +19 -0
  55. package/registry/items/floating-toolbar.json +16 -0
  56. package/registry/items/form.json +14 -0
  57. package/registry/items/format.json +15 -0
  58. package/registry/items/gantt.json +22 -0
  59. package/registry/items/history.json +14 -0
  60. package/registry/items/hotkeys.json +18 -0
  61. package/registry/items/hover-card.json +17 -0
  62. package/registry/items/image-cropper.json +17 -0
  63. package/registry/items/input-group.json +20 -0
  64. package/registry/items/input-otp.json +18 -0
  65. package/registry/items/input.json +15 -0
  66. package/registry/items/item.json +19 -0
  67. package/registry/items/json-tree-view.json +17 -0
  68. package/registry/items/kanban.json +26 -0
  69. package/registry/items/kbd.json +15 -0
  70. package/registry/items/label.json +15 -0
  71. package/registry/items/live-region.json +16 -0
  72. package/registry/items/marker.json +18 -0
  73. package/registry/items/marquee.json +17 -0
  74. package/registry/items/menubar.json +19 -0
  75. package/registry/items/message.json +15 -0
  76. package/registry/items/navigation-menu.json +19 -0
  77. package/registry/items/node-graph.json +22 -0
  78. package/registry/items/number-input.json +18 -0
  79. package/registry/items/pagination.json +18 -0
  80. package/registry/items/password-input.json +18 -0
  81. package/registry/items/popconfirm.json +20 -0
  82. package/registry/items/popover.json +18 -0
  83. package/registry/items/progress.json +17 -0
  84. package/registry/items/qr-code.json +17 -0
  85. package/registry/items/query-builder.json +23 -0
  86. package/registry/items/radio-group.json +17 -0
  87. package/registry/items/rating-group.json +18 -0
  88. package/registry/items/resizable.json +17 -0
  89. package/registry/items/rich-text-editor.json +37 -0
  90. package/registry/items/row-layout.json +15 -0
  91. package/registry/items/scheduler.json +23 -0
  92. package/registry/items/scroll-area.json +17 -0
  93. package/registry/items/segment-group.json +17 -0
  94. package/registry/items/select.json +19 -0
  95. package/registry/items/separator.json +15 -0
  96. package/registry/items/sheet.json +19 -0
  97. package/registry/items/sidebar.json +27 -0
  98. package/registry/items/signature-pad.json +19 -0
  99. package/registry/items/skeleton.json +15 -0
  100. package/registry/items/slider.json +17 -0
  101. package/registry/items/sonner.json +17 -0
  102. package/registry/items/spinner.json +17 -0
  103. package/registry/items/steps.json +19 -0
  104. package/registry/items/swap.json +17 -0
  105. package/registry/items/switch.json +17 -0
  106. package/registry/items/table.json +16 -0
  107. package/registry/items/tabs.json +18 -0
  108. package/registry/items/tags-input.json +18 -0
  109. package/registry/items/textarea.json +15 -0
  110. package/registry/items/time.json +14 -0
  111. package/registry/items/timer.json +18 -0
  112. package/registry/items/toc.json +17 -0
  113. package/registry/items/toggle-group.json +19 -0
  114. package/registry/items/toggle.json +18 -0
  115. package/registry/items/tooltip.json +17 -0
  116. package/registry/items/tour.json +19 -0
  117. package/registry/items/transfer-list.json +24 -0
  118. package/registry/items/tree-select.json +24 -0
  119. package/registry/items/tree-view.json +18 -0
  120. package/registry/items/use-mobile.json +13 -0
  121. package/registry/items/utils.json +17 -0
  122. package/registry/items/virtual-list.json +16 -0
  123. package/src/components/ui/accordion.tsx +111 -0
  124. package/src/components/ui/activity-feed.tsx +228 -0
  125. package/src/components/ui/alert-dialog.tsx +204 -0
  126. package/src/components/ui/alert.tsx +55 -0
  127. package/src/components/ui/angle-slider.tsx +117 -0
  128. package/src/components/ui/app-shell.tsx +985 -0
  129. package/src/components/ui/aspect-ratio.tsx +35 -0
  130. package/src/components/ui/attachment.tsx +193 -0
  131. package/src/components/ui/avatar.tsx +94 -0
  132. package/src/components/ui/badge.tsx +45 -0
  133. package/src/components/ui/breadcrumb.tsx +93 -0
  134. package/src/components/ui/bubble.tsx +119 -0
  135. package/src/components/ui/button-group.tsx +79 -0
  136. package/src/components/ui/button.tsx +65 -0
  137. package/src/components/ui/calendar.tsx +172 -0
  138. package/src/components/ui/canvas.tsx +723 -0
  139. package/src/components/ui/card.tsx +69 -0
  140. package/src/components/ui/carousel.tsx +228 -0
  141. package/src/components/ui/cascader.tsx +754 -0
  142. package/src/components/ui/chart.tsx +303 -0
  143. package/src/components/ui/chat.tsx +544 -0
  144. package/src/components/ui/checkbox.tsx +94 -0
  145. package/src/components/ui/clipboard.tsx +94 -0
  146. package/src/components/ui/collapsible.tsx +32 -0
  147. package/src/components/ui/color-picker.tsx +441 -0
  148. package/src/components/ui/combobox.tsx +400 -0
  149. package/src/components/ui/command.tsx +292 -0
  150. package/src/components/ui/comment-thread.tsx +923 -0
  151. package/src/components/ui/context-menu.tsx +331 -0
  152. package/src/components/ui/data-grid.tsx +1227 -0
  153. package/src/components/ui/data-table.tsx +993 -0
  154. package/src/components/ui/date-input.tsx +103 -0
  155. package/src/components/ui/dialog.tsx +159 -0
  156. package/src/components/ui/direction.tsx +32 -0
  157. package/src/components/ui/drawer.tsx +200 -0
  158. package/src/components/ui/dropdown-menu.tsx +329 -0
  159. package/src/components/ui/editable.tsx +90 -0
  160. package/src/components/ui/empty.tsx +86 -0
  161. package/src/components/ui/field.tsx +218 -0
  162. package/src/components/ui/file-upload.tsx +204 -0
  163. package/src/components/ui/floating-panel.tsx +199 -0
  164. package/src/components/ui/floating-toolbar.tsx +79 -0
  165. package/src/components/ui/format.tsx +22 -0
  166. package/src/components/ui/gantt.tsx +950 -0
  167. package/src/components/ui/hotkeys.tsx +340 -0
  168. package/src/components/ui/hover-card.tsx +83 -0
  169. package/src/components/ui/image-cropper.tsx +100 -0
  170. package/src/components/ui/input-group.tsx +133 -0
  171. package/src/components/ui/input-otp.tsx +82 -0
  172. package/src/components/ui/input.tsx +18 -0
  173. package/src/components/ui/item.tsx +174 -0
  174. package/src/components/ui/json-tree-view.tsx +37 -0
  175. package/src/components/ui/kanban.tsx +884 -0
  176. package/src/components/ui/kbd.tsx +20 -0
  177. package/src/components/ui/label.tsx +30 -0
  178. package/src/components/ui/live-region.tsx +54 -0
  179. package/src/components/ui/marker.tsx +66 -0
  180. package/src/components/ui/marquee.tsx +61 -0
  181. package/src/components/ui/menubar.tsx +456 -0
  182. package/src/components/ui/message.tsx +74 -0
  183. package/src/components/ui/navigation-menu.tsx +202 -0
  184. package/src/components/ui/node-graph.tsx +1723 -0
  185. package/src/components/ui/number-input.tsx +148 -0
  186. package/src/components/ui/pagination.tsx +88 -0
  187. package/src/components/ui/password-input.tsx +104 -0
  188. package/src/components/ui/popconfirm.tsx +149 -0
  189. package/src/components/ui/popover.tsx +126 -0
  190. package/src/components/ui/progress.tsx +114 -0
  191. package/src/components/ui/qr-code.tsx +51 -0
  192. package/src/components/ui/query-builder.tsx +938 -0
  193. package/src/components/ui/radio-group.tsx +108 -0
  194. package/src/components/ui/rating-group.tsx +91 -0
  195. package/src/components/ui/resizable.tsx +41 -0
  196. package/src/components/ui/rich-text-editor.tsx +845 -0
  197. package/src/components/ui/scheduler.tsx +1164 -0
  198. package/src/components/ui/scroll-area.tsx +82 -0
  199. package/src/components/ui/segment-group.tsx +95 -0
  200. package/src/components/ui/select.tsx +354 -0
  201. package/src/components/ui/separator.tsx +32 -0
  202. package/src/components/ui/sheet.tsx +130 -0
  203. package/src/components/ui/sidebar.tsx +665 -0
  204. package/src/components/ui/signature-pad.tsx +112 -0
  205. package/src/components/ui/skeleton.tsx +7 -0
  206. package/src/components/ui/slider.tsx +183 -0
  207. package/src/components/ui/sonner.tsx +37 -0
  208. package/src/components/ui/spinner.tsx +16 -0
  209. package/src/components/ui/steps.tsx +152 -0
  210. package/src/components/ui/swap.tsx +33 -0
  211. package/src/components/ui/switch.tsx +83 -0
  212. package/src/components/ui/table.tsx +72 -0
  213. package/src/components/ui/tabs.tsx +100 -0
  214. package/src/components/ui/tags-input.tsx +153 -0
  215. package/src/components/ui/textarea.tsx +17 -0
  216. package/src/components/ui/timer.tsx +67 -0
  217. package/src/components/ui/toc.tsx +64 -0
  218. package/src/components/ui/toggle-group.tsx +89 -0
  219. package/src/components/ui/toggle.tsx +46 -0
  220. package/src/components/ui/tooltip.tsx +113 -0
  221. package/src/components/ui/tour.tsx +168 -0
  222. package/src/components/ui/transfer-list.tsx +700 -0
  223. package/src/components/ui/tree-select.tsx +638 -0
  224. package/src/components/ui/tree-view.tsx +217 -0
  225. package/src/components/ui/virtual-list.tsx +343 -0
  226. package/src/hooks/use-mobile.ts +19 -0
  227. package/src/lib/controllable.ts +31 -0
  228. package/src/lib/data-table-adapter.ts +67 -0
  229. package/src/lib/drag-preview.ts +39 -0
  230. package/src/lib/form.ts +39 -0
  231. package/src/lib/history.ts +55 -0
  232. package/src/lib/row-layout.ts +81 -0
  233. package/src/lib/table.ts +483 -0
  234. package/src/lib/time.ts +37 -0
  235. package/src/lib/utils.ts +6 -0
  236. package/src/styles/arkcn.css +764 -0
  237. package/src/styles/index.css +3 -0
@@ -0,0 +1,82 @@
1
+ import * as React from "react"
2
+ import { cn } from "@/lib/utils"
3
+ import { ScrollArea as ScrollAreaPrimitive } from "@ark-ui/react"
4
+
5
+ function ScrollArea({ className, children, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
6
+ return (
7
+ <ScrollAreaPrimitive.Root data-slot="scroll-area" className={cn("relative", className)} {...props}>
8
+ <ScrollAreaViewport>
9
+ <ScrollAreaContent>{children}</ScrollAreaContent>
10
+ </ScrollAreaViewport>
11
+ <ScrollBar />
12
+ <ScrollAreaCorner />
13
+ </ScrollAreaPrimitive.Root>
14
+ )
15
+ }
16
+
17
+ function ScrollAreaContext({ ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Context>) {
18
+ return <ScrollAreaPrimitive.Context {...props} />
19
+ }
20
+
21
+ function ScrollAreaViewport({ className, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Viewport>) {
22
+ return (
23
+ <ScrollAreaPrimitive.Viewport
24
+ data-slot="scroll-area-viewport"
25
+ className={cn(
26
+ "no-scrollbar size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1",
27
+ className
28
+ )}
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function ScrollAreaContent({ className, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Content>) {
35
+ return (
36
+ <ScrollAreaPrimitive.Content data-slot="scroll-area-content" className={cn("min-w-full", className)} {...props} />
37
+ )
38
+ }
39
+
40
+ function ScrollBar({
41
+ className,
42
+ orientation = "vertical",
43
+ ...props
44
+ }: React.ComponentProps<typeof ScrollAreaPrimitive.Scrollbar>) {
45
+ return (
46
+ <ScrollAreaPrimitive.Scrollbar
47
+ data-slot="scroll-area-scrollbar"
48
+ orientation={orientation}
49
+ className={cn(
50
+ "flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-horizontal:not-data-overflow-x:hidden data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent data-vertical:not-data-overflow-y:hidden",
51
+ className
52
+ )}
53
+ {...props}
54
+ >
55
+ <ScrollAreaThumb />
56
+ </ScrollAreaPrimitive.Scrollbar>
57
+ )
58
+ }
59
+
60
+ function ScrollAreaThumb({ className, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Thumb>) {
61
+ return (
62
+ <ScrollAreaPrimitive.Thumb
63
+ data-slot="scroll-area-thumb"
64
+ className={cn("relative flex-1 rounded-full bg-border", className)}
65
+ {...props}
66
+ />
67
+ )
68
+ }
69
+
70
+ function ScrollAreaCorner({ ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Corner>) {
71
+ return <ScrollAreaPrimitive.Corner data-slot="scroll-area-corner" {...props} />
72
+ }
73
+
74
+ export {
75
+ ScrollArea,
76
+ ScrollAreaContent,
77
+ ScrollAreaContext,
78
+ ScrollAreaCorner,
79
+ ScrollAreaThumb,
80
+ ScrollAreaViewport,
81
+ ScrollBar,
82
+ }
@@ -0,0 +1,95 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+ import { SegmentGroup as SegmentGroupPrimitive } from "@ark-ui/react"
6
+
7
+ function SegmentGroup({
8
+ className,
9
+ orientation = "horizontal",
10
+ ...props
11
+ }: React.ComponentProps<typeof SegmentGroupPrimitive.Root>) {
12
+ return (
13
+ <SegmentGroupPrimitive.Root
14
+ data-slot="segment-group"
15
+ orientation={orientation}
16
+ className={cn(
17
+ "relative inline-flex h-8 w-fit items-center gap-0.5 rounded-lg bg-muted p-0.75 text-muted-foreground data-vertical:h-auto data-vertical:flex-col data-vertical:items-stretch",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ function SegmentGroupContext({ ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.Context>) {
26
+ return <SegmentGroupPrimitive.Context {...props} />
27
+ }
28
+
29
+ function SegmentGroupLabel({ className, ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.Label>) {
30
+ return (
31
+ <SegmentGroupPrimitive.Label
32
+ data-slot="segment-group-label"
33
+ className={cn("text-sm font-medium select-none", className)}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ function SegmentGroupIndicator({ className, ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.Indicator>) {
40
+ return (
41
+ <SegmentGroupPrimitive.Indicator
42
+ data-slot="segment-group-indicator"
43
+ className={cn(
44
+ "top-(--top) left-(--left) z-0 h-(--height) w-(--width) rounded-md bg-background shadow-sm transition-[left,top,width,height] duration-200 dark:border dark:border-input dark:bg-input/30",
45
+ className
46
+ )}
47
+ {...props}
48
+ />
49
+ )
50
+ }
51
+
52
+ function SegmentGroupItem({ className, children, ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.Item>) {
53
+ return (
54
+ <SegmentGroupPrimitive.Item
55
+ data-slot="segment-group-item"
56
+ className={cn(
57
+ "relative z-10 inline-flex h-full cursor-pointer items-center justify-center gap-1.5 rounded-md px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-colors select-none hover:text-foreground data-focus-visible:ring-3 data-focus-visible:ring-ring/50 data-checked:text-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4",
58
+ className
59
+ )}
60
+ {...props}
61
+ >
62
+ <SegmentGroupItemText>{children}</SegmentGroupItemText>
63
+ <SegmentGroupItemControl />
64
+ <SegmentGroupItemHiddenInput />
65
+ </SegmentGroupPrimitive.Item>
66
+ )
67
+ }
68
+
69
+ function SegmentGroupItemContext({ ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.ItemContext>) {
70
+ return <SegmentGroupPrimitive.ItemContext {...props} />
71
+ }
72
+
73
+ function SegmentGroupItemText({ ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.ItemText>) {
74
+ return <SegmentGroupPrimitive.ItemText data-slot="segment-group-item-text" {...props} />
75
+ }
76
+
77
+ function SegmentGroupItemControl({ ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.ItemControl>) {
78
+ return <SegmentGroupPrimitive.ItemControl data-slot="segment-group-item-control" {...props} />
79
+ }
80
+
81
+ function SegmentGroupItemHiddenInput({ ...props }: React.ComponentProps<typeof SegmentGroupPrimitive.ItemHiddenInput>) {
82
+ return <SegmentGroupPrimitive.ItemHiddenInput {...props} />
83
+ }
84
+
85
+ export {
86
+ SegmentGroup,
87
+ SegmentGroupContext,
88
+ SegmentGroupIndicator,
89
+ SegmentGroupItem,
90
+ SegmentGroupItemContext,
91
+ SegmentGroupItemControl,
92
+ SegmentGroupItemHiddenInput,
93
+ SegmentGroupItemText,
94
+ SegmentGroupLabel,
95
+ }
@@ -0,0 +1,354 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+ import {
6
+ Select as SelectPrimitive,
7
+ Portal as PortalPrimitive,
8
+ createListCollection,
9
+ type CollectionItem,
10
+ type ListCollection,
11
+ } from "@ark-ui/react"
12
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
13
+
14
+ function Select<T extends CollectionItem>({
15
+ positioning,
16
+ lazyMount = true,
17
+ unmountOnExit = true,
18
+ ...props
19
+ }: React.ComponentProps<typeof SelectPrimitive.Root<T>>) {
20
+ return (
21
+ <SelectPrimitive.Root
22
+ data-slot="select"
23
+ positioning={{
24
+ placement: "bottom",
25
+ gutter: 4,
26
+ sameWidth: true,
27
+ ...positioning,
28
+ }}
29
+ lazyMount={lazyMount}
30
+ unmountOnExit={unmountOnExit}
31
+ {...props}
32
+ />
33
+ )
34
+ }
35
+
36
+ function SelectContext({ ...props }: React.ComponentProps<typeof SelectPrimitive.Context>) {
37
+ return <SelectPrimitive.Context {...props} />
38
+ }
39
+
40
+ function SelectHiddenSelect({ ...props }: React.ComponentProps<typeof SelectPrimitive.HiddenSelect>) {
41
+ return <SelectPrimitive.HiddenSelect {...props} />
42
+ }
43
+
44
+ function SelectRootLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {
45
+ return (
46
+ <SelectPrimitive.Label data-slot="select-root-label" className={cn("text-sm font-medium", className)} {...props} />
47
+ )
48
+ }
49
+
50
+ function SelectControl({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Control>) {
51
+ return (
52
+ <SelectPrimitive.Control
53
+ data-slot="select-control"
54
+ className={cn("flex items-center gap-1", className)}
55
+ {...props}
56
+ />
57
+ )
58
+ }
59
+
60
+ function SelectGroup({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ItemGroup>) {
61
+ return <SelectPrimitive.ItemGroup data-slot="select-group" className={cn("scroll-my-1 p-1", className)} {...props} />
62
+ }
63
+
64
+ function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.ValueText>) {
65
+ return <SelectPrimitive.ValueText data-slot="select-value" {...props} />
66
+ }
67
+
68
+ function SelectIndicator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Indicator>) {
69
+ return (
70
+ <SelectPrimitive.Indicator
71
+ data-slot="select-indicator"
72
+ className={cn("pointer-events-none text-muted-foreground", className)}
73
+ {...props}
74
+ />
75
+ )
76
+ }
77
+
78
+ function SelectClearTrigger({ ...props }: React.ComponentProps<typeof SelectPrimitive.ClearTrigger>) {
79
+ return <SelectPrimitive.ClearTrigger data-slot="select-clear-trigger" {...props} />
80
+ }
81
+
82
+ /** `id` is omitted: set part ids through the root `ids` prop so Ark's internal lookups keep working. */
83
+ /**
84
+ * `variant="unstyled"` keeps only the layout (flex, gap, icon sizing) so a host
85
+ * can supply its own chrome, e.g. an editable grid cell that already draws the
86
+ * focus ring.
87
+ */
88
+ function SelectTrigger({
89
+ className,
90
+ size = "default",
91
+ variant = "default",
92
+ children,
93
+ ...props
94
+ }: Omit<React.ComponentProps<typeof SelectPrimitive.Trigger>, "id"> & {
95
+ size?: "sm" | "default"
96
+ variant?: "default" | "unstyled"
97
+ }) {
98
+ return (
99
+ <SelectPrimitive.Trigger
100
+ data-slot="select-trigger"
101
+ data-size={size}
102
+ data-variant={variant}
103
+ className={cn(
104
+ "flex items-center justify-between gap-1.5 text-sm whitespace-nowrap outline-none select-none disabled:cursor-not-allowed disabled:opacity-50 data-placeholder-shown:text-muted-foreground *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
105
+ variant === "default" &&
106
+ "w-fit rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 transition-colors focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 data-invalid:border-destructive data-invalid:ring-3 data-invalid:ring-destructive/20 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] dark:bg-input/30 dark:hover:bg-input/50 dark:data-invalid:border-destructive/50 dark:data-invalid:ring-destructive/40",
107
+ className
108
+ )}
109
+ {...props}
110
+ >
111
+ {children}
112
+ <SelectIndicator asChild>
113
+ <ChevronDownIcon className="size-4" />
114
+ </SelectIndicator>
115
+ </SelectPrimitive.Trigger>
116
+ )
117
+ }
118
+
119
+ function SelectPositioner({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Positioner>) {
120
+ return (
121
+ <SelectPrimitive.Positioner data-slot="select-positioner" className={cn("[--z-index:50]", className)} {...props} />
122
+ )
123
+ }
124
+
125
+ /** `id` is omitted: set part ids through the root `ids` prop so Ark's internal lookups keep working. */
126
+ function SelectContent({
127
+ className,
128
+ children,
129
+ ...props
130
+ }: Omit<React.ComponentProps<typeof SelectPrimitive.Content>, "id">) {
131
+ return (
132
+ <PortalPrimitive>
133
+ <SelectPositioner>
134
+ <SelectPrimitive.Content
135
+ data-slot="select-content"
136
+ className={cn(
137
+ "relative z-50 max-h-(--available-height) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden 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",
138
+ className
139
+ )}
140
+ {...props}
141
+ >
142
+ <SelectScrollUpButton />
143
+ {children}
144
+ <SelectScrollDownButton />
145
+ </SelectPrimitive.Content>
146
+ </SelectPositioner>
147
+ </PortalPrimitive>
148
+ )
149
+ }
150
+
151
+ function SelectList({ ...props }: React.ComponentProps<typeof SelectPrimitive.List>) {
152
+ return <SelectPrimitive.List data-slot="select-list" {...props} />
153
+ }
154
+
155
+ function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ItemGroupLabel>) {
156
+ return (
157
+ <SelectPrimitive.ItemGroupLabel
158
+ data-slot="select-label"
159
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
160
+ {...props}
161
+ />
162
+ )
163
+ }
164
+
165
+ function SelectItem({
166
+ className,
167
+ children,
168
+ item,
169
+ value,
170
+ ...props
171
+ }: Omit<React.ComponentProps<typeof SelectPrimitive.Item>, "item"> & {
172
+ /** The collection item. Falls back to `value` for string collections. */
173
+ item?: CollectionItem
174
+ value?: string
175
+ }) {
176
+ return (
177
+ <SelectPrimitive.Item
178
+ data-slot="select-item"
179
+ item={item ?? value}
180
+ className={cn(
181
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**: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 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
182
+ className
183
+ )}
184
+ {...props}
185
+ >
186
+ <SelectItemIndicator>
187
+ <CheckIcon className="pointer-events-none" />
188
+ </SelectItemIndicator>
189
+ <SelectPrimitive.ItemText data-slot="select-item-text">{children}</SelectPrimitive.ItemText>
190
+ </SelectPrimitive.Item>
191
+ )
192
+ }
193
+
194
+ function SelectItemText({ ...props }: React.ComponentProps<typeof SelectPrimitive.ItemText>) {
195
+ return <SelectPrimitive.ItemText data-slot="select-item-text" {...props} />
196
+ }
197
+
198
+ function SelectItemIndicator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ItemIndicator>) {
199
+ return (
200
+ <SelectPrimitive.ItemIndicator
201
+ data-slot="select-item-indicator"
202
+ className={cn("pointer-events-none absolute right-2 flex size-4 items-center justify-center", className)}
203
+ {...props}
204
+ />
205
+ )
206
+ }
207
+
208
+ function SelectSeparator({ className, ...props }: React.ComponentProps<"div">) {
209
+ return (
210
+ <div
211
+ role="separator"
212
+ aria-orientation="horizontal"
213
+ data-slot="select-separator"
214
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
215
+ {...props}
216
+ />
217
+ )
218
+ }
219
+
220
+ /**
221
+ * Ark's Select content is its own scroll container and has no scroll buttons.
222
+ * These reproduce Radix's: shown only when the content can scroll in that
223
+ * direction, and they scroll while hovered.
224
+ */
225
+ function useSelectScrollButton(direction: "up" | "down") {
226
+ const ref = React.useRef<HTMLDivElement>(null)
227
+ const [visible, setVisible] = React.useState(false)
228
+ const timer = React.useRef<number | null>(null)
229
+
230
+ const getContent = React.useCallback(
231
+ () => ref.current?.closest<HTMLElement>('[data-slot="select-content"]') ?? null,
232
+ []
233
+ )
234
+
235
+ React.useEffect(() => {
236
+ const content = getContent()
237
+ if (!content) return
238
+ const update = () => {
239
+ const canUp = content.scrollTop > 0
240
+ const canDown = content.scrollTop + content.clientHeight < content.scrollHeight - 1
241
+ setVisible(direction === "up" ? canUp : canDown)
242
+ }
243
+ update()
244
+ content.addEventListener("scroll", update)
245
+ const observer = new ResizeObserver(update)
246
+ observer.observe(content)
247
+ return () => {
248
+ content.removeEventListener("scroll", update)
249
+ observer.disconnect()
250
+ }
251
+ }, [direction, getContent])
252
+
253
+ const stop = React.useCallback(() => {
254
+ if (timer.current !== null) window.clearInterval(timer.current)
255
+ timer.current = null
256
+ }, [])
257
+
258
+ const start = React.useCallback(() => {
259
+ stop()
260
+ timer.current = window.setInterval(() => {
261
+ getContent()?.scrollBy({ top: direction === "up" ? -8 : 8 })
262
+ }, 40)
263
+ }, [direction, getContent, stop])
264
+
265
+ React.useEffect(() => stop, [stop])
266
+
267
+ return { ref, visible, start, stop }
268
+ }
269
+
270
+ function SelectScrollUpButton({ className, onPointerEnter, onPointerLeave, ...props }: React.ComponentProps<"div">) {
271
+ const { ref, visible, start, stop } = useSelectScrollButton("up")
272
+ return (
273
+ <div
274
+ ref={ref}
275
+ aria-hidden
276
+ hidden={!visible}
277
+ data-slot="select-scroll-up-button"
278
+ className={cn(
279
+ "sticky top-0 z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
280
+ className
281
+ )}
282
+ onPointerEnter={(event) => {
283
+ onPointerEnter?.(event)
284
+ start()
285
+ }}
286
+ onPointerLeave={(event) => {
287
+ onPointerLeave?.(event)
288
+ stop()
289
+ }}
290
+ {...props}
291
+ >
292
+ <ChevronUpIcon />
293
+ </div>
294
+ )
295
+ }
296
+
297
+ function SelectScrollDownButton({ className, onPointerEnter, onPointerLeave, ...props }: React.ComponentProps<"div">) {
298
+ const { ref, visible, start, stop } = useSelectScrollButton("down")
299
+ return (
300
+ <div
301
+ ref={ref}
302
+ aria-hidden
303
+ hidden={!visible}
304
+ data-slot="select-scroll-down-button"
305
+ className={cn(
306
+ "sticky bottom-0 z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
307
+ className
308
+ )}
309
+ onPointerEnter={(event) => {
310
+ onPointerEnter?.(event)
311
+ start()
312
+ }}
313
+ onPointerLeave={(event) => {
314
+ onPointerLeave?.(event)
315
+ stop()
316
+ }}
317
+ {...props}
318
+ >
319
+ <ChevronDownIcon />
320
+ </div>
321
+ )
322
+ }
323
+
324
+ /** Render-prop access to one item's state (`{ selected, highlighted, disabled, ... }`). */
325
+ function SelectItemContext({ ...props }: React.ComponentProps<typeof SelectPrimitive.ItemContext>) {
326
+ return <SelectPrimitive.ItemContext {...props} />
327
+ }
328
+
329
+ export {
330
+ Select,
331
+ SelectClearTrigger,
332
+ SelectContent,
333
+ SelectContext,
334
+ SelectControl,
335
+ SelectGroup,
336
+ SelectHiddenSelect,
337
+ SelectIndicator,
338
+ SelectItem,
339
+ SelectItemIndicator,
340
+ SelectItemText,
341
+ SelectLabel,
342
+ SelectList,
343
+ SelectPositioner,
344
+ SelectRootLabel,
345
+ SelectScrollDownButton,
346
+ SelectScrollUpButton,
347
+ SelectSeparator,
348
+ SelectTrigger,
349
+ SelectValue,
350
+ createListCollection,
351
+ type CollectionItem,
352
+ type ListCollection,
353
+ SelectItemContext,
354
+ }
@@ -0,0 +1,32 @@
1
+ import * as React from "react"
2
+ import { cn } from "@/lib/utils"
3
+
4
+ /**
5
+ * Ark UI has no Separator primitive. This mirrors Radix's: a `div` with
6
+ * `role="separator"` (or `role="none"` when decorative) and `data-orientation`.
7
+ */
8
+ function Separator({
9
+ className,
10
+ orientation = "horizontal",
11
+ decorative = true,
12
+ ...props
13
+ }: React.ComponentProps<"div"> & {
14
+ orientation?: "horizontal" | "vertical"
15
+ decorative?: boolean
16
+ }) {
17
+ return (
18
+ <div
19
+ data-slot="separator"
20
+ data-orientation={orientation}
21
+ role={decorative ? "none" : "separator"}
22
+ aria-orientation={!decorative && orientation === "vertical" ? "vertical" : undefined}
23
+ className={cn(
24
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
25
+ className
26
+ )}
27
+ {...props}
28
+ />
29
+ )
30
+ }
31
+
32
+ export { Separator }
@@ -0,0 +1,130 @@
1
+ import * as React from "react"
2
+ import { cn } from "@/lib/utils"
3
+ import { Dialog as SheetPrimitive, Portal as PortalPrimitive } from "@ark-ui/react"
4
+
5
+ import { Button } from "@/components/ui/button"
6
+ import { XIcon } from "lucide-react"
7
+
8
+ function Sheet({ lazyMount = true, unmountOnExit = true, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
9
+ return <SheetPrimitive.Root lazyMount={lazyMount} unmountOnExit={unmountOnExit} {...props} />
10
+ }
11
+
12
+ function SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
13
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
14
+ }
15
+
16
+ function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.CloseTrigger>) {
17
+ return <SheetPrimitive.CloseTrigger data-slot="sheet-close" {...props} />
18
+ }
19
+
20
+ function SheetPortal({ ...props }: React.ComponentProps<typeof PortalPrimitive>) {
21
+ return <PortalPrimitive {...props} />
22
+ }
23
+
24
+ function SheetContext({ ...props }: React.ComponentProps<typeof SheetPrimitive.Context>) {
25
+ return <SheetPrimitive.Context {...props} />
26
+ }
27
+
28
+ function SheetOverlay({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Backdrop>) {
29
+ return (
30
+ <SheetPrimitive.Backdrop
31
+ data-slot="sheet-overlay"
32
+ className={cn(
33
+ "fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
34
+ className
35
+ )}
36
+ {...props}
37
+ />
38
+ )
39
+ }
40
+
41
+ function SheetPositioner({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Positioner>) {
42
+ return (
43
+ <SheetPrimitive.Positioner
44
+ data-slot="sheet-positioner"
45
+ className={cn("fixed inset-0 z-50", className)}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ function SheetContent({
52
+ className,
53
+ children,
54
+ side = "right",
55
+ showCloseButton = true,
56
+ ...props
57
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
58
+ side?: "top" | "right" | "bottom" | "left"
59
+ showCloseButton?: boolean
60
+ }) {
61
+ return (
62
+ <SheetPortal>
63
+ <SheetOverlay />
64
+ <SheetPositioner data-side={side}>
65
+ <SheetPrimitive.Content
66
+ data-slot="sheet-content"
67
+ data-side={side}
68
+ className={cn(
69
+ "absolute flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
70
+ className
71
+ )}
72
+ {...props}
73
+ >
74
+ {children}
75
+ {showCloseButton && (
76
+ <SheetPrimitive.CloseTrigger data-slot="sheet-close" asChild>
77
+ <Button variant="ghost" className="absolute top-3 right-3" size="icon-sm">
78
+ <XIcon />
79
+ <span className="sr-only">Close</span>
80
+ </Button>
81
+ </SheetPrimitive.CloseTrigger>
82
+ )}
83
+ </SheetPrimitive.Content>
84
+ </SheetPositioner>
85
+ </SheetPortal>
86
+ )
87
+ }
88
+
89
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
90
+ return <div data-slot="sheet-header" className={cn("flex flex-col gap-0.5 p-4", className)} {...props} />
91
+ }
92
+
93
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
94
+ return <div data-slot="sheet-footer" className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
95
+ }
96
+
97
+ function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {
98
+ return (
99
+ <SheetPrimitive.Title
100
+ data-slot="sheet-title"
101
+ className={cn("font-heading text-base font-medium text-foreground", className)}
102
+ {...props}
103
+ />
104
+ )
105
+ }
106
+
107
+ function SheetDescription({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Description>) {
108
+ return (
109
+ <SheetPrimitive.Description
110
+ data-slot="sheet-description"
111
+ className={cn("text-sm text-muted-foreground", className)}
112
+ {...props}
113
+ />
114
+ )
115
+ }
116
+
117
+ export {
118
+ Sheet,
119
+ SheetTrigger,
120
+ SheetClose,
121
+ SheetContent,
122
+ SheetContext,
123
+ SheetHeader,
124
+ SheetFooter,
125
+ SheetOverlay,
126
+ SheetPortal,
127
+ SheetPositioner,
128
+ SheetTitle,
129
+ SheetDescription,
130
+ }