@inui/design-system 0.0.0-stage → 1.22.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 (312) hide show
  1. package/README.md +360 -2
  2. package/dist/components/ui/accordion.d.ts +44 -0
  3. package/dist/components/ui/accordion.d.ts.map +1 -0
  4. package/dist/components/ui/accordion.js +86 -0
  5. package/dist/components/ui/accordion.js.map +1 -0
  6. package/dist/components/ui/ai-avatar.d.ts +46 -0
  7. package/dist/components/ui/ai-avatar.d.ts.map +1 -0
  8. package/dist/components/ui/ai-avatar.js +43 -0
  9. package/dist/components/ui/ai-avatar.js.map +1 -0
  10. package/dist/components/ui/ai-label.d.ts +118 -0
  11. package/dist/components/ui/ai-label.d.ts.map +1 -0
  12. package/dist/components/ui/ai-label.js +184 -0
  13. package/dist/components/ui/ai-label.js.map +1 -0
  14. package/dist/components/ui/ai-sparkle.d.ts +91 -0
  15. package/dist/components/ui/ai-sparkle.d.ts.map +1 -0
  16. package/dist/components/ui/ai-sparkle.js +200 -0
  17. package/dist/components/ui/ai-sparkle.js.map +1 -0
  18. package/dist/components/ui/alert-dialog.d.ts +79 -0
  19. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  20. package/dist/components/ui/alert-dialog.js +147 -0
  21. package/dist/components/ui/alert-dialog.js.map +1 -0
  22. package/dist/components/ui/alert.d.ts +71 -0
  23. package/dist/components/ui/alert.d.ts.map +1 -0
  24. package/dist/components/ui/alert.js +108 -0
  25. package/dist/components/ui/alert.js.map +1 -0
  26. package/dist/components/ui/aspect-ratio.d.ts +30 -0
  27. package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
  28. package/dist/components/ui/aspect-ratio.js +40 -0
  29. package/dist/components/ui/aspect-ratio.js.map +1 -0
  30. package/dist/components/ui/attachment.d.ts +74 -0
  31. package/dist/components/ui/attachment.d.ts.map +1 -0
  32. package/dist/components/ui/attachment.js +142 -0
  33. package/dist/components/ui/attachment.js.map +1 -0
  34. package/dist/components/ui/avatar.d.ts +82 -0
  35. package/dist/components/ui/avatar.d.ts.map +1 -0
  36. package/dist/components/ui/avatar.js +123 -0
  37. package/dist/components/ui/avatar.js.map +1 -0
  38. package/dist/components/ui/badge.d.ts +130 -0
  39. package/dist/components/ui/badge.d.ts.map +1 -0
  40. package/dist/components/ui/badge.js +226 -0
  41. package/dist/components/ui/badge.js.map +1 -0
  42. package/dist/components/ui/breadcrumb.d.ts +43 -0
  43. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  44. package/dist/components/ui/breadcrumb.js +98 -0
  45. package/dist/components/ui/breadcrumb.js.map +1 -0
  46. package/dist/components/ui/browser-tabs.d.ts +218 -0
  47. package/dist/components/ui/browser-tabs.d.ts.map +1 -0
  48. package/dist/components/ui/browser-tabs.js +528 -0
  49. package/dist/components/ui/browser-tabs.js.map +1 -0
  50. package/dist/components/ui/bubble.d.ts +80 -0
  51. package/dist/components/ui/bubble.d.ts.map +1 -0
  52. package/dist/components/ui/bubble.js +235 -0
  53. package/dist/components/ui/bubble.js.map +1 -0
  54. package/dist/components/ui/button-group.d.ts +60 -0
  55. package/dist/components/ui/button-group.d.ts.map +1 -0
  56. package/dist/components/ui/button-group.js +89 -0
  57. package/dist/components/ui/button-group.js.map +1 -0
  58. package/dist/components/ui/button.d.ts +157 -0
  59. package/dist/components/ui/button.d.ts.map +1 -0
  60. package/dist/components/ui/button.js +144 -0
  61. package/dist/components/ui/button.js.map +1 -0
  62. package/dist/components/ui/calendar.d.ts +57 -0
  63. package/dist/components/ui/calendar.d.ts.map +1 -0
  64. package/dist/components/ui/calendar.js +163 -0
  65. package/dist/components/ui/calendar.js.map +1 -0
  66. package/dist/components/ui/card.d.ts +96 -0
  67. package/dist/components/ui/card.d.ts.map +1 -0
  68. package/dist/components/ui/card.js +131 -0
  69. package/dist/components/ui/card.js.map +1 -0
  70. package/dist/components/ui/carousel.d.ts +86 -0
  71. package/dist/components/ui/carousel.d.ts.map +1 -0
  72. package/dist/components/ui/carousel.js +207 -0
  73. package/dist/components/ui/carousel.js.map +1 -0
  74. package/dist/components/ui/checkbox.d.ts +54 -0
  75. package/dist/components/ui/checkbox.d.ts.map +1 -0
  76. package/dist/components/ui/checkbox.js +78 -0
  77. package/dist/components/ui/checkbox.js.map +1 -0
  78. package/dist/components/ui/collapsible.d.ts +45 -0
  79. package/dist/components/ui/collapsible.d.ts.map +1 -0
  80. package/dist/components/ui/collapsible.js +65 -0
  81. package/dist/components/ui/collapsible.js.map +1 -0
  82. package/dist/components/ui/combobox.d.ts +111 -0
  83. package/dist/components/ui/combobox.d.ts.map +1 -0
  84. package/dist/components/ui/combobox.js +264 -0
  85. package/dist/components/ui/combobox.js.map +1 -0
  86. package/dist/components/ui/command.d.ts +71 -0
  87. package/dist/components/ui/command.d.ts.map +1 -0
  88. package/dist/components/ui/command.js +133 -0
  89. package/dist/components/ui/command.js.map +1 -0
  90. package/dist/components/ui/context-menu.d.ts +70 -0
  91. package/dist/components/ui/context-menu.d.ts.map +1 -0
  92. package/dist/components/ui/context-menu.js +163 -0
  93. package/dist/components/ui/context-menu.js.map +1 -0
  94. package/dist/components/ui/count-badge.d.ts +40 -0
  95. package/dist/components/ui/count-badge.d.ts.map +1 -0
  96. package/dist/components/ui/count-badge.js +43 -0
  97. package/dist/components/ui/count-badge.js.map +1 -0
  98. package/dist/components/ui/data-table.d.ts +1026 -0
  99. package/dist/components/ui/data-table.d.ts.map +1 -0
  100. package/dist/components/ui/data-table.js +3423 -0
  101. package/dist/components/ui/data-table.js.map +1 -0
  102. package/dist/components/ui/dialog.d.ts +73 -0
  103. package/dist/components/ui/dialog.d.ts.map +1 -0
  104. package/dist/components/ui/dialog.js +145 -0
  105. package/dist/components/ui/dialog.js.map +1 -0
  106. package/dist/components/ui/direction.d.ts +35 -0
  107. package/dist/components/ui/direction.d.ts.map +1 -0
  108. package/dist/components/ui/direction.js +35 -0
  109. package/dist/components/ui/direction.js.map +1 -0
  110. package/dist/components/ui/drawer.d.ts +53 -0
  111. package/dist/components/ui/drawer.d.ts.map +1 -0
  112. package/dist/components/ui/drawer.js +115 -0
  113. package/dist/components/ui/drawer.js.map +1 -0
  114. package/dist/components/ui/dropdown-menu.d.ts +75 -0
  115. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  116. package/dist/components/ui/dropdown-menu.js +173 -0
  117. package/dist/components/ui/dropdown-menu.js.map +1 -0
  118. package/dist/components/ui/dropzone.d.ts +141 -0
  119. package/dist/components/ui/dropzone.d.ts.map +1 -0
  120. package/dist/components/ui/dropzone.js +257 -0
  121. package/dist/components/ui/dropzone.js.map +1 -0
  122. package/dist/components/ui/empty.d.ts +94 -0
  123. package/dist/components/ui/empty.d.ts.map +1 -0
  124. package/dist/components/ui/empty.js +149 -0
  125. package/dist/components/ui/empty.js.map +1 -0
  126. package/dist/components/ui/field.d.ts +122 -0
  127. package/dist/components/ui/field.d.ts.map +1 -0
  128. package/dist/components/ui/field.js +254 -0
  129. package/dist/components/ui/field.js.map +1 -0
  130. package/dist/components/ui/hover-card.d.ts +51 -0
  131. package/dist/components/ui/hover-card.d.ts.map +1 -0
  132. package/dist/components/ui/hover-card.js +101 -0
  133. package/dist/components/ui/hover-card.js.map +1 -0
  134. package/dist/components/ui/input-group.d.ts +62 -0
  135. package/dist/components/ui/input-group.d.ts.map +1 -0
  136. package/dist/components/ui/input-group.js +115 -0
  137. package/dist/components/ui/input-group.js.map +1 -0
  138. package/dist/components/ui/input-otp.d.ts +52 -0
  139. package/dist/components/ui/input-otp.d.ts.map +1 -0
  140. package/dist/components/ui/input-otp.js +89 -0
  141. package/dist/components/ui/input-otp.js.map +1 -0
  142. package/dist/components/ui/input.d.ts +47 -0
  143. package/dist/components/ui/input.d.ts.map +1 -0
  144. package/dist/components/ui/input.js +47 -0
  145. package/dist/components/ui/input.js.map +1 -0
  146. package/dist/components/ui/item.d.ts +74 -0
  147. package/dist/components/ui/item.d.ts.map +1 -0
  148. package/dist/components/ui/item.js +176 -0
  149. package/dist/components/ui/item.js.map +1 -0
  150. package/dist/components/ui/kbd.d.ts +41 -0
  151. package/dist/components/ui/kbd.d.ts.map +1 -0
  152. package/dist/components/ui/kbd.js +58 -0
  153. package/dist/components/ui/kbd.js.map +1 -0
  154. package/dist/components/ui/key-value-pair.d.ts +56 -0
  155. package/dist/components/ui/key-value-pair.d.ts.map +1 -0
  156. package/dist/components/ui/key-value-pair.js +110 -0
  157. package/dist/components/ui/key-value-pair.js.map +1 -0
  158. package/dist/components/ui/label.d.ts +83 -0
  159. package/dist/components/ui/label.d.ts.map +1 -0
  160. package/dist/components/ui/label.js +85 -0
  161. package/dist/components/ui/label.js.map +1 -0
  162. package/dist/components/ui/marker.d.ts +54 -0
  163. package/dist/components/ui/marker.d.ts.map +1 -0
  164. package/dist/components/ui/marker.js +79 -0
  165. package/dist/components/ui/marker.js.map +1 -0
  166. package/dist/components/ui/menubar.d.ts +72 -0
  167. package/dist/components/ui/menubar.d.ts.map +1 -0
  168. package/dist/components/ui/menubar.js +174 -0
  169. package/dist/components/ui/menubar.js.map +1 -0
  170. package/dist/components/ui/message-scroller.d.ts +53 -0
  171. package/dist/components/ui/message-scroller.d.ts.map +1 -0
  172. package/dist/components/ui/message-scroller.js +95 -0
  173. package/dist/components/ui/message-scroller.js.map +1 -0
  174. package/dist/components/ui/message.d.ts +63 -0
  175. package/dist/components/ui/message.d.ts.map +1 -0
  176. package/dist/components/ui/message.js +92 -0
  177. package/dist/components/ui/message.js.map +1 -0
  178. package/dist/components/ui/meta-list.d.ts +55 -0
  179. package/dist/components/ui/meta-list.d.ts.map +1 -0
  180. package/dist/components/ui/meta-list.js +75 -0
  181. package/dist/components/ui/meta-list.js.map +1 -0
  182. package/dist/components/ui/native-select.d.ts +51 -0
  183. package/dist/components/ui/native-select.d.ts.map +1 -0
  184. package/dist/components/ui/native-select.js +75 -0
  185. package/dist/components/ui/native-select.js.map +1 -0
  186. package/dist/components/ui/navigation-menu.d.ts +56 -0
  187. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  188. package/dist/components/ui/navigation-menu.js +116 -0
  189. package/dist/components/ui/navigation-menu.js.map +1 -0
  190. package/dist/components/ui/page-header.d.ts +223 -0
  191. package/dist/components/ui/page-header.d.ts.map +1 -0
  192. package/dist/components/ui/page-header.js +233 -0
  193. package/dist/components/ui/page-header.js.map +1 -0
  194. package/dist/components/ui/pagination.d.ts +68 -0
  195. package/dist/components/ui/pagination.d.ts.map +1 -0
  196. package/dist/components/ui/pagination.js +145 -0
  197. package/dist/components/ui/pagination.js.map +1 -0
  198. package/dist/components/ui/popover.d.ts +61 -0
  199. package/dist/components/ui/popover.d.ts.map +1 -0
  200. package/dist/components/ui/popover.js +144 -0
  201. package/dist/components/ui/popover.js.map +1 -0
  202. package/dist/components/ui/progress.d.ts +35 -0
  203. package/dist/components/ui/progress.d.ts.map +1 -0
  204. package/dist/components/ui/progress.js +46 -0
  205. package/dist/components/ui/progress.js.map +1 -0
  206. package/dist/components/ui/questionnaire.d.ts +92 -0
  207. package/dist/components/ui/questionnaire.d.ts.map +1 -0
  208. package/dist/components/ui/questionnaire.js +277 -0
  209. package/dist/components/ui/questionnaire.js.map +1 -0
  210. package/dist/components/ui/radio-group.d.ts +50 -0
  211. package/dist/components/ui/radio-group.d.ts.map +1 -0
  212. package/dist/components/ui/radio-group.js +65 -0
  213. package/dist/components/ui/radio-group.js.map +1 -0
  214. package/dist/components/ui/resizable.d.ts +44 -0
  215. package/dist/components/ui/resizable.d.ts.map +1 -0
  216. package/dist/components/ui/resizable.js +73 -0
  217. package/dist/components/ui/resizable.js.map +1 -0
  218. package/dist/components/ui/scroll-area.d.ts +55 -0
  219. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  220. package/dist/components/ui/scroll-area.js +72 -0
  221. package/dist/components/ui/scroll-area.js.map +1 -0
  222. package/dist/components/ui/select.d.ts +274 -0
  223. package/dist/components/ui/select.d.ts.map +1 -0
  224. package/dist/components/ui/select.js +609 -0
  225. package/dist/components/ui/select.js.map +1 -0
  226. package/dist/components/ui/separator.d.ts +31 -0
  227. package/dist/components/ui/separator.d.ts.map +1 -0
  228. package/dist/components/ui/separator.js +38 -0
  229. package/dist/components/ui/separator.js.map +1 -0
  230. package/dist/components/ui/sheet.d.ts +59 -0
  231. package/dist/components/ui/sheet.d.ts.map +1 -0
  232. package/dist/components/ui/sheet.js +128 -0
  233. package/dist/components/ui/sheet.js.map +1 -0
  234. package/dist/components/ui/sidebar.d.ts +166 -0
  235. package/dist/components/ui/sidebar.d.ts.map +1 -0
  236. package/dist/components/ui/sidebar.js +512 -0
  237. package/dist/components/ui/sidebar.js.map +1 -0
  238. package/dist/components/ui/skeleton.d.ts +35 -0
  239. package/dist/components/ui/skeleton.d.ts.map +1 -0
  240. package/dist/components/ui/skeleton.js +46 -0
  241. package/dist/components/ui/skeleton.js.map +1 -0
  242. package/dist/components/ui/slider.d.ts +39 -0
  243. package/dist/components/ui/slider.d.ts.map +1 -0
  244. package/dist/components/ui/slider.js +75 -0
  245. package/dist/components/ui/slider.js.map +1 -0
  246. package/dist/components/ui/sonner.d.ts +56 -0
  247. package/dist/components/ui/sonner.d.ts.map +1 -0
  248. package/dist/components/ui/sonner.js +96 -0
  249. package/dist/components/ui/sonner.js.map +1 -0
  250. package/dist/components/ui/spinner.d.ts +37 -0
  251. package/dist/components/ui/spinner.d.ts.map +1 -0
  252. package/dist/components/ui/spinner.js +51 -0
  253. package/dist/components/ui/spinner.js.map +1 -0
  254. package/dist/components/ui/stepper.d.ts +84 -0
  255. package/dist/components/ui/stepper.d.ts.map +1 -0
  256. package/dist/components/ui/stepper.js +145 -0
  257. package/dist/components/ui/stepper.js.map +1 -0
  258. package/dist/components/ui/switch.d.ts +36 -0
  259. package/dist/components/ui/switch.d.ts.map +1 -0
  260. package/dist/components/ui/switch.js +44 -0
  261. package/dist/components/ui/switch.js.map +1 -0
  262. package/dist/components/ui/table.d.ts +80 -0
  263. package/dist/components/ui/table.d.ts.map +1 -0
  264. package/dist/components/ui/table.js +130 -0
  265. package/dist/components/ui/table.js.map +1 -0
  266. package/dist/components/ui/tabs.d.ts +87 -0
  267. package/dist/components/ui/tabs.d.ts.map +1 -0
  268. package/dist/components/ui/tabs.js +128 -0
  269. package/dist/components/ui/tabs.js.map +1 -0
  270. package/dist/components/ui/textarea.d.ts +35 -0
  271. package/dist/components/ui/textarea.d.ts.map +1 -0
  272. package/dist/components/ui/textarea.js +38 -0
  273. package/dist/components/ui/textarea.js.map +1 -0
  274. package/dist/components/ui/time-picker.d.ts +58 -0
  275. package/dist/components/ui/time-picker.d.ts.map +1 -0
  276. package/dist/components/ui/time-picker.js +188 -0
  277. package/dist/components/ui/time-picker.js.map +1 -0
  278. package/dist/components/ui/toggle-group.d.ts +52 -0
  279. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  280. package/dist/components/ui/toggle-group.js +94 -0
  281. package/dist/components/ui/toggle-group.js.map +1 -0
  282. package/dist/components/ui/toggle.d.ts +50 -0
  283. package/dist/components/ui/toggle.d.ts.map +1 -0
  284. package/dist/components/ui/toggle.js +70 -0
  285. package/dist/components/ui/toggle.js.map +1 -0
  286. package/dist/components/ui/tooltip.d.ts +51 -0
  287. package/dist/components/ui/tooltip.d.ts.map +1 -0
  288. package/dist/components/ui/tooltip.js +78 -0
  289. package/dist/components/ui/tooltip.js.map +1 -0
  290. package/dist/hooks/use-dark-mode.d.ts +2 -0
  291. package/dist/hooks/use-dark-mode.d.ts.map +1 -0
  292. package/dist/hooks/use-dark-mode.js +36 -0
  293. package/dist/hooks/use-dark-mode.js.map +1 -0
  294. package/dist/hooks/use-mobile.d.ts +2 -0
  295. package/dist/hooks/use-mobile.d.ts.map +1 -0
  296. package/dist/hooks/use-mobile.js +20 -0
  297. package/dist/hooks/use-mobile.js.map +1 -0
  298. package/dist/index.d.ts +88 -0
  299. package/dist/index.d.ts.map +1 -0
  300. package/dist/index.js +77 -0
  301. package/dist/lib/scope.d.ts +64 -0
  302. package/dist/lib/scope.d.ts.map +1 -0
  303. package/dist/lib/scope.js +74 -0
  304. package/dist/lib/scope.js.map +1 -0
  305. package/dist/lib/utils.d.ts +3 -0
  306. package/dist/lib/utils.d.ts.map +1 -0
  307. package/dist/lib/utils.js +11 -0
  308. package/dist/lib/utils.js.map +1 -0
  309. package/dist/styles.css +2 -0
  310. package/dist/theme-tokens.css +537 -0
  311. package/dist/theme.css +417 -0
  312. package/package.json +103 -3
