@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,665 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { cn } from "@/lib/utils"
4
+ import { ark } from "@ark-ui/react"
5
+
6
+ import { useIsMobile } from "@/hooks/use-mobile"
7
+ import { Button } from "@/components/ui/button"
8
+ import { Input } from "@/components/ui/input"
9
+ import { Separator } from "@/components/ui/separator"
10
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "@/components/ui/sheet"
11
+ import { Skeleton } from "@/components/ui/skeleton"
12
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
13
+ import { PanelLeftIcon } from "lucide-react"
14
+
15
+ const SIDEBAR_COOKIE_NAME = "sidebar_state"
16
+ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
17
+ const SIDEBAR_WIDTH = "16rem"
18
+ const SIDEBAR_WIDTH_MOBILE = "18rem"
19
+ const SIDEBAR_WIDTH_ICON = "3rem"
20
+ const SIDEBAR_KEYBOARD_SHORTCUT = "b"
21
+
22
+ type SidebarContextProps = {
23
+ state: "expanded" | "collapsed"
24
+ open: boolean
25
+ setOpen: (open: boolean) => void
26
+ openMobile: boolean
27
+ setOpenMobile: (open: boolean) => void
28
+ isMobile: boolean
29
+ toggleSidebar: () => void
30
+ }
31
+
32
+ const SidebarContext = React.createContext<SidebarContextProps | null>(null)
33
+
34
+ function useSidebar() {
35
+ const context = React.useContext(SidebarContext)
36
+ if (!context) {
37
+ throw new Error("useSidebar must be used within a SidebarProvider.")
38
+ }
39
+
40
+ return context
41
+ }
42
+
43
+ function SidebarProvider({
44
+ defaultOpen = true,
45
+ open: openProp,
46
+ onOpenChange: setOpenProp,
47
+ className,
48
+ style,
49
+ children,
50
+ ...props
51
+ }: React.ComponentProps<"div"> & {
52
+ defaultOpen?: boolean
53
+ open?: boolean
54
+ onOpenChange?: (open: boolean) => void
55
+ }) {
56
+ const isMobile = useIsMobile()
57
+ const [openMobile, setOpenMobile] = React.useState(false)
58
+
59
+ // This is the internal state of the sidebar.
60
+ // We use openProp and setOpenProp for control from outside the component.
61
+ const [_open, _setOpen] = React.useState(defaultOpen)
62
+ const open = openProp ?? _open
63
+ const setOpen = React.useCallback(
64
+ (value: boolean | ((value: boolean) => boolean)) => {
65
+ const openState = typeof value === "function" ? value(open) : value
66
+ if (setOpenProp) {
67
+ setOpenProp(openState)
68
+ } else {
69
+ _setOpen(openState)
70
+ }
71
+
72
+ // This sets the cookie to keep the sidebar state.
73
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
74
+ },
75
+ [setOpenProp, open]
76
+ )
77
+
78
+ // Helper to toggle the sidebar.
79
+ const toggleSidebar = React.useCallback(() => {
80
+ return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)
81
+ }, [isMobile, setOpen, setOpenMobile])
82
+
83
+ // Adds a keyboard shortcut to toggle the sidebar.
84
+ React.useEffect(() => {
85
+ const handleKeyDown = (event: KeyboardEvent) => {
86
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
87
+ event.preventDefault()
88
+ toggleSidebar()
89
+ }
90
+ }
91
+
92
+ window.addEventListener("keydown", handleKeyDown)
93
+ return () => window.removeEventListener("keydown", handleKeyDown)
94
+ }, [toggleSidebar])
95
+
96
+ // We add a state so that we can do data-state="expanded" or "collapsed".
97
+ // This makes it easier to style the sidebar with Tailwind classes.
98
+ const state = open ? "expanded" : "collapsed"
99
+
100
+ const contextValue = React.useMemo<SidebarContextProps>(
101
+ () => ({
102
+ state,
103
+ open,
104
+ setOpen,
105
+ isMobile,
106
+ openMobile,
107
+ setOpenMobile,
108
+ toggleSidebar,
109
+ }),
110
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
111
+ )
112
+
113
+ return (
114
+ <SidebarContext.Provider value={contextValue}>
115
+ <div
116
+ data-slot="sidebar-wrapper"
117
+ style={
118
+ {
119
+ "--sidebar-width": SIDEBAR_WIDTH,
120
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
121
+ ...style,
122
+ } as React.CSSProperties
123
+ }
124
+ className={cn("group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className)}
125
+ {...props}
126
+ >
127
+ {children}
128
+ </div>
129
+ </SidebarContext.Provider>
130
+ )
131
+ }
132
+
133
+ function Sidebar({
134
+ side = "left",
135
+ variant = "sidebar",
136
+ collapsible = "offcanvas",
137
+ className,
138
+ children,
139
+ dir,
140
+ ...props
141
+ }: React.ComponentProps<"div"> & {
142
+ side?: "left" | "right"
143
+ variant?: "sidebar" | "floating" | "inset"
144
+ collapsible?: "offcanvas" | "icon" | "none"
145
+ }) {
146
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
147
+
148
+ if (collapsible === "none") {
149
+ return (
150
+ <div
151
+ data-slot="sidebar"
152
+ className={cn("flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground", className)}
153
+ {...props}
154
+ >
155
+ {children}
156
+ </div>
157
+ )
158
+ }
159
+
160
+ if (isMobile) {
161
+ return (
162
+ <Sheet open={openMobile} onOpenChange={({ open }) => setOpenMobile(open)}>
163
+ <SheetContent
164
+ {...props}
165
+ dir={dir}
166
+ data-sidebar="sidebar"
167
+ data-slot="sidebar"
168
+ data-mobile="true"
169
+ className="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
170
+ style={
171
+ {
172
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
173
+ } as React.CSSProperties
174
+ }
175
+ side={side}
176
+ >
177
+ <SheetHeader className="sr-only">
178
+ <SheetTitle>Sidebar</SheetTitle>
179
+ <SheetDescription>Displays the mobile sidebar.</SheetDescription>
180
+ </SheetHeader>
181
+ <div className="flex size-full flex-col">{children}</div>
182
+ </SheetContent>
183
+ </Sheet>
184
+ )
185
+ }
186
+
187
+ return (
188
+ <div
189
+ className="group peer hidden text-sidebar-foreground md:block"
190
+ data-state={state}
191
+ data-collapsible={state === "collapsed" ? collapsible : ""}
192
+ data-variant={variant}
193
+ data-side={side}
194
+ data-slot="sidebar"
195
+ >
196
+ {/* This is what handles the sidebar gap on desktop */}
197
+ <div
198
+ data-slot="sidebar-gap"
199
+ className={cn(
200
+ "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
201
+ "group-data-[collapsible=offcanvas]:w-0",
202
+ "group-data-[side=right]:rotate-180",
203
+ variant === "floating" || variant === "inset"
204
+ ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
205
+ : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
206
+ )}
207
+ />
208
+ <div
209
+ data-slot="sidebar-container"
210
+ data-side={side}
211
+ className={cn(
212
+ "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:-left-(--sidebar-width) data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:-right-(--sidebar-width) md:flex",
213
+ // Adjust the padding for floating and inset variants.
214
+ variant === "floating" || variant === "inset"
215
+ ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
216
+ : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
217
+ className
218
+ )}
219
+ {...props}
220
+ >
221
+ <div
222
+ data-sidebar="sidebar"
223
+ data-slot="sidebar-inner"
224
+ className="flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border"
225
+ >
226
+ {children}
227
+ </div>
228
+ </div>
229
+ </div>
230
+ )
231
+ }
232
+
233
+ function SidebarTrigger({ className, onClick, asChild, children, ...props }: React.ComponentProps<typeof Button>) {
234
+ const { toggleSidebar } = useSidebar()
235
+
236
+ return (
237
+ <Button
238
+ data-sidebar="trigger"
239
+ data-slot="sidebar-trigger"
240
+ variant="ghost"
241
+ size="icon-sm"
242
+ asChild={asChild}
243
+ className={cn(className)}
244
+ onClick={(event) => {
245
+ onClick?.(event)
246
+ toggleSidebar()
247
+ }}
248
+ {...props}
249
+ >
250
+ {asChild
251
+ ? children
252
+ : (children ?? (
253
+ <>
254
+ <PanelLeftIcon />
255
+ <span className="sr-only">Toggle Sidebar</span>
256
+ </>
257
+ ))}
258
+ </Button>
259
+ )
260
+ }
261
+
262
+ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
263
+ const { toggleSidebar } = useSidebar()
264
+
265
+ return (
266
+ <button
267
+ data-sidebar="rail"
268
+ data-slot="sidebar-rail"
269
+ aria-label="Toggle Sidebar"
270
+ tabIndex={-1}
271
+ onClick={toggleSidebar}
272
+ title="Toggle Sidebar"
273
+ className={cn(
274
+ "absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:inset-s-1/2 after:w-0.5 hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2",
275
+ "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
276
+ "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
277
+ "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar",
278
+ "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
279
+ "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
280
+ className
281
+ )}
282
+ {...props}
283
+ />
284
+ )
285
+ }
286
+
287
+ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
288
+ return (
289
+ <main
290
+ data-slot="sidebar-inset"
291
+ className={cn(
292
+ "relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
293
+ className
294
+ )}
295
+ {...props}
296
+ />
297
+ )
298
+ }
299
+
300
+ function SidebarInput({ className, ...props }: React.ComponentProps<typeof Input>) {
301
+ return (
302
+ <Input
303
+ data-slot="sidebar-input"
304
+ data-sidebar="input"
305
+ className={cn("h-8 w-full bg-background shadow-none", className)}
306
+ {...props}
307
+ />
308
+ )
309
+ }
310
+
311
+ function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
312
+ return (
313
+ <div
314
+ data-slot="sidebar-header"
315
+ data-sidebar="header"
316
+ className={cn("flex flex-col gap-2 p-2", className)}
317
+ {...props}
318
+ />
319
+ )
320
+ }
321
+
322
+ function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
323
+ return (
324
+ <div
325
+ data-slot="sidebar-footer"
326
+ data-sidebar="footer"
327
+ className={cn("flex flex-col gap-2 p-2", className)}
328
+ {...props}
329
+ />
330
+ )
331
+ }
332
+
333
+ function SidebarSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {
334
+ return (
335
+ <Separator
336
+ data-slot="sidebar-separator"
337
+ data-sidebar="separator"
338
+ className={cn("mx-2 w-auto bg-sidebar-border", className)}
339
+ {...props}
340
+ />
341
+ )
342
+ }
343
+
344
+ function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
345
+ return (
346
+ <div
347
+ data-slot="sidebar-content"
348
+ data-sidebar="content"
349
+ className={cn(
350
+ "no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
351
+ className
352
+ )}
353
+ {...props}
354
+ />
355
+ )
356
+ }
357
+
358
+ function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
359
+ return (
360
+ <div
361
+ data-slot="sidebar-group"
362
+ data-sidebar="group"
363
+ className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
364
+ {...props}
365
+ />
366
+ )
367
+ }
368
+
369
+ function SidebarGroupLabel({
370
+ className,
371
+ asChild = false,
372
+ ...props
373
+ }: React.ComponentProps<"div"> & { asChild?: boolean }) {
374
+ const Comp = ark.div
375
+
376
+ return (
377
+ <Comp
378
+ asChild={asChild}
379
+ data-slot="sidebar-group-label"
380
+ data-sidebar="group-label"
381
+ className={cn(
382
+ "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
383
+ className
384
+ )}
385
+ {...props}
386
+ />
387
+ )
388
+ }
389
+
390
+ function SidebarGroupAction({
391
+ className,
392
+ asChild = false,
393
+ ...props
394
+ }: React.ComponentProps<"button"> & { asChild?: boolean }) {
395
+ const Comp = ark.button
396
+
397
+ return (
398
+ <Comp
399
+ asChild={asChild}
400
+ data-slot="sidebar-group-action"
401
+ data-sidebar="group-action"
402
+ className={cn(
403
+ "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
404
+ className
405
+ )}
406
+ {...props}
407
+ />
408
+ )
409
+ }
410
+
411
+ function SidebarGroupContent({ className, ...props }: React.ComponentProps<"div">) {
412
+ return (
413
+ <div
414
+ data-slot="sidebar-group-content"
415
+ data-sidebar="group-content"
416
+ className={cn("w-full text-sm", className)}
417
+ {...props}
418
+ />
419
+ )
420
+ }
421
+
422
+ function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
423
+ return (
424
+ <ul
425
+ data-slot="sidebar-menu"
426
+ data-sidebar="menu"
427
+ className={cn("flex w-full min-w-0 flex-col gap-0", className)}
428
+ {...props}
429
+ />
430
+ )
431
+ }
432
+
433
+ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
434
+ return (
435
+ <li
436
+ data-slot="sidebar-menu-item"
437
+ data-sidebar="menu-item"
438
+ className={cn("group/menu-item relative", className)}
439
+ {...props}
440
+ />
441
+ )
442
+ }
443
+
444
+ const sidebarMenuButtonVariants = cva(
445
+ "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
446
+ {
447
+ variants: {
448
+ variant: {
449
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
450
+ outline:
451
+ "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]",
452
+ },
453
+ size: {
454
+ default: "h-8 text-sm",
455
+ sm: "h-7 text-xs",
456
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
457
+ },
458
+ },
459
+ defaultVariants: {
460
+ variant: "default",
461
+ size: "default",
462
+ },
463
+ }
464
+ )
465
+
466
+ function SidebarMenuButton({
467
+ asChild = false,
468
+ isActive = false,
469
+ variant = "default",
470
+ size = "default",
471
+ tooltip,
472
+ className,
473
+ ...props
474
+ }: React.ComponentProps<"button"> & {
475
+ asChild?: boolean
476
+ isActive?: boolean
477
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>
478
+ } & VariantProps<typeof sidebarMenuButtonVariants>) {
479
+ const Comp = ark.button
480
+ const { isMobile, state } = useSidebar()
481
+
482
+ const button = (
483
+ <Comp
484
+ asChild={asChild}
485
+ data-slot="sidebar-menu-button"
486
+ data-sidebar="menu-button"
487
+ data-size={size}
488
+ data-active={isActive}
489
+ className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
490
+ {...props}
491
+ />
492
+ )
493
+
494
+ if (!tooltip) {
495
+ return button
496
+ }
497
+
498
+ if (typeof tooltip === "string") {
499
+ tooltip = {
500
+ children: tooltip,
501
+ }
502
+ }
503
+
504
+ return (
505
+ <Tooltip positioning={{ placement: "right" }}>
506
+ <TooltipTrigger asChild>{button}</TooltipTrigger>
507
+ <TooltipContent hidden={state !== "collapsed" || isMobile} {...tooltip} />
508
+ </Tooltip>
509
+ )
510
+ }
511
+
512
+ function SidebarMenuAction({
513
+ className,
514
+ asChild = false,
515
+ showOnHover = false,
516
+ ...props
517
+ }: React.ComponentProps<"button"> & {
518
+ asChild?: boolean
519
+ showOnHover?: boolean
520
+ }) {
521
+ const Comp = ark.button
522
+
523
+ return (
524
+ <Comp
525
+ asChild={asChild}
526
+ data-slot="sidebar-menu-action"
527
+ data-sidebar="menu-action"
528
+ className={cn(
529
+ "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
530
+ showOnHover &&
531
+ "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
532
+ className
533
+ )}
534
+ {...props}
535
+ />
536
+ )
537
+ }
538
+
539
+ function SidebarMenuBadge({ className, ...props }: React.ComponentProps<"div">) {
540
+ return (
541
+ <div
542
+ data-slot="sidebar-menu-badge"
543
+ data-sidebar="menu-badge"
544
+ className={cn(
545
+ "pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-active/menu-button:text-sidebar-accent-foreground",
546
+ className
547
+ )}
548
+ {...props}
549
+ />
550
+ )
551
+ }
552
+
553
+ function SidebarMenuSkeleton({
554
+ className,
555
+ showIcon = false,
556
+ ...props
557
+ }: React.ComponentProps<"div"> & {
558
+ showIcon?: boolean
559
+ }) {
560
+ // Random width between 50 to 90%.
561
+ const [width] = React.useState(() => {
562
+ return `${Math.floor(Math.random() * 40) + 50}%`
563
+ })
564
+
565
+ return (
566
+ <div
567
+ data-slot="sidebar-menu-skeleton"
568
+ data-sidebar="menu-skeleton"
569
+ className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
570
+ {...props}
571
+ >
572
+ {showIcon && <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />}
573
+ <Skeleton
574
+ className="h-4 max-w-(--skeleton-width) flex-1"
575
+ data-sidebar="menu-skeleton-text"
576
+ style={
577
+ {
578
+ "--skeleton-width": width,
579
+ } as React.CSSProperties
580
+ }
581
+ />
582
+ </div>
583
+ )
584
+ }
585
+
586
+ function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
587
+ return (
588
+ <ul
589
+ data-slot="sidebar-menu-sub"
590
+ data-sidebar="menu-sub"
591
+ className={cn(
592
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden",
593
+ className
594
+ )}
595
+ {...props}
596
+ />
597
+ )
598
+ }
599
+
600
+ function SidebarMenuSubItem({ className, ...props }: React.ComponentProps<"li">) {
601
+ return (
602
+ <li
603
+ data-slot="sidebar-menu-sub-item"
604
+ data-sidebar="menu-sub-item"
605
+ className={cn("group/menu-sub-item relative", className)}
606
+ {...props}
607
+ />
608
+ )
609
+ }
610
+
611
+ function SidebarMenuSubButton({
612
+ asChild = false,
613
+ size = "md",
614
+ isActive = false,
615
+ className,
616
+ ...props
617
+ }: React.ComponentProps<"a"> & {
618
+ asChild?: boolean
619
+ size?: "sm" | "md"
620
+ isActive?: boolean
621
+ }) {
622
+ const Comp = ark.a
623
+
624
+ return (
625
+ <Comp
626
+ asChild={asChild}
627
+ data-slot="sidebar-menu-sub-button"
628
+ data-sidebar="menu-sub-button"
629
+ data-size={size}
630
+ data-active={isActive}
631
+ className={cn(
632
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
633
+ className
634
+ )}
635
+ {...props}
636
+ />
637
+ )
638
+ }
639
+
640
+ export {
641
+ Sidebar,
642
+ SidebarContent,
643
+ SidebarFooter,
644
+ SidebarGroup,
645
+ SidebarGroupAction,
646
+ SidebarGroupContent,
647
+ SidebarGroupLabel,
648
+ SidebarHeader,
649
+ SidebarInput,
650
+ SidebarInset,
651
+ SidebarMenu,
652
+ SidebarMenuAction,
653
+ SidebarMenuBadge,
654
+ SidebarMenuButton,
655
+ SidebarMenuItem,
656
+ SidebarMenuSkeleton,
657
+ SidebarMenuSub,
658
+ SidebarMenuSubButton,
659
+ SidebarMenuSubItem,
660
+ SidebarProvider,
661
+ SidebarRail,
662
+ SidebarSeparator,
663
+ SidebarTrigger,
664
+ useSidebar,
665
+ }