@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,103 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+ import { DateInput as DateInputPrimitive } from "@ark-ui/react"
6
+
7
+ function DateInput({ className, children, ...props }: React.ComponentProps<typeof DateInputPrimitive.Root>) {
8
+ return (
9
+ <DateInputPrimitive.Root
10
+ data-slot="date-input"
11
+ className={cn("flex w-full flex-col gap-1.5", className)}
12
+ {...props}
13
+ >
14
+ {children ?? (
15
+ <DateInputControl>
16
+ <DateInputSegmentGroup />
17
+ <DateInputHiddenInput />
18
+ </DateInputControl>
19
+ )}
20
+ </DateInputPrimitive.Root>
21
+ )
22
+ }
23
+
24
+ function DateInputContext({ ...props }: React.ComponentProps<typeof DateInputPrimitive.Context>) {
25
+ return <DateInputPrimitive.Context {...props} />
26
+ }
27
+
28
+ function DateInputLabel({ className, ...props }: React.ComponentProps<typeof DateInputPrimitive.Label>) {
29
+ return (
30
+ <DateInputPrimitive.Label
31
+ data-slot="date-input-label"
32
+ className={cn("text-sm font-medium select-none", className)}
33
+ {...props}
34
+ />
35
+ )
36
+ }
37
+
38
+ function DateInputControl({ className, ...props }: React.ComponentProps<typeof DateInputPrimitive.Control>) {
39
+ return (
40
+ <DateInputPrimitive.Control
41
+ data-slot="date-input-control"
42
+ className={cn(
43
+ "flex h-8 w-fit items-center rounded-lg border border-input bg-transparent px-2.5 text-sm transition-colors has-focus-visible:border-ring has-focus-visible:ring-3 has-focus-visible:ring-ring/50 data-invalid:border-destructive data-invalid:ring-3 data-invalid:ring-destructive/20 dark:bg-input/30 data-disabled:pointer-events-none data-disabled:opacity-50",
44
+ className
45
+ )}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ function DateInputSegmentGroup({
52
+ className,
53
+ children,
54
+ index = 0,
55
+ ...props
56
+ }: React.ComponentProps<typeof DateInputPrimitive.SegmentGroup>) {
57
+ return (
58
+ <DateInputPrimitive.SegmentGroup
59
+ data-slot="date-input-segment-group"
60
+ index={index}
61
+ className={cn("flex items-center", className)}
62
+ {...props}
63
+ >
64
+ {children ?? (
65
+ <DateInputPrimitive.Context>
66
+ {(api) => api.getSegments({ index }).map((segment, i) => <DateInputSegment key={i} segment={segment} />)}
67
+ </DateInputPrimitive.Context>
68
+ )}
69
+ </DateInputPrimitive.SegmentGroup>
70
+ )
71
+ }
72
+
73
+ function DateInputSegment({ className, ...props }: React.ComponentProps<typeof DateInputPrimitive.Segment>) {
74
+ return (
75
+ <DateInputPrimitive.Segment
76
+ data-slot="date-input-segment"
77
+ className={cn(
78
+ "rounded-sm px-0.5 tabular-nums outline-none data-editable:focus:bg-primary data-editable:focus:text-primary-foreground data-placeholder-shown:text-muted-foreground data-[type=literal]:text-muted-foreground",
79
+ className
80
+ )}
81
+ {...props}
82
+ />
83
+ )
84
+ }
85
+
86
+ function DateInputSegmentContext({ ...props }: React.ComponentProps<typeof DateInputPrimitive.SegmentContext>) {
87
+ return <DateInputPrimitive.SegmentContext {...props} />
88
+ }
89
+
90
+ function DateInputHiddenInput({ ...props }: React.ComponentProps<typeof DateInputPrimitive.HiddenInput>) {
91
+ return <DateInputPrimitive.HiddenInput {...props} />
92
+ }
93
+
94
+ export {
95
+ DateInput,
96
+ DateInputContext,
97
+ DateInputControl,
98
+ DateInputHiddenInput,
99
+ DateInputLabel,
100
+ DateInputSegment,
101
+ DateInputSegmentContext,
102
+ DateInputSegmentGroup,
103
+ }
@@ -0,0 +1,159 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "@/lib/utils"
5
+ import { Dialog as DialogPrimitive, Portal as PortalPrimitive } from "@ark-ui/react"
6
+
7
+ import { Button } from "@/components/ui/button"
8
+ import { XIcon } from "lucide-react"
9
+
10
+ function Dialog({
11
+ lazyMount = true,
12
+ unmountOnExit = true,
13
+ ...props
14
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) {
15
+ return <DialogPrimitive.Root lazyMount={lazyMount} unmountOnExit={unmountOnExit} {...props} />
16
+ }
17
+
18
+ function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
19
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
20
+ }
21
+
22
+ function DialogPortal({ ...props }: React.ComponentProps<typeof PortalPrimitive>) {
23
+ return <PortalPrimitive {...props} />
24
+ }
25
+
26
+ function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.CloseTrigger>) {
27
+ return <DialogPrimitive.CloseTrigger data-slot="dialog-close" {...props} />
28
+ }
29
+
30
+ function DialogContext({ ...props }: React.ComponentProps<typeof DialogPrimitive.Context>) {
31
+ return <DialogPrimitive.Context {...props} />
32
+ }
33
+
34
+ function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Backdrop>) {
35
+ return (
36
+ <DialogPrimitive.Backdrop
37
+ data-slot="dialog-overlay"
38
+ className={cn(
39
+ "fixed inset-0 isolate 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",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ )
45
+ }
46
+
47
+ function DialogPositioner({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Positioner>) {
48
+ return (
49
+ <DialogPrimitive.Positioner
50
+ data-slot="dialog-positioner"
51
+ className={cn("fixed inset-0 z-50 flex items-center justify-center", className)}
52
+ {...props}
53
+ />
54
+ )
55
+ }
56
+
57
+ function DialogContent({
58
+ className,
59
+ children,
60
+ showCloseButton = true,
61
+ ...props
62
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
63
+ showCloseButton?: boolean
64
+ }) {
65
+ return (
66
+ <DialogPortal>
67
+ <DialogOverlay />
68
+ <DialogPositioner>
69
+ <DialogPrimitive.Content
70
+ data-slot="dialog-content"
71
+ className={cn(
72
+ "relative grid w-full max-w-[calc(100%-2rem)] gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm 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",
73
+ className
74
+ )}
75
+ {...props}
76
+ >
77
+ {children}
78
+ {showCloseButton && (
79
+ <DialogPrimitive.CloseTrigger data-slot="dialog-close" asChild>
80
+ <Button variant="ghost" className="absolute top-2 right-2" size="icon-sm">
81
+ <XIcon />
82
+ <span className="sr-only">Close</span>
83
+ </Button>
84
+ </DialogPrimitive.CloseTrigger>
85
+ )}
86
+ </DialogPrimitive.Content>
87
+ </DialogPositioner>
88
+ </DialogPortal>
89
+ )
90
+ }
91
+
92
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
93
+ return <div data-slot="dialog-header" className={cn("flex flex-col gap-2", className)} {...props} />
94
+ }
95
+
96
+ function DialogFooter({
97
+ className,
98
+ showCloseButton = false,
99
+ children,
100
+ ...props
101
+ }: React.ComponentProps<"div"> & {
102
+ showCloseButton?: boolean
103
+ }) {
104
+ return (
105
+ <div
106
+ data-slot="dialog-footer"
107
+ className={cn(
108
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
109
+ className
110
+ )}
111
+ {...props}
112
+ >
113
+ {children}
114
+ {showCloseButton && (
115
+ <DialogPrimitive.CloseTrigger asChild>
116
+ <Button variant="outline">Close</Button>
117
+ </DialogPrimitive.CloseTrigger>
118
+ )}
119
+ </div>
120
+ )
121
+ }
122
+
123
+ function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
124
+ return (
125
+ <DialogPrimitive.Title
126
+ data-slot="dialog-title"
127
+ className={cn("font-heading text-base leading-none font-medium", className)}
128
+ {...props}
129
+ />
130
+ )
131
+ }
132
+
133
+ function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
134
+ return (
135
+ <DialogPrimitive.Description
136
+ data-slot="dialog-description"
137
+ className={cn(
138
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
139
+ className
140
+ )}
141
+ {...props}
142
+ />
143
+ )
144
+ }
145
+
146
+ export {
147
+ Dialog,
148
+ DialogClose,
149
+ DialogContent,
150
+ DialogContext,
151
+ DialogDescription,
152
+ DialogFooter,
153
+ DialogHeader,
154
+ DialogOverlay,
155
+ DialogPortal,
156
+ DialogPositioner,
157
+ DialogTitle,
158
+ DialogTrigger,
159
+ }
@@ -0,0 +1,32 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+
5
+ type Direction = "ltr" | "rtl"
6
+
7
+ /**
8
+ * Ark UI has no global direction provider; each Ark component accepts a `dir`
9
+ * prop and its `LocaleProvider` derives direction from a locale. This mirrors
10
+ * Radix's `DirectionProvider`: a plain React context you can read with
11
+ * `useDirection` and forward to Ark components as `dir`.
12
+ */
13
+ const DirectionContext = React.createContext<Direction | undefined>(undefined)
14
+
15
+ function DirectionProvider({
16
+ dir,
17
+ direction,
18
+ children,
19
+ }: {
20
+ dir?: Direction
21
+ direction?: Direction
22
+ children?: React.ReactNode
23
+ }) {
24
+ return <DirectionContext.Provider value={direction ?? dir}>{children}</DirectionContext.Provider>
25
+ }
26
+
27
+ function useDirection(localDir?: Direction): Direction {
28
+ const globalDir = React.useContext(DirectionContext)
29
+ return localDir ?? globalDir ?? "ltr"
30
+ }
31
+
32
+ export { DirectionProvider, useDirection }
@@ -0,0 +1,200 @@
1
+ import * as React from "react"
2
+ import { cn } from "@/lib/utils"
3
+ import { Drawer as DrawerPrimitive, Portal as PortalPrimitive } from "@ark-ui/react"
4
+
5
+ type DrawerDirection = "top" | "bottom" | "left" | "right"
6
+
7
+ const swipeDirectionByDirection = {
8
+ bottom: "down",
9
+ top: "up",
10
+ left: "start",
11
+ right: "end",
12
+ } as const
13
+
14
+ function Drawer({
15
+ direction = "bottom",
16
+ swipeDirection,
17
+ lazyMount = true,
18
+ unmountOnExit = true,
19
+ ...props
20
+ }: React.ComponentProps<typeof DrawerPrimitive.Root> & {
21
+ /** Edge the drawer slides in from. Maps to Ark's `swipeDirection`. */
22
+ direction?: DrawerDirection
23
+ }) {
24
+ return (
25
+ <DrawerPrimitive.Root
26
+ swipeDirection={swipeDirection ?? swipeDirectionByDirection[direction]}
27
+ lazyMount={lazyMount}
28
+ unmountOnExit={unmountOnExit}
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
35
+ return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
36
+ }
37
+
38
+ function DrawerPortal({ ...props }: React.ComponentProps<typeof PortalPrimitive>) {
39
+ return <PortalPrimitive {...props} />
40
+ }
41
+
42
+ function DrawerContext({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Context>) {
43
+ return <DrawerPrimitive.Context {...props} />
44
+ }
45
+
46
+ function DrawerClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.CloseTrigger>) {
47
+ return <DrawerPrimitive.CloseTrigger data-slot="drawer-close" {...props} />
48
+ }
49
+
50
+ function DrawerOverlay({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Backdrop>) {
51
+ return (
52
+ <DrawerPrimitive.Backdrop
53
+ data-slot="drawer-overlay"
54
+ className={cn(
55
+ "fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
56
+ className
57
+ )}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+
63
+ function DrawerPositioner({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Positioner>) {
64
+ return (
65
+ <DrawerPrimitive.Positioner
66
+ data-slot="drawer-positioner"
67
+ className={cn("fixed inset-0 z-50", className)}
68
+ {...props}
69
+ />
70
+ )
71
+ }
72
+
73
+ function DrawerGrabber({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Grabber>) {
74
+ return (
75
+ <DrawerPrimitive.Grabber
76
+ data-slot="drawer-grabber"
77
+ className={cn(
78
+ "mx-auto mt-4 hidden shrink-0 cursor-grab touch-none group-data-[swipe-direction=down]/drawer-content:block",
79
+ className
80
+ )}
81
+ {...props}
82
+ >
83
+ <DrawerPrimitive.GrabberIndicator
84
+ data-slot="drawer-grabber-indicator"
85
+ className="block h-1 w-25 rounded-full bg-muted"
86
+ />
87
+ </DrawerPrimitive.Grabber>
88
+ )
89
+ }
90
+
91
+ function DrawerContent({ className, children, ...props }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
92
+ return (
93
+ <DrawerPortal>
94
+ <DrawerOverlay />
95
+ <DrawerPositioner>
96
+ <DrawerPrimitive.Content
97
+ data-slot="drawer-content"
98
+ className={cn(
99
+ "group/drawer-content absolute flex h-auto flex-col bg-popover text-sm text-popover-foreground outline-hidden transition-transform duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] data-[swipe-direction=down]:inset-x-0 data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:mt-24 data-[swipe-direction=down]:max-h-[80vh] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t data-[swipe-direction=left]:inset-y-0 data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:w-3/4 data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:border-r data-[swipe-direction=right]:inset-y-0 data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:w-3/4 data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:border-l data-[swipe-direction=up]:inset-x-0 data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:mb-24 data-[swipe-direction=up]:max-h-[80vh] data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b data-[swipe-direction=left]:sm:max-w-sm data-[swipe-direction=right]:sm:max-w-sm data-open:animate-in data-[swipe-direction=down]:data-open:slide-in-from-bottom-full data-[swipe-direction=left]:data-open:slide-in-from-left-full data-[swipe-direction=right]:data-open:slide-in-from-right-full data-[swipe-direction=up]:data-open:slide-in-from-top-full data-closed:animate-out data-[swipe-direction=down]:data-closed:slide-out-to-bottom-full data-[swipe-direction=left]:data-closed:slide-out-to-left-full data-[swipe-direction=right]:data-closed:slide-out-to-right-full data-[swipe-direction=up]:data-closed:slide-out-to-top-full",
100
+ className
101
+ )}
102
+ {...props}
103
+ >
104
+ <DrawerGrabber />
105
+ {children}
106
+ </DrawerPrimitive.Content>
107
+ </DrawerPositioner>
108
+ </DrawerPortal>
109
+ )
110
+ }
111
+
112
+ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
113
+ return (
114
+ <div
115
+ data-slot="drawer-header"
116
+ className={cn(
117
+ "flex flex-col gap-0.5 p-4 group-data-[swipe-direction=down]/drawer-content:text-center group-data-[swipe-direction=up]/drawer-content:text-center md:gap-0.5 md:text-left",
118
+ className
119
+ )}
120
+ {...props}
121
+ />
122
+ )
123
+ }
124
+
125
+ function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
126
+ return <div data-slot="drawer-footer" className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
127
+ }
128
+
129
+ function DrawerTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
130
+ return (
131
+ <DrawerPrimitive.Title
132
+ data-slot="drawer-title"
133
+ className={cn("font-heading text-base font-medium text-foreground", className)}
134
+ {...props}
135
+ />
136
+ )
137
+ }
138
+
139
+ function DrawerDescription({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
140
+ return (
141
+ <DrawerPrimitive.Description
142
+ data-slot="drawer-description"
143
+ className={cn("text-sm text-muted-foreground", className)}
144
+ {...props}
145
+ />
146
+ )
147
+ }
148
+
149
+ function DrawerSwipeArea({ ...props }: React.ComponentProps<typeof DrawerPrimitive.SwipeArea>) {
150
+ return <DrawerPrimitive.SwipeArea data-slot="drawer-swipe-area" {...props} />
151
+ }
152
+
153
+ /** Wrap page content in a stack so nested drawers push it back (`Drawer` parts inside read the stack). */
154
+ function DrawerStack({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Stack>) {
155
+ return <DrawerPrimitive.Stack data-slot="drawer-stack" {...props} />
156
+ }
157
+
158
+ /** The layer that scales and shifts back when a drawer opens over it. */
159
+ function DrawerIndent({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Indent>) {
160
+ return (
161
+ <DrawerPrimitive.Indent
162
+ data-slot="drawer-indent"
163
+ className={cn("origin-center transition-transform duration-300 ease-out", className)}
164
+ {...props}
165
+ />
166
+ )
167
+ }
168
+
169
+ function DrawerIndentBackground({
170
+ className,
171
+ ...props
172
+ }: React.ComponentProps<typeof DrawerPrimitive.IndentBackground>) {
173
+ return (
174
+ <DrawerPrimitive.IndentBackground
175
+ data-slot="drawer-indent-background"
176
+ className={cn("fixed inset-0 bg-black", className)}
177
+ {...props}
178
+ />
179
+ )
180
+ }
181
+
182
+ export {
183
+ Drawer,
184
+ DrawerClose,
185
+ DrawerContent,
186
+ DrawerContext,
187
+ DrawerDescription,
188
+ DrawerFooter,
189
+ DrawerGrabber,
190
+ DrawerHeader,
191
+ DrawerOverlay,
192
+ DrawerPortal,
193
+ DrawerPositioner,
194
+ DrawerSwipeArea,
195
+ DrawerTitle,
196
+ DrawerTrigger,
197
+ DrawerIndent,
198
+ DrawerIndentBackground,
199
+ DrawerStack,
200
+ }