@@ -0,0 +1,512 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { useIsMobile } from "../../hooks/use-mobile.js";
3
+ import { Button } from "./button.js";
4
+ import { Input } from "./input.js";
5
+ import { Tooltip as Tooltip$1, TooltipContent, TooltipTrigger } from "./tooltip.js";
6
+ import { Separator as Separator$1 } from "./separator.js";
7
+ import { Collapsible as Collapsible$1, CollapsibleContent, CollapsibleTrigger } from "./collapsible.js";
8
+ import { Skeleton } from "./skeleton.js";
9
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "./sheet.js";
10
+ import * as React from "react";
11
+ import { Slot } from "radix-ui";
12
+ import { ChevronDownIcon, PanelLeftIcon } from "lucide-react";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ import { cva } from "class-variance-authority";
15
+ //#region src/components/ui/sidebar.tsx
16
+ /**
17
+ * Sidebar — full application side-navigation shell.
18
+ *
19
+ * Includes SidebarMenuCollapsible, an animated, disclosable nav "folder"
20
+ * that pairs SidebarMenuButton with Collapsible (see its own doc comment above
21
+ * its definition). Composed from many sub-exports; see the WHEN TO USE /
22
+ * KEY RULES block at the end of this file for the family as a whole.
23
+ */
24
+ var SIDEBAR_COOKIE_NAME = "sidebar_state";
25
+ var SIDEBAR_COOKIE_MAX_AGE = 604800;
26
+ var SIDEBAR_WIDTH = "16rem";
27
+ var SIDEBAR_WIDTH_MOBILE = "18rem";
28
+ var SIDEBAR_WIDTH_ICON = "3rem";
29
+ var SIDEBAR_KEYBOARD_SHORTCUT = "b";
30
+ var SidebarContext = React.createContext(null);
31
+ function useSidebar() {
32
+ const context = React.useContext(SidebarContext);
33
+ if (!context) throw new Error("useSidebar must be used within a SidebarProvider.");
34
+ return context;
35
+ }
36
+ function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }) {
37
+ const isMobile = useIsMobile();
38
+ const [openMobile, setOpenMobile] = React.useState(false);
39
+ const contentId = React.useId();
40
+ const [_open, _setOpen] = React.useState(defaultOpen);
41
+ const open = openProp ?? _open;
42
+ const setOpen = React.useCallback((value) => {
43
+ const openState = typeof value === "function" ? value(open) : value;
44
+ if (setOpenProp) setOpenProp(openState);
45
+ else _setOpen(openState);
46
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
47
+ }, [setOpenProp, open]);
48
+ const toggleSidebar = React.useCallback(() => {
49
+ return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
50
+ }, [
51
+ isMobile,
52
+ setOpen,
53
+ setOpenMobile
54
+ ]);
55
+ React.useEffect(() => {
56
+ const handleKeyDown = (event) => {
57
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
58
+ event.preventDefault();
59
+ toggleSidebar();
60
+ }
61
+ };
62
+ window.addEventListener("keydown", handleKeyDown);
63
+ return () => window.removeEventListener("keydown", handleKeyDown);
64
+ }, [toggleSidebar]);
65
+ const state = open ? "expanded" : "collapsed";
66
+ const contextValue = React.useMemo(() => ({
67
+ state,
68
+ open,
69
+ setOpen,
70
+ isMobile,
71
+ openMobile,
72
+ setOpenMobile,
73
+ toggleSidebar,
74
+ contentId
75
+ }), [
76
+ state,
77
+ open,
78
+ setOpen,
79
+ isMobile,
80
+ openMobile,
81
+ setOpenMobile,
82
+ toggleSidebar,
83
+ contentId
84
+ ]);
85
+ return /* @__PURE__ */ jsx(SidebarContext.Provider, {
86
+ value: contextValue,
87
+ children: /* @__PURE__ */ jsx("div", {
88
+ "data-slot": "sidebar-wrapper",
89
+ style: {
90
+ "--sidebar-width": SIDEBAR_WIDTH,
91
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
92
+ ...style
93
+ },
94
+ className: cn("group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className),
95
+ ...props,
96
+ children
97
+ })
98
+ });
99
+ }
100
+ function Sidebar({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, dir, ...props }) {
101
+ const { isMobile, state, openMobile, setOpenMobile, contentId } = useSidebar();
102
+ if (collapsible === "none") return /* @__PURE__ */ jsx("div", {
103
+ id: contentId,
104
+ "data-slot": "sidebar",
105
+ className: cn("flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground", className),
106
+ ...props,
107
+ children
108
+ });
109
+ if (isMobile) return /* @__PURE__ */ jsx(Sheet, {
110
+ open: openMobile,
111
+ onOpenChange: setOpenMobile,
112
+ ...props,
113
+ children: /* @__PURE__ */ jsxs(SheetContent, {
114
+ id: contentId,
115
+ dir,
116
+ "data-sidebar": "sidebar",
117
+ "data-slot": "sidebar",
118
+ "data-mobile": "true",
119
+ className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
120
+ style: { "--sidebar-width": SIDEBAR_WIDTH_MOBILE },
121
+ side,
122
+ children: [/* @__PURE__ */ jsxs(SheetHeader, {
123
+ className: "sr-only",
124
+ children: [/* @__PURE__ */ jsx(SheetTitle, { children: "Sidebar" }), /* @__PURE__ */ jsx(SheetDescription, { children: "Displays the mobile sidebar." })]
125
+ }), /* @__PURE__ */ jsx("div", {
126
+ className: "flex h-full w-full flex-col",
127
+ children
128
+ })]
129
+ })
130
+ });
131
+ return /* @__PURE__ */ jsxs("div", {
132
+ className: "group peer hidden text-sidebar-foreground md:block",
133
+ "data-state": state,
134
+ "data-collapsible": state === "collapsed" ? collapsible : "",
135
+ "data-variant": variant,
136
+ "data-side": side,
137
+ "data-slot": "sidebar",
138
+ children: [/* @__PURE__ */ jsx("div", {
139
+ "data-slot": "sidebar-gap",
140
+ className: cn("relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear", "group-data-[collapsible=offcanvas]:w-0", "group-data-[side=right]:rotate-180", variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)")
141
+ }), /* @__PURE__ */ jsx("div", {
142
+ id: contentId,
143
+ "data-slot": "sidebar-container",
144
+ "data-side": side,
145
+ inert: collapsible === "offcanvas" && state === "collapsed",
146
+ className: cn("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-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex", variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", className),
147
+ ...props,
148
+ children: /* @__PURE__ */ jsx("div", {
149
+ "data-sidebar": "sidebar",
150
+ "data-slot": "sidebar-inner",
151
+ className: "flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-xl group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border",
152
+ children
153
+ })
154
+ })]
155
+ });
156
+ }
157
+ function SidebarTrigger({ className, onClick, ...props }) {
158
+ const { toggleSidebar, state, contentId } = useSidebar();
159
+ return /* @__PURE__ */ jsxs(Button, {
160
+ "data-sidebar": "trigger",
161
+ "data-slot": "sidebar-trigger",
162
+ variant: "ghost",
163
+ size: "sm",
164
+ iconOnly: true,
165
+ "aria-label": "Toggle Sidebar",
166
+ "aria-expanded": state === "expanded",
167
+ "aria-controls": contentId,
168
+ className: cn(className),
169
+ onClick: (event) => {
170
+ onClick?.(event);
171
+ toggleSidebar();
172
+ },
173
+ ...props,
174
+ children: [/* @__PURE__ */ jsx(PanelLeftIcon, {}), /* @__PURE__ */ jsx("span", {
175
+ className: "sr-only",
176
+ children: "Toggle Sidebar"
177
+ })]
178
+ });
179
+ }
180
+ function SidebarRail({ className, ...props }) {
181
+ const { toggleSidebar } = useSidebar();
182
+ return /* @__PURE__ */ jsx("button", {
183
+ "data-sidebar": "rail",
184
+ "data-slot": "sidebar-rail",
185
+ "aria-label": "Toggle Sidebar",
186
+ tabIndex: -1,
187
+ onClick: toggleSidebar,
188
+ title: "Toggle Sidebar",
189
+ className: cn("absolute inset-y-0 z-20 hidden w-4 transition-colors ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2", "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar", "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", className),
190
+ ...props
191
+ });
192
+ }
193
+ function SidebarInset({ className, ...props }) {
194
+ return /* @__PURE__ */ jsx("main", {
195
+ "data-slot": "sidebar-inset",
196
+ className: cn("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", className),
197
+ ...props
198
+ });
199
+ }
200
+ function SidebarInput({ className, ...props }) {
201
+ return /* @__PURE__ */ jsx(Input, {
202
+ "data-slot": "sidebar-input",
203
+ "data-sidebar": "input",
204
+ className: cn("h-8 w-full bg-background shadow-none", className),
205
+ ...props
206
+ });
207
+ }
208
+ function SidebarHeader({ className, ...props }) {
209
+ return /* @__PURE__ */ jsx("div", {
210
+ "data-slot": "sidebar-header",
211
+ "data-sidebar": "header",
212
+ className: cn("flex flex-col gap-2 p-2", className),
213
+ ...props
214
+ });
215
+ }
216
+ function SidebarFooter({ className, ...props }) {
217
+ return /* @__PURE__ */ jsx("div", {
218
+ "data-slot": "sidebar-footer",
219
+ "data-sidebar": "footer",
220
+ className: cn("flex flex-col gap-2 p-2", className),
221
+ ...props
222
+ });
223
+ }
224
+ function SidebarSeparator({ className, ...props }) {
225
+ return /* @__PURE__ */ jsx(Separator$1, {
226
+ "data-slot": "sidebar-separator",
227
+ "data-sidebar": "separator",
228
+ className: cn("mx-2 w-auto bg-sidebar-border", className),
229
+ ...props
230
+ });
231
+ }
232
+ function SidebarContent({ className, ...props }) {
233
+ return /* @__PURE__ */ jsx("div", {
234
+ "data-slot": "sidebar-content",
235
+ "data-sidebar": "content",
236
+ className: cn("no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden", className),
237
+ ...props
238
+ });
239
+ }
240
+ function SidebarGroup({ className, ...props }) {
241
+ return /* @__PURE__ */ jsx("div", {
242
+ "data-slot": "sidebar-group",
243
+ "data-sidebar": "group",
244
+ className: cn("relative flex w-full min-w-0 flex-col p-2", className),
245
+ ...props
246
+ });
247
+ }
248
+ function SidebarGroupLabel({ className, asChild = false, ...props }) {
249
+ const Comp = asChild ? Slot.Root : "div";
250
+ return /* @__PURE__ */ jsx(Comp, {
251
+ "data-slot": "sidebar-group-label",
252
+ "data-sidebar": "group-label",
253
+ className: cn("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", className),
254
+ ...props
255
+ });
256
+ }
257
+ function SidebarGroupAction({ className, asChild = false, ...props }) {
258
+ const Comp = asChild ? Slot.Root : "button";
259
+ return /* @__PURE__ */ jsx(Comp, {
260
+ "data-slot": "sidebar-group-action",
261
+ "data-sidebar": "group-action",
262
+ className: cn("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", className),
263
+ ...props
264
+ });
265
+ }
266
+ function SidebarGroupContent({ className, ...props }) {
267
+ return /* @__PURE__ */ jsx("div", {
268
+ "data-slot": "sidebar-group-content",
269
+ "data-sidebar": "group-content",
270
+ className: cn("w-full text-sm", className),
271
+ ...props
272
+ });
273
+ }
274
+ function SidebarMenu({ className, ...props }) {
275
+ return /* @__PURE__ */ jsx("ul", {
276
+ "data-slot": "sidebar-menu",
277
+ "data-sidebar": "menu",
278
+ className: cn("flex w-full min-w-0 flex-col gap-0", className),
279
+ ...props
280
+ });
281
+ }
282
+ function SidebarMenuItem({ className, ...props }) {
283
+ return /* @__PURE__ */ jsx("li", {
284
+ "data-slot": "sidebar-menu-item",
285
+ "data-sidebar": "menu-item",
286
+ className: cn("group/menu-item relative", className),
287
+ ...props
288
+ });
289
+ }
290
+ var sidebarMenuButtonVariants = cva("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-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate", {
291
+ variants: {
292
+ variant: {
293
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
294
+ outline: "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)]"
295
+ },
296
+ size: {
297
+ default: "h-8 text-sm",
298
+ sm: "h-7 text-xs",
299
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
300
+ }
301
+ },
302
+ defaultVariants: {
303
+ variant: "default",
304
+ size: "default"
305
+ }
306
+ });
307
+ function SidebarMenuButton({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, ...props }) {
308
+ const Comp = asChild ? Slot.Root : "button";
309
+ const { isMobile, state } = useSidebar();
310
+ const button = /* @__PURE__ */ jsx(Comp, {
311
+ "data-slot": "sidebar-menu-button",
312
+ "data-sidebar": "menu-button",
313
+ "data-size": size,
314
+ "data-active": isActive,
315
+ "aria-current": isActive ? "page" : void 0,
316
+ className: cn(sidebarMenuButtonVariants({
317
+ variant,
318
+ size
319
+ }), className),
320
+ ...props
321
+ });
322
+ if (!tooltip) return button;
323
+ if (typeof tooltip === "string") tooltip = { children: tooltip };
324
+ return /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
325
+ asChild: true,
326
+ children: button
327
+ }), /* @__PURE__ */ jsx(TooltipContent, {
328
+ side: "right",
329
+ align: "center",
330
+ hidden: state !== "collapsed" || isMobile,
331
+ ...tooltip
332
+ })] });
333
+ }
334
+ function SidebarMenuAction({ className, asChild = false, showOnHover = false, ...props }) {
335
+ const Comp = asChild ? Slot.Root : "button";
336
+ return /* @__PURE__ */ jsx(Comp, {
337
+ "data-slot": "sidebar-menu-action",
338
+ "data-sidebar": "menu-action",
339
+ className: cn("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", showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-primary aria-expanded:opacity-100 md:opacity-0", className),
340
+ ...props
341
+ });
342
+ }
343
+ function SidebarMenuBadge({ className, ...props }) {
344
+ return /* @__PURE__ */ jsx("div", {
345
+ "data-slot": "sidebar-menu-badge",
346
+ "data-sidebar": "menu-badge",
347
+ className: cn("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-[active=true]/menu-button:text-sidebar-primary 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", className),
348
+ ...props
349
+ });
350
+ }
351
+ function SidebarMenuSkeleton({ className, showIcon = false, ...props }) {
352
+ const [width] = React.useState(() => {
353
+ return `${Math.floor(Math.random() * 40) + 50}%`;
354
+ });
355
+ return /* @__PURE__ */ jsxs("div", {
356
+ "data-slot": "sidebar-menu-skeleton",
357
+ "data-sidebar": "menu-skeleton",
358
+ className: cn("flex h-8 items-center gap-2 rounded-md px-2", className),
359
+ ...props,
360
+ children: [showIcon && /* @__PURE__ */ jsx(Skeleton, {
361
+ className: "size-4 rounded-md",
362
+ "data-sidebar": "menu-skeleton-icon"
363
+ }), /* @__PURE__ */ jsx(Skeleton, {
364
+ className: "h-4 max-w-(--skeleton-width) flex-1",
365
+ "data-sidebar": "menu-skeleton-text",
366
+ style: { "--skeleton-width": width }
367
+ })]
368
+ });
369
+ }
370
+ function SidebarMenuSub({ className, ...props }) {
371
+ return /* @__PURE__ */ jsx("ul", {
372
+ "data-slot": "sidebar-menu-sub",
373
+ "data-sidebar": "menu-sub",
374
+ className: cn("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", className),
375
+ ...props
376
+ });
377
+ }
378
+ function SidebarMenuSubItem({ className, ...props }) {
379
+ return /* @__PURE__ */ jsx("li", {
380
+ "data-slot": "sidebar-menu-sub-item",
381
+ "data-sidebar": "menu-sub-item",
382
+ className: cn("group/menu-sub-item relative", className),
383
+ ...props
384
+ });
385
+ }
386
+ function SidebarMenuSubButton({ asChild = false, size = "md", isActive = false, className, ...props }) {
387
+ const Comp = asChild ? Slot.Root : "a";
388
+ return /* @__PURE__ */ jsx(Comp, {
389
+ "data-slot": "sidebar-menu-sub-button",
390
+ "data-sidebar": "menu-sub-button",
391
+ "data-size": size,
392
+ "data-active": isActive,
393
+ "aria-current": isActive ? "page" : void 0,
394
+ className: cn("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-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[size=md]:text-sm data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", className),
395
+ ...props
396
+ });
397
+ }
398
+ /**
399
+ * A SidebarMenuButton that discloses a set of child rows underneath it
400
+ * instead of navigating — a "folder" of related destinations in the rail.
401
+ *
402
+ * SidebarMenuSub is a static indented list with no disclosure state of its
403
+ * own; this pairs it with Collapsible so opening/closing actually animates,
404
+ * and flattens the indent to 0 once the sidebar collapses to icon-only
405
+ * (`group-data-[collapsible=icon]`), matching how every other menu row in
406
+ * this family already collapses.
407
+ *
408
+ * `open`/`onOpenChange` are owned by the caller, same as SidebarMenuButton's
409
+ * `isActive` — this component holds no state of its own, so multiple
410
+ * instances of the same rail (e.g. a docked sidebar and its own hover
411
+ * overlay) can share one open/closed answer instead of disagreeing.
412
+ */
413
+ function SidebarMenuCollapsible({ icon, label, children, open, onOpenChange, isActive = false, className, ...props }) {
414
+ return /* @__PURE__ */ jsxs(Collapsible$1, {
415
+ open,
416
+ onOpenChange,
417
+ children: [/* @__PURE__ */ jsx(CollapsibleTrigger, {
418
+ asChild: true,
419
+ children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
420
+ "data-slot": "sidebar-menu-collapsible-trigger",
421
+ isActive,
422
+ className: cn(!isActive && "bg-transparent", className),
423
+ ...props,
424
+ children: [
425
+ icon,
426
+ /* @__PURE__ */ jsx("span", {
427
+ className: "min-w-0 flex-1 truncate",
428
+ children: label
429
+ }),
430
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("shrink-0 text-sidebar-foreground/70 transition-transform duration-150", open && "rotate-180") })
431
+ ]
432
+ })
433
+ }), /* @__PURE__ */ jsx(CollapsibleContent, {
434
+ forceMount: true,
435
+ "data-slot": "sidebar-menu-collapsible-content",
436
+ className: cn("grid ease-out", open ? "visible grid-rows-[1fr] opacity-100 transition-opacity duration-150" : "invisible grid-rows-[0fr] opacity-0 transition-[grid-template-rows,opacity,visibility] duration-200"),
437
+ children: /* @__PURE__ */ jsx("div", {
438
+ className: "overflow-hidden",
439
+ children: /* @__PURE__ */ jsx("div", {
440
+ className: "mt-0.5 flex flex-col gap-0.5 pl-7 transition-[padding-left] duration-200 ease-linear group-data-[collapsible=icon]:pl-0",
441
+ children
442
+ })
443
+ })
444
+ })]
445
+ });
446
+ }
447
+ /**
448
+ * WHEN TO USE
449
+ * - Persistent primary navigation in an app-shell layout — the main way
450
+ * users move between top-level sections of the product.
451
+ *
452
+ * NOT WHEN
453
+ * - A temporary/dismissible panel — use Sheet (Sidebar itself renders as a
454
+ * Sheet on mobile automatically, but don't reach for Sidebar to build a
455
+ * one-off drawer).
456
+ * - Top-bar navigation — use NavigationMenu.
457
+ * - A plain, non-collapsible list with no app-shell chrome — use Item.
458
+ *
459
+ * KEY RULES
460
+ * - Requires SidebarProvider wrapping both the Sidebar and the SidebarInset
461
+ * content — it owns the open/collapsed state via context (`useSidebar`);
462
+ * Sidebar and SidebarInset don't work standalone.
463
+ * - `side`: "left" | "right". `variant`: "sidebar" (flush) | "floating"
464
+ * (rounded, ringed) | "inset" (content insets around it). `collapsible`:
465
+ * "offcanvas" (slides fully away) | "icon" (shrinks to icon rail) | "none"
466
+ * (always expanded, no collapse control).
467
+ * - Below the `md` breakpoint the sidebar always renders as a Sheet
468
+ * regardless of `collapsible`, via `useIsMobile` — don't special-case
469
+ * mobile yourself.
470
+ * - SidebarMenuButton's `isActive` and SidebarMenuCollapsible's `open` are
471
+ * both caller-owned — this file holds no "current route" state.
472
+ * - SidebarMenuSub is a static indented list; SidebarMenuCollapsible is the
473
+ * version with its own open/close disclosure and icon-collapse indent
474
+ * flattening — don't use Sub when you need a toggleable "folder".
475
+ * - Cmd/Ctrl+B toggles the sidebar globally (wired inside SidebarProvider).
476
+ *
477
+ * USAGE
478
+ * <SidebarProvider>
479
+ * <Sidebar>
480
+ * <SidebarHeader>...</SidebarHeader>
481
+ * <SidebarContent>
482
+ * <SidebarGroup>
483
+ * <SidebarGroupLabel>Platform</SidebarGroupLabel>
484
+ * <SidebarGroupContent>
485
+ * <SidebarMenu>
486
+ * <SidebarMenuItem>
487
+ * <SidebarMenuButton isActive>
488
+ * <HomeIcon />Overview
489
+ * </SidebarMenuButton>
490
+ * </SidebarMenuItem>
491
+ * <SidebarMenuItem>
492
+ * <SidebarMenuCollapsible
493
+ * icon={<FolderIcon />}
494
+ * label="Analytics"
495
+ * open={open}
496
+ * onOpenChange={setOpen}
497
+ * >
498
+ * <SidebarMenuButton><BarChartIcon />Cohort Builder</SidebarMenuButton>
499
+ * </SidebarMenuCollapsible>
500
+ * </SidebarMenuItem>
501
+ * </SidebarMenu>
502
+ * </SidebarGroupContent>
503
+ * </SidebarGroup>
504
+ * </SidebarContent>
505
+ * </Sidebar>
506
+ * <SidebarInset>{"<page content>"}</SidebarInset>
507
+ * </SidebarProvider>
508
+ */
509
+ //#endregion
510
+ export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuCollapsible, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar };
511
+
512
+ //# sourceMappingURL=sidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar.js","names":[],"sources":["../../../src/components/ui/sidebar.tsx"],"sourcesContent":["/**\n * Sidebar — full application side-navigation shell.\n *\n * Includes SidebarMenuCollapsible, an animated, disclosable nav \"folder\"\n * that pairs SidebarMenuButton with Collapsible (see its own doc comment above\n * its definition). Composed from many sub-exports; see the WHEN TO USE /\n * KEY RULES block at the end of this file for the family as a whole.\n */\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { useIsMobile } from \"@/hooks/use-mobile\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { Input } from \"@/components/ui/input\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"@/components/ui/sheet\"\nimport { Skeleton } from \"@/components/ui/skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { ChevronDownIcon, PanelLeftIcon } from \"lucide-react\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n /** Shared with `Sidebar` (as its panel `id`) and `SidebarTrigger` (as `aria-controls`) so the trigger's open/closed toggle button points at a real target instead of just changing state with no reachable relationship. */\n contentId: string\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n const contentId = React.useId()\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n contentId,\n }),\n [\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n contentId,\n ]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n dir,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, openMobile, setOpenMobile, contentId } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n id={contentId}\n data-slot=\"sidebar\"\n className={cn(\n \"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n id={contentId}\n dir={dir}\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer hidden text-sidebar-foreground md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n id={contentId}\n data-slot=\"sidebar-container\"\n data-side={side}\n // Offcanvas collapse only ever moves this box off-screen via\n // `left`/`right` — a transform, not `display`/`aria-hidden` — so\n // without `inert` its contents stayed in the tab order and\n // accessibility tree while invisible: keyboard/AT users could tab\n // into and activate controls they can't see. `inert` removes both\n // at once (focusability and AT exposure) without touching the\n // transition itself. Only applies to the collapse mode that's\n // actually invisible when collapsed — \"icon\" mode stays visible\n // (shrunk, not hidden), so its content correctly stays reachable.\n inert={collapsible === \"offcanvas\" && state === \"collapsed\"}\n className={cn(\n \"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-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-xl group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: Omit<\n React.ComponentProps<typeof Button>,\n \"size\" | \"iconOnly\" | \"asChild\" | \"aria-label\" | \"variant\"\n>) {\n const { toggleSidebar, state, contentId } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"sm\"\n iconOnly\n aria-label=\"Toggle Sidebar\"\n // Static label + no other state cue meant this button never told AT\n // whether activating it would open or close the panel, unlike every\n // other disclosure trigger in this library.\n aria-expanded={state === \"expanded\"}\n aria-controls={contentId}\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"absolute inset-y-0 z-20 hidden w-4 transition-colors ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"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\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"h-8 w-full bg-background shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"mx-2 w-auto bg-sidebar-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"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\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"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\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-0\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n // data-[state=open]: covers `asChild` wrapping a Radix trigger (a\n // DropdownMenuTrigger/CollapsibleTrigger) that sets its own real\n // data-state on this exact node — not a literal data-open this button\n // ever sets itself.\n \"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-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"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)]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot.Root : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n // data-active alone is a CSS hook — nothing AT-facing conveyed \"this\n // is the current page\" beyond color/weight. aria-current is the\n // actual state attribute; \"page\" fits this row's usual role (a nav\n // destination link), not \"true\", since these usually render as/wrap\n // a real page link via asChild.\n aria-current={isActive ? \"page\" : undefined}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"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\",\n showOnHover &&\n \"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-primary aria-expanded:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"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-[active=true]/menu-button:text-sidebar-primary 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\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const [width] = React.useState(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n })\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"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\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot.Root : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n \"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-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[size=md]:text-sm data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n className\n )}\n {...props}\n />\n )\n}\n\n/**\n * A SidebarMenuButton that discloses a set of child rows underneath it\n * instead of navigating — a \"folder\" of related destinations in the rail.\n *\n * SidebarMenuSub is a static indented list with no disclosure state of its\n * own; this pairs it with Collapsible so opening/closing actually animates,\n * and flattens the indent to 0 once the sidebar collapses to icon-only\n * (`group-data-[collapsible=icon]`), matching how every other menu row in\n * this family already collapses.\n *\n * `open`/`onOpenChange` are owned by the caller, same as SidebarMenuButton's\n * `isActive` — this component holds no state of its own, so multiple\n * instances of the same rail (e.g. a docked sidebar and its own hover\n * overlay) can share one open/closed answer instead of disagreeing.\n */\nfunction SidebarMenuCollapsible({\n icon,\n label,\n children,\n open,\n onOpenChange,\n isActive = false,\n className,\n ...props\n}: Omit<React.ComponentProps<typeof SidebarMenuButton>, \"children\"> & {\n icon?: React.ReactNode\n /** The trigger row's own text — distinct from `children`, which is the disclosed row list. */\n label: React.ReactNode\n /** Child rows, revealed when open. */\n children: React.ReactNode\n open: boolean\n onOpenChange: (open: boolean) => void\n}) {\n return (\n <Collapsible open={open} onOpenChange={onOpenChange}>\n <CollapsibleTrigger asChild>\n <SidebarMenuButton\n data-slot=\"sidebar-menu-collapsible-trigger\"\n isActive={isActive}\n className={cn(!isActive && \"bg-transparent\", className)}\n {...props}\n >\n {icon}\n <span className=\"min-w-0 flex-1 truncate\">{label}</span>\n <ChevronDownIcon\n className={cn(\n \"shrink-0 text-sidebar-foreground/70 transition-transform duration-150\",\n open && \"rotate-180\"\n )}\n />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n {/* forceMount keeps this mounted through the collapse so the close\n direction animates too, instead of being ripped out of the DOM the\n instant it closes. Opening only transitions opacity (the height\n lands immediately, rows fade up); closing also transitions the grid\n track, since an instant height change on that side reads as a\n jerk. */}\n <CollapsibleContent\n forceMount\n data-slot=\"sidebar-menu-collapsible-content\"\n className={cn(\n \"grid ease-out\",\n open\n ? \"visible grid-rows-[1fr] opacity-100 transition-opacity duration-150\"\n : \"invisible grid-rows-[0fr] opacity-0 transition-[grid-template-rows,opacity,visibility] duration-200\"\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"mt-0.5 flex flex-col gap-0.5 pl-7 transition-[padding-left] duration-200 ease-linear group-data-[collapsible=icon]:pl-0\">\n {children}\n </div>\n </div>\n </CollapsibleContent>\n </Collapsible>\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuCollapsible,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n\n/**\n * WHEN TO USE\n * - Persistent primary navigation in an app-shell layout — the main way\n * users move between top-level sections of the product.\n *\n * NOT WHEN\n * - A temporary/dismissible panel — use Sheet (Sidebar itself renders as a\n * Sheet on mobile automatically, but don't reach for Sidebar to build a\n * one-off drawer).\n * - Top-bar navigation — use NavigationMenu.\n * - A plain, non-collapsible list with no app-shell chrome — use Item.\n *\n * KEY RULES\n * - Requires SidebarProvider wrapping both the Sidebar and the SidebarInset\n * content — it owns the open/collapsed state via context (`useSidebar`);\n * Sidebar and SidebarInset don't work standalone.\n * - `side`: \"left\" | \"right\". `variant`: \"sidebar\" (flush) | \"floating\"\n * (rounded, ringed) | \"inset\" (content insets around it). `collapsible`:\n * \"offcanvas\" (slides fully away) | \"icon\" (shrinks to icon rail) | \"none\"\n * (always expanded, no collapse control).\n * - Below the `md` breakpoint the sidebar always renders as a Sheet\n * regardless of `collapsible`, via `useIsMobile` — don't special-case\n * mobile yourself.\n * - SidebarMenuButton's `isActive` and SidebarMenuCollapsible's `open` are\n * both caller-owned — this file holds no \"current route\" state.\n * - SidebarMenuSub is a static indented list; SidebarMenuCollapsible is the\n * version with its own open/close disclosure and icon-collapse indent\n * flattening — don't use Sub when you need a toggleable \"folder\".\n * - Cmd/Ctrl+B toggles the sidebar globally (wired inside SidebarProvider).\n *\n * USAGE\n * <SidebarProvider>\n * <Sidebar>\n * <SidebarHeader>...</SidebarHeader>\n * <SidebarContent>\n * <SidebarGroup>\n * <SidebarGroupLabel>Platform</SidebarGroupLabel>\n * <SidebarGroupContent>\n * <SidebarMenu>\n * <SidebarMenuItem>\n * <SidebarMenuButton isActive>\n * <HomeIcon />Overview\n * </SidebarMenuButton>\n * </SidebarMenuItem>\n * <SidebarMenuItem>\n * <SidebarMenuCollapsible\n * icon={<FolderIcon />}\n * label=\"Analytics\"\n * open={open}\n * onOpenChange={setOpen}\n * >\n * <SidebarMenuButton><BarChartIcon />Cohort Builder</SidebarMenuButton>\n * </SidebarMenuCollapsible>\n * </SidebarMenuItem>\n * </SidebarMenu>\n * </SidebarGroupContent>\n * </SidebarGroup>\n * </SidebarContent>\n * </Sidebar>\n * <SidebarInset>{\"<page content>\"}</SidebarInset>\n * </SidebarProvider>\n */\n"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Skeleton — pulsing placeholder block that mirrors the shape of content still loading.
3
+ *
4
+ * A single div with an `animate-pulse` background; no internal shape logic.
5
+ * All sizing/shape comes from
6
+ * utility classes passed via `className` (e.g. `h-4 w-48`, `size-12 rounded-full`).
7
+ */
8
+ declare function Skeleton({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
9
+ export { Skeleton };
10
+ /**
11
+ * WHEN TO USE
12
+ * - Initial data fetch for a region whose layout is already known — lists, cards, tables — so the placeholder mirrors the real content shape.
13
+ * - Composing multiple Skeletons together (e.g. an avatar circle plus two text lines) to approximate a specific card or row.
14
+ *
15
+ * NOT WHEN
16
+ * - Action-level feedback on a button or small control — use Spinner instead.
17
+ * - Loads short enough to flash (under ~300ms) — a flashing skeleton reads as a glitch, not loading.
18
+ * - The final layout isn't known yet — an inaccurate placeholder is worse than a generic spinner.
19
+ *
20
+ * KEY RULES
21
+ * - Skeleton has no default size — always pass explicit sizing via `className` (e.g. `h-4 w-48`, `size-12 rounded-full`) to match the real content.
22
+ * - Shape should mirror the content it stands in for: circles for avatars, matching line-heights/widths for text.
23
+ *
24
+ * USAGE
25
+ * <Skeleton className="h-4 w-48" />
26
+ *
27
+ * <div className="flex items-center gap-4">
28
+ * <Skeleton className="size-12 rounded-full" />
29
+ * <div className="grid flex-1 gap-2">
30
+ * <Skeleton className="h-4 w-full" />
31
+ * <Skeleton className="h-4 w-3/5" />
32
+ * </div>
33
+ * </div>
34
+ */
35
+ //# sourceMappingURL=skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/ui/skeleton.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BAQrE;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}