@gerege-systems/ui 0.11.2

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 (218) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +234 -0
  3. package/dist-lib/__tests__/helpers/color.d.ts +9 -0
  4. package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
  5. package/dist-lib/components/ui/Accordion.d.ts +21 -0
  6. package/dist-lib/components/ui/Accordion.js +71 -0
  7. package/dist-lib/components/ui/Accordion.js.map +1 -0
  8. package/dist-lib/components/ui/Alert.d.ts +51 -0
  9. package/dist-lib/components/ui/Alert.js +79 -0
  10. package/dist-lib/components/ui/Alert.js.map +1 -0
  11. package/dist-lib/components/ui/Avatar.d.ts +52 -0
  12. package/dist-lib/components/ui/Avatar.js +94 -0
  13. package/dist-lib/components/ui/Avatar.js.map +1 -0
  14. package/dist-lib/components/ui/Badge.d.ts +26 -0
  15. package/dist-lib/components/ui/Badge.js +76 -0
  16. package/dist-lib/components/ui/Badge.js.map +1 -0
  17. package/dist-lib/components/ui/Breadcrumbs.d.ts +33 -0
  18. package/dist-lib/components/ui/Breadcrumbs.js +52 -0
  19. package/dist-lib/components/ui/Breadcrumbs.js.map +1 -0
  20. package/dist-lib/components/ui/Button.d.ts +52 -0
  21. package/dist-lib/components/ui/Button.js +131 -0
  22. package/dist-lib/components/ui/Button.js.map +1 -0
  23. package/dist-lib/components/ui/Calendar.d.ts +15 -0
  24. package/dist-lib/components/ui/Calendar.js +139 -0
  25. package/dist-lib/components/ui/Calendar.js.map +1 -0
  26. package/dist-lib/components/ui/Card.d.ts +39 -0
  27. package/dist-lib/components/ui/Card.js +97 -0
  28. package/dist-lib/components/ui/Card.js.map +1 -0
  29. package/dist-lib/components/ui/Carousel.d.ts +27 -0
  30. package/dist-lib/components/ui/Carousel.js +174 -0
  31. package/dist-lib/components/ui/Carousel.js.map +1 -0
  32. package/dist-lib/components/ui/Chart.d.ts +87 -0
  33. package/dist-lib/components/ui/Chart.js +487 -0
  34. package/dist-lib/components/ui/Chart.js.map +1 -0
  35. package/dist-lib/components/ui/Checkbox.d.ts +28 -0
  36. package/dist-lib/components/ui/Checkbox.js +70 -0
  37. package/dist-lib/components/ui/Checkbox.js.map +1 -0
  38. package/dist-lib/components/ui/Combobox.d.ts +67 -0
  39. package/dist-lib/components/ui/Combobox.js +195 -0
  40. package/dist-lib/components/ui/Combobox.js.map +1 -0
  41. package/dist-lib/components/ui/CommandPalette.d.ts +112 -0
  42. package/dist-lib/components/ui/CommandPalette.js +179 -0
  43. package/dist-lib/components/ui/CommandPalette.js.map +1 -0
  44. package/dist-lib/components/ui/ContextMenu.d.ts +50 -0
  45. package/dist-lib/components/ui/ContextMenu.js +165 -0
  46. package/dist-lib/components/ui/ContextMenu.js.map +1 -0
  47. package/dist-lib/components/ui/DataGrid.d.ts +79 -0
  48. package/dist-lib/components/ui/DataGrid.js +99 -0
  49. package/dist-lib/components/ui/DataGrid.js.map +1 -0
  50. package/dist-lib/components/ui/DatePicker.d.ts +45 -0
  51. package/dist-lib/components/ui/DatePicker.js +193 -0
  52. package/dist-lib/components/ui/DatePicker.js.map +1 -0
  53. package/dist-lib/components/ui/DesignSystemProvider.d.ts +147 -0
  54. package/dist-lib/components/ui/DesignSystemProvider.js +135 -0
  55. package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -0
  56. package/dist-lib/components/ui/Dialog.d.ts +77 -0
  57. package/dist-lib/components/ui/Dialog.js +165 -0
  58. package/dist-lib/components/ui/Dialog.js.map +1 -0
  59. package/dist-lib/components/ui/Drawer.d.ts +44 -0
  60. package/dist-lib/components/ui/Drawer.js +132 -0
  61. package/dist-lib/components/ui/Drawer.js.map +1 -0
  62. package/dist-lib/components/ui/DropdownMenu.d.ts +47 -0
  63. package/dist-lib/components/ui/DropdownMenu.js +169 -0
  64. package/dist-lib/components/ui/DropdownMenu.js.map +1 -0
  65. package/dist-lib/components/ui/EmptyState.d.ts +48 -0
  66. package/dist-lib/components/ui/EmptyState.js +46 -0
  67. package/dist-lib/components/ui/EmptyState.js.map +1 -0
  68. package/dist-lib/components/ui/ErrorState.d.ts +51 -0
  69. package/dist-lib/components/ui/ErrorState.js +69 -0
  70. package/dist-lib/components/ui/ErrorState.js.map +1 -0
  71. package/dist-lib/components/ui/FileUpload.d.ts +26 -0
  72. package/dist-lib/components/ui/FileUpload.js +111 -0
  73. package/dist-lib/components/ui/FileUpload.js.map +1 -0
  74. package/dist-lib/components/ui/Form.d.ts +36 -0
  75. package/dist-lib/components/ui/Form.js +131 -0
  76. package/dist-lib/components/ui/Form.js.map +1 -0
  77. package/dist-lib/components/ui/Icon.d.ts +34 -0
  78. package/dist-lib/components/ui/Icon.js +32 -0
  79. package/dist-lib/components/ui/Icon.js.map +1 -0
  80. package/dist-lib/components/ui/IconButton.d.ts +34 -0
  81. package/dist-lib/components/ui/IconButton.js +64 -0
  82. package/dist-lib/components/ui/IconButton.js.map +1 -0
  83. package/dist-lib/components/ui/Input.d.ts +54 -0
  84. package/dist-lib/components/ui/Input.js +158 -0
  85. package/dist-lib/components/ui/Input.js.map +1 -0
  86. package/dist-lib/components/ui/Kbd.d.ts +16 -0
  87. package/dist-lib/components/ui/Kbd.js +24 -0
  88. package/dist-lib/components/ui/Kbd.js.map +1 -0
  89. package/dist-lib/components/ui/MultiSelect.d.ts +64 -0
  90. package/dist-lib/components/ui/MultiSelect.js +210 -0
  91. package/dist-lib/components/ui/MultiSelect.js.map +1 -0
  92. package/dist-lib/components/ui/Pagination.d.ts +55 -0
  93. package/dist-lib/components/ui/Pagination.js +153 -0
  94. package/dist-lib/components/ui/Pagination.js.map +1 -0
  95. package/dist-lib/components/ui/Popover.d.ts +16 -0
  96. package/dist-lib/components/ui/Popover.js +35 -0
  97. package/dist-lib/components/ui/Popover.js.map +1 -0
  98. package/dist-lib/components/ui/Progress.d.ts +40 -0
  99. package/dist-lib/components/ui/Progress.js +100 -0
  100. package/dist-lib/components/ui/Progress.js.map +1 -0
  101. package/dist-lib/components/ui/RadioGroup.d.ts +27 -0
  102. package/dist-lib/components/ui/RadioGroup.js +81 -0
  103. package/dist-lib/components/ui/RadioGroup.js.map +1 -0
  104. package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
  105. package/dist-lib/components/ui/RelativeTime.js +31 -0
  106. package/dist-lib/components/ui/RelativeTime.js.map +1 -0
  107. package/dist-lib/components/ui/ScrollArea.d.ts +21 -0
  108. package/dist-lib/components/ui/ScrollArea.js +60 -0
  109. package/dist-lib/components/ui/ScrollArea.js.map +1 -0
  110. package/dist-lib/components/ui/Select.d.ts +61 -0
  111. package/dist-lib/components/ui/Select.js +139 -0
  112. package/dist-lib/components/ui/Select.js.map +1 -0
  113. package/dist-lib/components/ui/Separator.d.ts +13 -0
  114. package/dist-lib/components/ui/Separator.js +26 -0
  115. package/dist-lib/components/ui/Separator.js.map +1 -0
  116. package/dist-lib/components/ui/Sheet.d.ts +55 -0
  117. package/dist-lib/components/ui/Sheet.js +136 -0
  118. package/dist-lib/components/ui/Sheet.js.map +1 -0
  119. package/dist-lib/components/ui/Sidebar.d.ts +91 -0
  120. package/dist-lib/components/ui/Sidebar.js +212 -0
  121. package/dist-lib/components/ui/Sidebar.js.map +1 -0
  122. package/dist-lib/components/ui/Skeleton.d.ts +37 -0
  123. package/dist-lib/components/ui/Skeleton.js +29 -0
  124. package/dist-lib/components/ui/Skeleton.js.map +1 -0
  125. package/dist-lib/components/ui/Slider.d.ts +33 -0
  126. package/dist-lib/components/ui/Slider.js +64 -0
  127. package/dist-lib/components/ui/Slider.js.map +1 -0
  128. package/dist-lib/components/ui/Snackbar.d.ts +21 -0
  129. package/dist-lib/components/ui/Snackbar.js +57 -0
  130. package/dist-lib/components/ui/Snackbar.js.map +1 -0
  131. package/dist-lib/components/ui/Spinner.d.ts +23 -0
  132. package/dist-lib/components/ui/Spinner.js +54 -0
  133. package/dist-lib/components/ui/Spinner.js.map +1 -0
  134. package/dist-lib/components/ui/Stepper.d.ts +40 -0
  135. package/dist-lib/components/ui/Stepper.js +111 -0
  136. package/dist-lib/components/ui/Stepper.js.map +1 -0
  137. package/dist-lib/components/ui/Switch.d.ts +33 -0
  138. package/dist-lib/components/ui/Switch.js +80 -0
  139. package/dist-lib/components/ui/Switch.js.map +1 -0
  140. package/dist-lib/components/ui/Table.d.ts +71 -0
  141. package/dist-lib/components/ui/Table.js +179 -0
  142. package/dist-lib/components/ui/Table.js.map +1 -0
  143. package/dist-lib/components/ui/Tabs.d.ts +32 -0
  144. package/dist-lib/components/ui/Tabs.js +91 -0
  145. package/dist-lib/components/ui/Tabs.js.map +1 -0
  146. package/dist-lib/components/ui/TagInput.d.ts +39 -0
  147. package/dist-lib/components/ui/TagInput.js +111 -0
  148. package/dist-lib/components/ui/TagInput.js.map +1 -0
  149. package/dist-lib/components/ui/Textarea.d.ts +34 -0
  150. package/dist-lib/components/ui/Textarea.js +88 -0
  151. package/dist-lib/components/ui/Textarea.js.map +1 -0
  152. package/dist-lib/components/ui/Timeline.d.ts +33 -0
  153. package/dist-lib/components/ui/Timeline.js +56 -0
  154. package/dist-lib/components/ui/Timeline.js.map +1 -0
  155. package/dist-lib/components/ui/Toast.d.ts +53 -0
  156. package/dist-lib/components/ui/Toast.js +158 -0
  157. package/dist-lib/components/ui/Toast.js.map +1 -0
  158. package/dist-lib/components/ui/Tooltip.d.ts +38 -0
  159. package/dist-lib/components/ui/Tooltip.js +60 -0
  160. package/dist-lib/components/ui/Tooltip.js.map +1 -0
  161. package/dist-lib/components/ui/TopNav.d.ts +37 -0
  162. package/dist-lib/components/ui/TopNav.js +69 -0
  163. package/dist-lib/components/ui/TopNav.js.map +1 -0
  164. package/dist-lib/components/ui/Tree.d.ts +51 -0
  165. package/dist-lib/components/ui/Tree.js +170 -0
  166. package/dist-lib/components/ui/Tree.js.map +1 -0
  167. package/dist-lib/hooks/use-debounce.d.ts +19 -0
  168. package/dist-lib/hooks/use-debounce.js +36 -0
  169. package/dist-lib/hooks/use-debounce.js.map +1 -0
  170. package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
  171. package/dist-lib/hooks/use-delayed-loading.js +20 -0
  172. package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
  173. package/dist-lib/hooks/use-field-ids.d.ts +30 -0
  174. package/dist-lib/hooks/use-field-ids.js +18 -0
  175. package/dist-lib/hooks/use-field-ids.js.map +1 -0
  176. package/dist-lib/hooks/use-media-query.d.ts +11 -0
  177. package/dist-lib/hooks/use-media-query.js +22 -0
  178. package/dist-lib/hooks/use-media-query.js.map +1 -0
  179. package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
  180. package/dist-lib/hooks/use-modifier-key.js +19 -0
  181. package/dist-lib/hooks/use-modifier-key.js.map +1 -0
  182. package/dist-lib/hooks/use-strings.d.ts +5 -0
  183. package/dist-lib/hooks/use-strings.js +12 -0
  184. package/dist-lib/hooks/use-strings.js.map +1 -0
  185. package/dist-lib/hooks/use-toast.d.ts +48 -0
  186. package/dist-lib/hooks/use-toast.js +67 -0
  187. package/dist-lib/hooks/use-toast.js.map +1 -0
  188. package/dist-lib/icon.d.ts +8 -0
  189. package/dist-lib/icon.js +7 -0
  190. package/dist-lib/icon.js.map +1 -0
  191. package/dist-lib/icons/index.d.ts +80 -0
  192. package/dist-lib/icons/index.js +163 -0
  193. package/dist-lib/icons/index.js.map +1 -0
  194. package/dist-lib/illustrations/index.d.ts +10 -0
  195. package/dist-lib/illustrations/index.js +114 -0
  196. package/dist-lib/illustrations/index.js.map +1 -0
  197. package/dist-lib/index.d.ts +68 -0
  198. package/dist-lib/index.js +291 -0
  199. package/dist-lib/index.js.map +1 -0
  200. package/dist-lib/lib/cva.d.ts +6 -0
  201. package/dist-lib/lib/format.d.ts +65 -0
  202. package/dist-lib/lib/format.js +95 -0
  203. package/dist-lib/lib/format.js.map +1 -0
  204. package/dist-lib/lib/return-focus.d.ts +11 -0
  205. package/dist-lib/lib/return-focus.js +12 -0
  206. package/dist-lib/lib/return-focus.js.map +1 -0
  207. package/dist-lib/lib/strings.d.ts +190 -0
  208. package/dist-lib/lib/strings.js +141 -0
  209. package/dist-lib/lib/strings.js.map +1 -0
  210. package/dist-lib/lib/strings.mn.d.ts +3 -0
  211. package/dist-lib/lib/strings.mn.js +115 -0
  212. package/dist-lib/lib/strings.mn.js.map +1 -0
  213. package/dist-lib/lib/utils.d.ts +11 -0
  214. package/dist-lib/lib/utils.js +10 -0
  215. package/dist-lib/lib/utils.js.map +1 -0
  216. package/dist-lib/styles.css +1 -0
  217. package/dist-lib/theme.css +840 -0
  218. package/package.json +158 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.js","sources":["../../../src/components/ui/Select.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementRef, type ReactNode } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\nimport { Check, ChevronDown, ChevronUp, ChevronsUpDown } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\n\n/* -----------------------------------------------------------------------------\n * Compound API:\n *\n * <Select value={…} onValueChange={…}>\n * <SelectTrigger placeholder=\"Pick one\" />\n * <SelectContent>\n * <SelectGroup label=\"Active\">\n * <SelectItem value=\"a\">Apple</SelectItem>\n * <SelectItem value=\"b\">Banana</SelectItem>\n * </SelectGroup>\n * </SelectContent>\n * </Select>\n *\n * All accessibility is handled by Radix: keyboard navigation, type-ahead,\n * focus trap, ARIA roles. We only style.\n * --------------------------------------------------------------------------- */\n\nexport const Select = SelectPrimitive.Root;\nexport const SelectValue = SelectPrimitive.Value;\n\nexport interface SelectTriggerProps extends Omit<\n ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>,\n 'children'\n> {\n /**\n * Placeholder shown when no value is selected. Also used as the trigger's\n * accessible name when no `aria-label` / `aria-labelledby` / `id` (external\n * `<Label htmlFor>`) is supplied — `role=\"combobox\"` takes no name from\n * its content.\n */\n placeholder?: string;\n /** Trigger height — matches Input sizes. */\n size?: 'sm' | 'md' | 'lg';\n /** Visual tone — `error` swaps the border + ring to danger. */\n tone?: 'default' | 'error';\n}\n\nexport const SelectTrigger = forwardRef<\n ElementRef<typeof SelectPrimitive.Trigger>,\n SelectTriggerProps\n>(function SelectTrigger({ className, placeholder, size = 'md', tone = 'default', ...props }, ref) {\n const strings = useStrings();\n const hasName = Boolean(props['aria-label'] || props['aria-labelledby'] || props.id);\n return (\n <SelectPrimitive.Trigger\n ref={ref}\n aria-label={hasName ? undefined : (placeholder ?? strings.select.placeholder)}\n className={cn(\n 'bg-card text-foreground inline-flex w-full items-center justify-between gap-2 rounded-md border text-lg md:text-sm',\n '[&>span]:min-w-0 [&>span]:truncate',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'outline-none',\n 'focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'data-[placeholder]:text-foreground-subtle',\n size === 'sm' && 'h-8 px-2.5',\n size === 'md' && 'h-9 px-3',\n size === 'lg' && 'h-10 px-3.5',\n tone === 'default'\n ? 'border-border-input focus-visible:border-accent focus-visible:ring-ring'\n : 'border-danger focus-visible:border-danger focus-visible:ring-danger',\n className,\n )}\n {...props}\n >\n <SelectPrimitive.Value placeholder={placeholder} />\n <SelectPrimitive.Icon asChild>\n <ChevronsUpDown className=\"text-foreground-subtle size-4 shrink-0\" aria-hidden />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n});\nSelectTrigger.displayName = 'SelectTrigger';\n\nconst scrollBtn = 'flex h-6 cursor-default items-center justify-center text-foreground-subtle';\n\nexport const SelectScrollUpButton = forwardRef<\n ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(function SelectScrollUpButton({ className, ...props }, ref) {\n return (\n <SelectPrimitive.ScrollUpButton ref={ref} className={cn(scrollBtn, className)} {...props}>\n <ChevronUp className=\"size-4\" aria-hidden />\n </SelectPrimitive.ScrollUpButton>\n );\n});\nSelectScrollUpButton.displayName = 'SelectScrollUpButton';\n\nexport const SelectScrollDownButton = forwardRef<\n ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(function SelectScrollDownButton({ className, ...props }, ref) {\n return (\n <SelectPrimitive.ScrollDownButton ref={ref} className={cn(scrollBtn, className)} {...props}>\n <ChevronDown className=\"size-4\" aria-hidden />\n </SelectPrimitive.ScrollDownButton>\n );\n});\nSelectScrollDownButton.displayName = 'SelectScrollDownButton';\n\nexport const SelectContent = forwardRef<\n ElementRef<typeof SelectPrimitive.Content>,\n ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(function SelectContent({ className, children, position = 'popper', ...props }, ref) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n position={position}\n className={cn(\n 'z-[var(--z-popover)] max-h-96 min-w-[var(--radix-select-trigger-width)]',\n 'border-border bg-popover text-popover-foreground overflow-hidden rounded-lg border',\n 'shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n position === 'popper' &&\n 'data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1',\n className,\n )}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport className=\"p-1\">{children}</SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n});\nSelectContent.displayName = 'SelectContent';\n\nexport const SelectLabel = forwardRef<\n ElementRef<typeof SelectPrimitive.Label>,\n ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(function SelectLabel({ className, ...props }, ref) {\n return (\n <SelectPrimitive.Label\n ref={ref}\n className={cn('text-foreground-subtle px-2 py-1.5 text-xs font-medium', className)}\n {...props}\n />\n );\n});\nSelectLabel.displayName = 'SelectLabel';\n\nexport interface SelectItemProps extends ComponentPropsWithoutRef<typeof SelectPrimitive.Item> {\n /** Icon shown to the left of the label. */\n leadingIcon?: ReactNode;\n}\n\nexport const SelectItem = forwardRef<ElementRef<typeof SelectPrimitive.Item>, SelectItemProps>(\n function SelectItem({ className, children, leadingIcon, ...props }, ref) {\n return (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex w-full cursor-default items-center gap-2 select-none',\n 'text-foreground rounded-sm px-2 py-1.5 pr-8 text-sm outline-none',\n 'data-[highlighted]:bg-background-muted data-[highlighted]:text-foreground',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className,\n )}\n {...props}\n >\n {leadingIcon && (\n <span className=\"text-foreground-subtle flex items-center [&_svg]:size-4\">\n {leadingIcon}\n </span>\n )}\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n <span className=\"absolute right-2 flex items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"text-accent size-4\" aria-hidden />\n </SelectPrimitive.ItemIndicator>\n </span>\n </SelectPrimitive.Item>\n );\n },\n);\nSelectItem.displayName = 'SelectItem';\n\nexport const SelectSeparator = forwardRef<\n ElementRef<typeof SelectPrimitive.Separator>,\n ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(function SelectSeparator({ className, ...props }, ref) {\n return (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn('bg-border -mx-1 my-1 h-px', className)}\n {...props}\n />\n );\n});\nSelectSeparator.displayName = 'SelectSeparator';\n\n/** Optional grouping with a label header. Pure composition over Radix Group + Label. */\nexport interface SelectGroupProps extends ComponentPropsWithoutRef<typeof SelectPrimitive.Group> {\n label?: ReactNode;\n}\nexport const SelectGroup = forwardRef<ElementRef<typeof SelectPrimitive.Group>, SelectGroupProps>(\n function SelectGroup({ label, children, ...props }, ref) {\n return (\n <SelectPrimitive.Group ref={ref} {...props}>\n {label && <SelectLabel>{label}</SelectLabel>}\n {children}\n </SelectPrimitive.Group>\n );\n },\n);\nSelectGroup.displayName = 'SelectGroup';\n\n/**\n * Compose `Select` + `SelectTrigger` + `SelectContent` + `SelectItem` for a\n * single-choice picker. Keyboard, type-ahead, and ARIA come from Radix.\n *\n * @example Basic\n * <Select onValueChange={setStatus}>\n * <SelectTrigger placeholder=\"Status\" />\n * <SelectContent>\n * <SelectItem value=\"open\">Open</SelectItem>\n * <SelectItem value=\"closed\">Closed</SelectItem>\n * </SelectContent>\n * </Select>\n *\n * @example Grouped\n * <SelectContent>\n * <SelectGroup label=\"People\">\n * <SelectItem value=\"anu\">Anu</SelectItem>\n * <SelectItem value=\"bat\">Bat</SelectItem>\n * </SelectGroup>\n * <SelectSeparator />\n * <SelectGroup label=\"Bots\">\n * <SelectItem value=\"robo\">Robo</SelectItem>\n * </SelectGroup>\n * </SelectContent>\n *\n * @do Use `placeholder` on the trigger when there is no default value.\n * @dont Use Select for more than ~12 options — switch to `Combobox`.\n */\n"],"names":["Select","SelectPrimitive","SelectValue","SelectTrigger","forwardRef","className","placeholder","size","tone","props","ref","strings","useStrings","hasName","jsxs","cn","jsx","ChevronsUpDown","scrollBtn","SelectScrollUpButton","ChevronUp","SelectScrollDownButton","ChevronDown","SelectContent","children","position","SelectLabel","SelectItem","leadingIcon","Check","SelectSeparator","SelectGroup","label"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
2
+ /**
3
+ * Hairline divider. Decorative by default (no role announced). Pass
4
+ * `decorative={false}` when the separator carries semantic meaning, e.g.
5
+ * splitting two regions in a landmark.
6
+ *
7
+ * @example Section divider
8
+ * <Separator className="my-6" />
9
+ *
10
+ * @example Vertical inside a toolbar
11
+ * <Separator orientation="vertical" className="h-5 mx-2" />
12
+ */
13
+ export declare const Separator: import('react').ForwardRefExoticComponent<Omit<SeparatorPrimitive.SeparatorProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx as p } from "react/jsx-runtime";
3
+ import { forwardRef as i } from "react";
4
+ import * as m from "@radix-ui/react-separator";
5
+ import { cn as f } from "../../lib/utils.js";
6
+ const l = i(function({ className: o, orientation: r = "horizontal", decorative: t = !0, ...a }, e) {
7
+ return /* @__PURE__ */ p(
8
+ m.Root,
9
+ {
10
+ ref: e,
11
+ orientation: r,
12
+ decorative: t,
13
+ className: f(
14
+ "bg-border shrink-0",
15
+ r === "horizontal" ? "h-px w-full" : "h-full w-px",
16
+ o
17
+ ),
18
+ ...a
19
+ }
20
+ );
21
+ });
22
+ l.displayName = "Separator";
23
+ export {
24
+ l as Separator
25
+ };
26
+ //# sourceMappingURL=Separator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Separator.js","sources":["../../../src/components/ui/Separator.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementRef } from 'react';\nimport * as SeparatorPrimitive from '@radix-ui/react-separator';\nimport { cn } from '@/lib/utils';\n\n/**\n * Hairline divider. Decorative by default (no role announced). Pass\n * `decorative={false}` when the separator carries semantic meaning, e.g.\n * splitting two regions in a landmark.\n *\n * @example Section divider\n * <Separator className=\"my-6\" />\n *\n * @example Vertical inside a toolbar\n * <Separator orientation=\"vertical\" className=\"h-5 mx-2\" />\n */\nexport const Separator = forwardRef<\n ElementRef<typeof SeparatorPrimitive.Root>,\n ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(function Separator({ className, orientation = 'horizontal', decorative = true, ...props }, ref) {\n return (\n <SeparatorPrimitive.Root\n ref={ref}\n orientation={orientation}\n decorative={decorative}\n className={cn(\n 'bg-border shrink-0',\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px',\n className,\n )}\n {...props}\n />\n );\n});\nSeparator.displayName = 'Separator';\n"],"names":["Separator","forwardRef","className","orientation","decorative","props","ref","jsx","SeparatorPrimitive","cn"],"mappings":";;;;;AAiBO,MAAMA,IAAYC,EAGvB,SAAmB,EAAE,WAAAC,GAAW,aAAAC,IAAc,cAAc,YAAAC,IAAa,IAAM,GAAGC,EAAA,GAASC,GAAK;AAChG,SACE,gBAAAC;AAAA,IAACC,EAAmB;AAAA,IAAnB;AAAA,MACC,KAAAF;AAAA,MACA,aAAAH;AAAA,MACA,YAAAC;AAAA,MACA,WAAWK;AAAA,QACT;AAAA,QACAN,MAAgB,eAAe,gBAAgB;AAAA,QAC/CD;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDL,EAAU,cAAc;"}
@@ -0,0 +1,55 @@
1
+ import { ComponentPropsWithoutRef, HTMLAttributes } from 'react';
2
+ import { VariantProps } from '../../lib/cva.js';
3
+ import { ReturnFocusRef } from '../../lib/return-focus.js';
4
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
5
+ export declare const Sheet: import('react').FC<DialogPrimitive.DialogProps>;
6
+ export declare const SheetTrigger: import('react').ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & import('react').RefAttributes<HTMLButtonElement>>;
7
+ export declare const SheetClose: import('react').ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & import('react').RefAttributes<HTMLButtonElement>>;
8
+ export declare const SheetPortal: import('react').FC<DialogPrimitive.DialogPortalProps>;
9
+ declare const sheet: (props?: ({
10
+ side?: "top" | "right" | "bottom" | "left" | null | undefined;
11
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
12
+ export interface SheetContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheet> {
13
+ showClose?: boolean;
14
+ /**
15
+ * Element to focus when the overlay closes. Overrides Radix's default
16
+ * (the element focused when the content mounted), which is `<body>` for
17
+ * controlled overlays opened from a pointer click on a non-focusable /
18
+ * tooltip-wrapped trigger. A consumer `onCloseAutoFocus` runs first and
19
+ * wins if it calls `preventDefault()`.
20
+ */
21
+ returnFocusTo?: ReturnFocusRef;
22
+ }
23
+ export declare const SheetContent: import('react').ForwardRefExoticComponent<SheetContentProps & import('react').RefAttributes<HTMLDivElement>>;
24
+ export declare function SheetHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
25
+ export declare namespace SheetHeader {
26
+ var displayName: string;
27
+ }
28
+ export declare function SheetFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
29
+ export declare namespace SheetFooter {
30
+ var displayName: string;
31
+ }
32
+ export declare const SheetTitle: import('react').ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & import('react').RefAttributes<HTMLHeadingElement>, "ref"> & import('react').RefAttributes<HTMLHeadingElement>>;
33
+ export declare const SheetDescription: import('react').ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & import('react').RefAttributes<HTMLParagraphElement>, "ref"> & import('react').RefAttributes<HTMLParagraphElement>>;
34
+ export {};
35
+ /**
36
+ * @example Right-side filter drawer
37
+ * <Sheet>
38
+ * <SheetTrigger asChild><Button variant="outline">Filters</Button></SheetTrigger>
39
+ * <SheetContent side="right">
40
+ * <SheetHeader>
41
+ * <SheetTitle>Filters</SheetTitle>
42
+ * <SheetDescription>Refine the result set.</SheetDescription>
43
+ * </SheetHeader>
44
+ * …
45
+ * <SheetFooter>
46
+ * <SheetClose asChild><Button variant="outline">Cancel</Button></SheetClose>
47
+ * <Button>Apply</Button>
48
+ * </SheetFooter>
49
+ * </SheetContent>
50
+ * </Sheet>
51
+ *
52
+ * @do Use right side for filters/inspectors, left for navigation, bottom for
53
+ * mobile sheets.
54
+ * @dont Use a full-screen sheet on desktop — prefer Dialog or a dedicated page.
55
+ */
@@ -0,0 +1,136 @@
1
+ "use client";
2
+ import { jsxs as d, jsx as o } from "react/jsx-runtime";
3
+ import { forwardRef as n } from "react";
4
+ import * as t from "@radix-ui/react-dialog";
5
+ import { X as g } from "../../icons/index.js";
6
+ import { cn as i } from "../../lib/utils.js";
7
+ import { useStrings as b } from "../../hooks/use-strings.js";
8
+ import { withReturnFocus as x } from "../../lib/return-focus.js";
9
+ import { cva as v } from "class-variance-authority";
10
+ const k = t.Root, A = t.Trigger, V = t.Close, S = t.Portal, l = n(function({ className: e, ...r }, s) {
11
+ return /* @__PURE__ */ o(
12
+ t.Overlay,
13
+ {
14
+ ref: s,
15
+ className: i(
16
+ "bg-overlay fixed inset-0 z-[var(--z-overlay)]",
17
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
18
+ "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
19
+ e
20
+ ),
21
+ ...r
22
+ }
23
+ );
24
+ });
25
+ l.displayName = "SheetOverlay";
26
+ const y = v(
27
+ [
28
+ "fixed z-[var(--z-modal)] bg-card text-card-foreground shadow-lg",
29
+ "flex flex-col gap-4 p-6",
30
+ // Safe-area insets for notched devices (consumers set viewport-fit=cover).
31
+ "pb-[max(1.5rem,env(safe-area-inset-bottom))] pl-[max(1.5rem,env(safe-area-inset-left))] pr-[max(1.5rem,env(safe-area-inset-right))]",
32
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
33
+ "data-[state=closed]:duration-[var(--duration-base)] data-[state=open]:duration-[var(--duration-slow)]"
34
+ ],
35
+ {
36
+ variants: {
37
+ side: {
38
+ top: "inset-x-0 top-0 border-b border-border data-[state=open]:slide-in-from-top data-[state=closed]:slide-out-to-top",
39
+ bottom: "inset-x-0 bottom-0 border-t border-border data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom",
40
+ left: "inset-y-0 left-0 h-full w-3/4 max-w-md border-r border-border data-[state=open]:slide-in-from-left data-[state=closed]:slide-out-to-left",
41
+ right: "inset-y-0 right-0 h-full w-3/4 max-w-md border-l border-border data-[state=open]:slide-in-from-right data-[state=closed]:slide-out-to-right"
42
+ }
43
+ },
44
+ defaultVariants: { side: "right" }
45
+ }
46
+ ), N = n(function({
47
+ className: e,
48
+ children: r,
49
+ side: s = "right",
50
+ showClose: m = !0,
51
+ returnFocusTo: f,
52
+ onCloseAutoFocus: c,
53
+ ...u
54
+ }, h) {
55
+ const p = b();
56
+ return /* @__PURE__ */ d(S, { children: [
57
+ /* @__PURE__ */ o(l, {}),
58
+ /* @__PURE__ */ d(
59
+ t.Content,
60
+ {
61
+ ref: h,
62
+ className: i(y({ side: s }), e),
63
+ onCloseAutoFocus: x(f, c),
64
+ ...u,
65
+ children: [
66
+ r,
67
+ m && /* @__PURE__ */ o(
68
+ t.Close,
69
+ {
70
+ "aria-label": p.sheet.close,
71
+ className: i(
72
+ "text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md",
73
+ "hover:bg-background-muted hover:text-foreground",
74
+ "focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
75
+ "transition-colors duration-[var(--duration-fast)]"
76
+ ),
77
+ children: /* @__PURE__ */ o(g, { className: "size-4", "aria-hidden": !0 })
78
+ }
79
+ )
80
+ ]
81
+ }
82
+ )
83
+ ] });
84
+ });
85
+ N.displayName = "SheetContent";
86
+ function w({ className: a, ...e }) {
87
+ return /* @__PURE__ */ o("div", { className: i("flex flex-col gap-1", a), ...e });
88
+ }
89
+ w.displayName = "SheetHeader";
90
+ function C({ className: a, ...e }) {
91
+ return /* @__PURE__ */ o(
92
+ "div",
93
+ {
94
+ className: i(
95
+ "mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end",
96
+ a
97
+ ),
98
+ ...e
99
+ }
100
+ );
101
+ }
102
+ C.displayName = "SheetFooter";
103
+ const z = n(function({ className: e, ...r }, s) {
104
+ return /* @__PURE__ */ o(
105
+ t.Title,
106
+ {
107
+ ref: s,
108
+ className: i("text-foreground text-lg leading-tight font-semibold", e),
109
+ ...r
110
+ }
111
+ );
112
+ });
113
+ z.displayName = "SheetTitle";
114
+ const T = n(function({ className: e, ...r }, s) {
115
+ return /* @__PURE__ */ o(
116
+ t.Description,
117
+ {
118
+ ref: s,
119
+ className: i("text-foreground-muted text-sm", e),
120
+ ...r
121
+ }
122
+ );
123
+ });
124
+ T.displayName = "SheetDescription";
125
+ export {
126
+ k as Sheet,
127
+ V as SheetClose,
128
+ N as SheetContent,
129
+ T as SheetDescription,
130
+ C as SheetFooter,
131
+ w as SheetHeader,
132
+ S as SheetPortal,
133
+ z as SheetTitle,
134
+ A as SheetTrigger
135
+ };
136
+ //# sourceMappingURL=Sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sheet.js","sources":["../../../src/components/ui/Sheet.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { cva, type VariantProps } from '@/lib/cva';\nimport { withReturnFocus, type ReturnFocusRef } from '@/lib/return-focus';\n\n/* -----------------------------------------------------------------------------\n * Sheet — drawer-style overlay. Built on Radix Dialog (focus trap, escape,\n * click-outside come from there). Slides in from one of four sides.\n * --------------------------------------------------------------------------- */\n\nexport const Sheet = DialogPrimitive.Root;\nexport const SheetTrigger = DialogPrimitive.Trigger;\nexport const SheetClose = DialogPrimitive.Close;\nexport const SheetPortal = DialogPrimitive.Portal;\n\nconst SheetOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(function SheetOverlay({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'bg-overlay fixed inset-0 z-[var(--z-overlay)]',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0',\n className,\n )}\n {...props}\n />\n );\n});\nSheetOverlay.displayName = 'SheetOverlay';\n\nconst sheet = cva(\n [\n 'fixed z-[var(--z-modal)] bg-card text-card-foreground shadow-lg',\n 'flex flex-col gap-4 p-6',\n // Safe-area insets for notched devices (consumers set viewport-fit=cover).\n 'pb-[max(1.5rem,env(safe-area-inset-bottom))] pl-[max(1.5rem,env(safe-area-inset-left))] pr-[max(1.5rem,env(safe-area-inset-right))]',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:duration-[var(--duration-base)] data-[state=open]:duration-[var(--duration-slow)]',\n ],\n {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b border-border data-[state=open]:slide-in-from-top data-[state=closed]:slide-out-to-top',\n bottom:\n 'inset-x-0 bottom-0 border-t border-border data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom',\n left: 'inset-y-0 left-0 h-full w-3/4 max-w-md border-r border-border data-[state=open]:slide-in-from-left data-[state=closed]:slide-out-to-left',\n right:\n 'inset-y-0 right-0 h-full w-3/4 max-w-md border-l border-border data-[state=open]:slide-in-from-right data-[state=closed]:slide-out-to-right',\n },\n },\n defaultVariants: { side: 'right' },\n },\n);\n\nexport interface SheetContentProps\n extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheet> {\n showClose?: boolean;\n /**\n * Element to focus when the overlay closes. Overrides Radix's default\n * (the element focused when the content mounted), which is `<body>` for\n * controlled overlays opened from a pointer click on a non-focusable /\n * tooltip-wrapped trigger. A consumer `onCloseAutoFocus` runs first and\n * wins if it calls `preventDefault()`.\n */\n returnFocusTo?: ReturnFocusRef;\n}\n\nexport const SheetContent = forwardRef<\n ElementRef<typeof DialogPrimitive.Content>,\n SheetContentProps\n>(function SheetContent(\n {\n className,\n children,\n side = 'right',\n showClose = true,\n returnFocusTo,\n onCloseAutoFocus,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n return (\n <SheetPortal>\n <SheetOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(sheet({ side }), className)}\n onCloseAutoFocus={withReturnFocus(returnFocusTo, onCloseAutoFocus)}\n {...props}\n >\n {children}\n {showClose && (\n <DialogPrimitive.Close\n aria-label={strings.sheet.close}\n className={cn(\n 'text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md',\n 'hover:bg-background-muted hover:text-foreground',\n 'focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n <X className=\"size-4\" aria-hidden />\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </SheetPortal>\n );\n});\nSheetContent.displayName = 'SheetContent';\n\nexport function SheetHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col gap-1', className)} {...props} />;\n}\nSheetHeader.displayName = 'SheetHeader';\n\nexport function SheetFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n 'mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n );\n}\nSheetFooter.displayName = 'SheetFooter';\n\nexport const SheetTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(function SheetTitle({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-foreground text-lg leading-tight font-semibold', className)}\n {...props}\n />\n );\n});\nSheetTitle.displayName = 'SheetTitle';\n\nexport const SheetDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(function SheetDescription({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-foreground-muted text-sm', className)}\n {...props}\n />\n );\n});\nSheetDescription.displayName = 'SheetDescription';\n\n/**\n * @example Right-side filter drawer\n * <Sheet>\n * <SheetTrigger asChild><Button variant=\"outline\">Filters</Button></SheetTrigger>\n * <SheetContent side=\"right\">\n * <SheetHeader>\n * <SheetTitle>Filters</SheetTitle>\n * <SheetDescription>Refine the result set.</SheetDescription>\n * </SheetHeader>\n * …\n * <SheetFooter>\n * <SheetClose asChild><Button variant=\"outline\">Cancel</Button></SheetClose>\n * <Button>Apply</Button>\n * </SheetFooter>\n * </SheetContent>\n * </Sheet>\n *\n * @do Use right side for filters/inspectors, left for navigation, bottom for\n * mobile sheets.\n * @dont Use a full-screen sheet on desktop — prefer Dialog or a dedicated page.\n */\n"],"names":["Sheet","DialogPrimitive","SheetTrigger","SheetClose","SheetPortal","SheetOverlay","forwardRef","className","props","ref","jsx","cn","sheet","cva","SheetContent","children","side","showClose","returnFocusTo","onCloseAutoFocus","strings","useStrings","jsxs","withReturnFocus","X","SheetHeader","SheetFooter","SheetTitle","SheetDescription"],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
2
+ interface SidebarContextValue {
3
+ collapsed: boolean;
4
+ }
5
+ /** Read the parent Sidebar's collapsed state. Useful for brand/footer slots
6
+ * that need to swap between full and compact rendering. */
7
+ export declare function useSidebar(): SidebarContextValue;
8
+ export interface SidebarProps extends HTMLAttributes<HTMLElement> {
9
+ /** Default state on first mount. Use `defaultCollapsed` for uncontrolled. */
10
+ defaultCollapsed?: boolean;
11
+ /** Controlled collapsed state. */
12
+ collapsed?: boolean;
13
+ /** Called when the user toggles via the rail or keyboard. */
14
+ onCollapsedChange?: (next: boolean) => void;
15
+ /** Header slot pinned to the top (brand, workspace switcher, etc.). */
16
+ header?: ReactNode;
17
+ /** Footer slot pinned to the bottom (user card, version, etc.). */
18
+ footer?: ReactNode;
19
+ }
20
+ /**
21
+ * App-level navigation rail. Holds `SidebarSection` → `SidebarItem` lists,
22
+ * and optionally a `footer`. Supports collapse to icon-only on desktop.
23
+ * Below `md` the rail is hidden — pair it with a Sheet / Drawer for mobile.
24
+ *
25
+ * @example
26
+ * <Sidebar footer={<UserCard />}>
27
+ * <SidebarSection label="Workspace">
28
+ * <SidebarItem icon={<Home />} active>Home</SidebarItem>
29
+ * <SidebarItem icon={<Folder />}>Projects</SidebarItem>
30
+ * </SidebarSection>
31
+ * <SidebarSection label="Account">
32
+ * <SidebarItem icon={<Settings />}>Settings</SidebarItem>
33
+ * </SidebarSection>
34
+ * </Sidebar>
35
+ *
36
+ * @do Use 1–3 sections. More than that signals the IA needs restructuring.
37
+ * @dont Hide critical navigation under the collapsed state — keep icons
38
+ * always visible with tooltips.
39
+ */
40
+ export declare const Sidebar: import('react').ForwardRefExoticComponent<SidebarProps & import('react').RefAttributes<HTMLElement>>;
41
+ export interface SidebarSectionProps extends HTMLAttributes<HTMLDivElement> {
42
+ /** Visible section header. Hidden when collapsed. */
43
+ label?: ReactNode;
44
+ }
45
+ export declare function SidebarSection({ label, className, children, ...props }: SidebarSectionProps): import("react/jsx-runtime").JSX.Element;
46
+ export declare namespace SidebarSection {
47
+ var displayName: string;
48
+ }
49
+ interface SidebarItemBaseProps {
50
+ /** Lucide icon shown to the left. */
51
+ icon?: ReactNode;
52
+ /** Mark as the current page. */
53
+ active?: boolean;
54
+ /** Trailing badge / counter slot. */
55
+ trailing?: ReactNode;
56
+ /** Render a sub-item indented under a parent. */
57
+ sub?: boolean;
58
+ /**
59
+ * Tooltip text shown while the sidebar is collapsed. Defaults to `children`
60
+ * when that is a plain string.
61
+ */
62
+ tooltip?: ReactNode;
63
+ /**
64
+ * Render the child element (router `<Link>`) instead of `<a>`/`<button>`.
65
+ * The child receives className, aria-current and the item content.
66
+ */
67
+ asChild?: boolean;
68
+ }
69
+ type SidebarItemAnchorProps = SidebarItemBaseProps & AnchorHTMLAttributes<HTMLAnchorElement> & {
70
+ /** Renders an `<a>`. Omit to render a `<button>`. */
71
+ href: string;
72
+ };
73
+ type SidebarItemButtonProps = SidebarItemBaseProps & ButtonHTMLAttributes<HTMLButtonElement> & {
74
+ href?: undefined;
75
+ };
76
+ /** Discriminated on `href`: with it the item is an anchor, without it a button. */
77
+ export type SidebarItemProps = SidebarItemAnchorProps | SidebarItemButtonProps;
78
+ export declare const SidebarItem: import('react').ForwardRefExoticComponent<SidebarItemProps & import('react').RefAttributes<HTMLElement>>;
79
+ /** Lightweight collapsible sub-section inside the sidebar. */
80
+ export interface SidebarGroupProps extends Omit<HTMLAttributes<HTMLLIElement>, 'children'> {
81
+ icon?: ReactNode;
82
+ label: ReactNode;
83
+ /** Initial open state (uncontrolled). */
84
+ defaultOpen?: boolean;
85
+ /** Controlled open state. */
86
+ open?: boolean;
87
+ onOpenChange?: (open: boolean) => void;
88
+ children: ReactNode;
89
+ }
90
+ export declare const SidebarGroup: import('react').ForwardRefExoticComponent<SidebarGroupProps & import('react').RefAttributes<HTMLLIElement>>;
91
+ export {};
@@ -0,0 +1,212 @@
1
+ "use client";
2
+ import { jsx as e, jsxs as x, Fragment as _ } from "react/jsx-runtime";
3
+ import { forwardRef as j, useState as P, useContext as k, useId as G, createContext as T } from "react";
4
+ import { Slot as R } from "@radix-ui/react-slot";
5
+ import { ChevronsRight as D, ChevronsLeft as F, ChevronDown as L } from "../../icons/index.js";
6
+ import { cn as u } from "../../lib/utils.js";
7
+ import { useStrings as q } from "../../hooks/use-strings.js";
8
+ import { Tooltip as A } from "./Tooltip.js";
9
+ const y = T({ collapsed: !1 });
10
+ function Y() {
11
+ return k(y);
12
+ }
13
+ const B = j(function({
14
+ defaultCollapsed: d = !1,
15
+ collapsed: a,
16
+ onCollapsedChange: l,
17
+ header: t,
18
+ footer: s,
19
+ className: v,
20
+ children: b,
21
+ "aria-label": g,
22
+ ...h
23
+ }, i) {
24
+ const o = q(), [c, n] = P(d), r = a ?? c, p = (f) => {
25
+ a === void 0 && n(f), l == null || l(f);
26
+ };
27
+ return /* @__PURE__ */ e(y.Provider, { value: { collapsed: r }, children: /* @__PURE__ */ x(
28
+ "nav",
29
+ {
30
+ ref: i,
31
+ "aria-label": g ?? o.sidebar.label,
32
+ className: u(
33
+ "border-border bg-background-subtle sticky top-0 hidden h-dvh shrink-0 flex-col gap-2 border-r md:flex",
34
+ // Deliberate motion exception: the rail's own width transitions (layout).
35
+ // Only the rail and the main column it flanks move; no content inside reflows.
36
+ "transition-[width] duration-[var(--duration-base)] ease-[var(--ease-out)] motion-reduce:transition-none",
37
+ r ? "w-14" : "w-60",
38
+ v
39
+ ),
40
+ ...h,
41
+ children: [
42
+ t && /* @__PURE__ */ e(
43
+ "div",
44
+ {
45
+ className: u(
46
+ "border-border flex h-14 shrink-0 items-center overflow-hidden border-b",
47
+ r ? "justify-center px-2" : "px-3"
48
+ ),
49
+ children: t
50
+ }
51
+ ),
52
+ /* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto py-3", children: b }),
53
+ s && /* @__PURE__ */ e("div", { className: "border-border border-t p-2", children: s }),
54
+ /* @__PURE__ */ x(
55
+ "button",
56
+ {
57
+ type: "button",
58
+ onClick: () => p(!r),
59
+ "aria-label": r ? o.sidebar.expand : o.sidebar.collapse,
60
+ "aria-expanded": !r,
61
+ className: u(
62
+ "text-foreground-subtle mx-2 mb-2 flex h-8 items-center gap-2 rounded-md px-2",
63
+ "hover:bg-background-muted hover:text-foreground outline-none",
64
+ "focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2",
65
+ "transition-colors duration-[var(--duration-fast)]"
66
+ ),
67
+ children: [
68
+ r ? /* @__PURE__ */ e(D, { className: "size-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(F, { className: "size-4", "aria-hidden": !0 }),
69
+ !r && /* @__PURE__ */ e("span", { className: "text-xs font-medium", children: o.sidebar.collapseShort })
70
+ ]
71
+ }
72
+ )
73
+ ]
74
+ }
75
+ ) });
76
+ });
77
+ B.displayName = "Sidebar";
78
+ function E({ label: m, className: d, children: a, ...l }) {
79
+ const { collapsed: t } = k(y), s = G();
80
+ return /* @__PURE__ */ x("div", { className: u("mb-3", d), ...l, children: [
81
+ m && // Kept in the DOM (sr-only) while collapsed so the list stays labelled.
82
+ /* @__PURE__ */ e(
83
+ "div",
84
+ {
85
+ id: s,
86
+ className: u(
87
+ "text-foreground-subtle px-4 pt-2 pb-1 text-xs font-medium",
88
+ t && "sr-only"
89
+ ),
90
+ children: m
91
+ }
92
+ ),
93
+ /* @__PURE__ */ e("ul", { "aria-labelledby": m ? s : void 0, className: "flex flex-col gap-px", children: a })
94
+ ] });
95
+ }
96
+ E.displayName = "SidebarSection";
97
+ const H = j(
98
+ function(d, a) {
99
+ const { icon: l, active: t, trailing: s, sub: v, tooltip: b, asChild: g, className: h, children: i, ...o } = d, { collapsed: c } = k(y), n = u(
100
+ "flex h-8 w-full items-center gap-2 rounded-md px-2 text-sm outline-none",
101
+ "transition-colors duration-[var(--duration-fast)]",
102
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
103
+ t ? "bg-background-muted text-foreground font-medium" : "text-foreground-muted hover:bg-background-muted hover:text-foreground",
104
+ v && !c && "ml-6",
105
+ c && "justify-center",
106
+ h
107
+ ), r = typeof i == "string" ? i : void 0, p = b ?? r, f = c && !!p, z = /* @__PURE__ */ x(_, { children: [
108
+ l && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: l }),
109
+ c ? /* @__PURE__ */ e("span", { className: "sr-only", children: i }) : /* @__PURE__ */ e("span", { className: "flex-1 truncate text-left", title: r, children: i }),
110
+ !c && s && /* @__PURE__ */ e("span", { className: "ml-auto", children: s })
111
+ ] });
112
+ let N;
113
+ if (g) {
114
+ const { href: w, type: S, ...I } = o;
115
+ N = /* @__PURE__ */ e(
116
+ R,
117
+ {
118
+ ref: a,
119
+ "aria-current": t ? "page" : void 0,
120
+ className: n,
121
+ ...I,
122
+ children: i && typeof i == "object" && "props" in i ? i : null
123
+ }
124
+ );
125
+ } else if (o.href !== void 0) {
126
+ const { href: w, ...S } = o;
127
+ N = /* @__PURE__ */ e(
128
+ "a",
129
+ {
130
+ ref: a,
131
+ href: w,
132
+ "aria-current": t ? "page" : void 0,
133
+ className: n,
134
+ ...S,
135
+ children: z
136
+ }
137
+ );
138
+ } else {
139
+ const {
140
+ href: w,
141
+ type: S,
142
+ ...I
143
+ } = o;
144
+ N = /* @__PURE__ */ e(
145
+ "button",
146
+ {
147
+ ref: a,
148
+ type: S ?? "button",
149
+ "aria-current": t ? "page" : void 0,
150
+ className: n,
151
+ ...I,
152
+ children: z
153
+ }
154
+ );
155
+ }
156
+ return /* @__PURE__ */ e("li", { className: "px-2", children: f ? /* @__PURE__ */ e(A, { label: p, side: "right", children: N }) : N });
157
+ }
158
+ );
159
+ H.displayName = "SidebarItem";
160
+ const J = j(function({
161
+ icon: d,
162
+ label: a,
163
+ defaultOpen: l = !0,
164
+ open: t,
165
+ onOpenChange: s,
166
+ className: v,
167
+ children: b,
168
+ ...g
169
+ }, h) {
170
+ const { collapsed: i } = k(y), [o, c] = P(l), n = t ?? o, r = G(), p = () => {
171
+ const f = !n;
172
+ t === void 0 && c(f), s == null || s(f);
173
+ };
174
+ return i ? /* @__PURE__ */ e(_, { children: b }) : /* @__PURE__ */ x("li", { ref: h, className: v, ...g, children: [
175
+ /* @__PURE__ */ x(
176
+ "button",
177
+ {
178
+ type: "button",
179
+ onClick: p,
180
+ "aria-controls": n ? r : void 0,
181
+ "aria-expanded": n,
182
+ className: u(
183
+ "text-foreground-muted mx-2 flex h-8 w-[calc(100%-1rem)] items-center gap-2 rounded-md px-2 text-sm outline-none",
184
+ "transition-colors duration-[var(--duration-fast)]",
185
+ "hover:bg-background-muted hover:text-foreground",
186
+ "focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2"
187
+ ),
188
+ children: [
189
+ d && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: d }),
190
+ /* @__PURE__ */ e("span", { className: "flex-1 text-left", children: a }),
191
+ /* @__PURE__ */ e(
192
+ L,
193
+ {
194
+ className: u("size-3.5 transition-transform", n && "rotate-180"),
195
+ "aria-hidden": !0
196
+ }
197
+ )
198
+ ]
199
+ }
200
+ ),
201
+ n && /* @__PURE__ */ e("ul", { id: r, className: "flex flex-col gap-px", children: b })
202
+ ] });
203
+ });
204
+ J.displayName = "SidebarGroup";
205
+ export {
206
+ B as Sidebar,
207
+ J as SidebarGroup,
208
+ H as SidebarItem,
209
+ E as SidebarSection,
210
+ Y as useSidebar
211
+ };
212
+ //# sourceMappingURL=Sidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sidebar.js","sources":["../../../src/components/ui/Sidebar.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n forwardRef,\n useContext,\n useId,\n useState,\n type AnchorHTMLAttributes,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { ChevronDown, ChevronsLeft, ChevronsRight } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { Tooltip } from './Tooltip';\n\ninterface SidebarContextValue {\n collapsed: boolean;\n}\nconst SidebarContext = createContext<SidebarContextValue>({ collapsed: false });\n\n/** Read the parent Sidebar's collapsed state. Useful for brand/footer slots\n * that need to swap between full and compact rendering. */\nexport function useSidebar(): SidebarContextValue {\n return useContext(SidebarContext);\n}\n\nexport interface SidebarProps extends HTMLAttributes<HTMLElement> {\n /** Default state on first mount. Use `defaultCollapsed` for uncontrolled. */\n defaultCollapsed?: boolean;\n /** Controlled collapsed state. */\n collapsed?: boolean;\n /** Called when the user toggles via the rail or keyboard. */\n onCollapsedChange?: (next: boolean) => void;\n /** Header slot pinned to the top (brand, workspace switcher, etc.). */\n header?: ReactNode;\n /** Footer slot pinned to the bottom (user card, version, etc.). */\n footer?: ReactNode;\n}\n\n/**\n * App-level navigation rail. Holds `SidebarSection` → `SidebarItem` lists,\n * and optionally a `footer`. Supports collapse to icon-only on desktop.\n * Below `md` the rail is hidden — pair it with a Sheet / Drawer for mobile.\n *\n * @example\n * <Sidebar footer={<UserCard />}>\n * <SidebarSection label=\"Workspace\">\n * <SidebarItem icon={<Home />} active>Home</SidebarItem>\n * <SidebarItem icon={<Folder />}>Projects</SidebarItem>\n * </SidebarSection>\n * <SidebarSection label=\"Account\">\n * <SidebarItem icon={<Settings />}>Settings</SidebarItem>\n * </SidebarSection>\n * </Sidebar>\n *\n * @do Use 1–3 sections. More than that signals the IA needs restructuring.\n * @dont Hide critical navigation under the collapsed state — keep icons\n * always visible with tooltips.\n */\nexport const Sidebar = forwardRef<HTMLElement, SidebarProps>(function Sidebar(\n {\n defaultCollapsed = false,\n collapsed: controlled,\n onCollapsedChange,\n header,\n footer,\n className,\n children,\n 'aria-label': ariaLabel,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n const [internal, setInternal] = useState(defaultCollapsed);\n const collapsed = controlled ?? internal;\n const setCollapsed = (next: boolean) => {\n if (controlled === undefined) setInternal(next);\n onCollapsedChange?.(next);\n };\n\n return (\n <SidebarContext.Provider value={{ collapsed }}>\n <nav\n ref={ref}\n aria-label={ariaLabel ?? strings.sidebar.label}\n className={cn(\n 'border-border bg-background-subtle sticky top-0 hidden h-dvh shrink-0 flex-col gap-2 border-r md:flex',\n // Deliberate motion exception: the rail's own width transitions (layout).\n // Only the rail and the main column it flanks move; no content inside reflows.\n 'transition-[width] duration-[var(--duration-base)] ease-[var(--ease-out)] motion-reduce:transition-none',\n collapsed ? 'w-14' : 'w-60',\n className,\n )}\n {...props}\n >\n {header && (\n <div\n className={cn(\n 'border-border flex h-14 shrink-0 items-center overflow-hidden border-b',\n collapsed ? 'justify-center px-2' : 'px-3',\n )}\n >\n {header}\n </div>\n )}\n <div className=\"flex-1 overflow-y-auto py-3\">{children}</div>\n {footer && <div className=\"border-border border-t p-2\">{footer}</div>}\n <button\n type=\"button\"\n onClick={() => setCollapsed(!collapsed)}\n aria-label={collapsed ? strings.sidebar.expand : strings.sidebar.collapse}\n aria-expanded={!collapsed}\n className={cn(\n 'text-foreground-subtle mx-2 mb-2 flex h-8 items-center gap-2 rounded-md px-2',\n 'hover:bg-background-muted hover:text-foreground outline-none',\n 'focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n {collapsed ? (\n <ChevronsRight className=\"size-4\" aria-hidden />\n ) : (\n <ChevronsLeft className=\"size-4\" aria-hidden />\n )}\n {!collapsed && (\n <span className=\"text-xs font-medium\">{strings.sidebar.collapseShort}</span>\n )}\n </button>\n </nav>\n </SidebarContext.Provider>\n );\n});\nSidebar.displayName = 'Sidebar';\n\nexport interface SidebarSectionProps extends HTMLAttributes<HTMLDivElement> {\n /** Visible section header. Hidden when collapsed. */\n label?: ReactNode;\n}\n\nexport function SidebarSection({ label, className, children, ...props }: SidebarSectionProps) {\n const { collapsed } = useContext(SidebarContext);\n const labelId = useId();\n return (\n <div className={cn('mb-3', className)} {...props}>\n {label && (\n // Kept in the DOM (sr-only) while collapsed so the list stays labelled.\n <div\n id={labelId}\n className={cn(\n 'text-foreground-subtle px-4 pt-2 pb-1 text-xs font-medium',\n collapsed && 'sr-only',\n )}\n >\n {label}\n </div>\n )}\n <ul aria-labelledby={label ? labelId : undefined} className=\"flex flex-col gap-px\">\n {children}\n </ul>\n </div>\n );\n}\nSidebarSection.displayName = 'SidebarSection';\n\ninterface SidebarItemBaseProps {\n /** Lucide icon shown to the left. */\n icon?: ReactNode;\n /** Mark as the current page. */\n active?: boolean;\n /** Trailing badge / counter slot. */\n trailing?: ReactNode;\n /** Render a sub-item indented under a parent. */\n sub?: boolean;\n /**\n * Tooltip text shown while the sidebar is collapsed. Defaults to `children`\n * when that is a plain string.\n */\n tooltip?: ReactNode;\n /**\n * Render the child element (router `<Link>`) instead of `<a>`/`<button>`.\n * The child receives className, aria-current and the item content.\n */\n asChild?: boolean;\n}\n\ntype SidebarItemAnchorProps = SidebarItemBaseProps &\n AnchorHTMLAttributes<HTMLAnchorElement> & {\n /** Renders an `<a>`. Omit to render a `<button>`. */\n href: string;\n };\n\ntype SidebarItemButtonProps = SidebarItemBaseProps &\n ButtonHTMLAttributes<HTMLButtonElement> & {\n href?: undefined;\n };\n\n/** Discriminated on `href`: with it the item is an anchor, without it a button. */\nexport type SidebarItemProps = SidebarItemAnchorProps | SidebarItemButtonProps;\n\nexport const SidebarItem = forwardRef<HTMLElement, SidebarItemProps>(\n function SidebarItem(props, ref) {\n const { icon, active, trailing, sub, tooltip, asChild, className, children, ...rest } = props;\n const { collapsed } = useContext(SidebarContext);\n\n const classes = cn(\n 'flex h-8 w-full items-center gap-2 rounded-md px-2 text-sm outline-none',\n 'transition-colors duration-[var(--duration-fast)]',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n active\n ? 'bg-background-muted text-foreground font-medium'\n : 'text-foreground-muted hover:bg-background-muted hover:text-foreground',\n sub && !collapsed && 'ml-6',\n collapsed && 'justify-center',\n className,\n );\n\n const labelTitle = typeof children === 'string' ? children : undefined;\n const tip = tooltip ?? labelTitle;\n // Collapsed: keep an sr-only label so the control always has a name —\n // the Tooltip only wires aria-describedby while it is open.\n const showTooltip = collapsed && !!tip;\n\n const content = (\n <>\n {icon && <span className=\"flex shrink-0 items-center [&_svg]:size-4\">{icon}</span>}\n {collapsed ? (\n <span className=\"sr-only\">{children}</span>\n ) : (\n <span className=\"flex-1 truncate text-left\" title={labelTitle}>\n {children}\n </span>\n )}\n {!collapsed && trailing && <span className=\"ml-auto\">{trailing}</span>}\n </>\n );\n\n let element: ReactNode;\n if (asChild) {\n const { href: _href, type: _type, ...slotProps } = rest as Record<string, unknown>;\n element = (\n <Slot\n ref={ref}\n aria-current={active ? 'page' : undefined}\n className={classes}\n {...(slotProps as HTMLAttributes<HTMLElement>)}\n >\n {children && typeof children === 'object' && 'props' in (children as object)\n ? children\n : null}\n </Slot>\n );\n } else if (rest.href !== undefined) {\n const { href, ...anchorProps } = rest as Omit<\n SidebarItemAnchorProps,\n keyof SidebarItemBaseProps\n >;\n element = (\n <a\n ref={ref as Ref<HTMLAnchorElement>}\n href={href}\n aria-current={active ? 'page' : undefined}\n className={classes}\n {...anchorProps}\n >\n {content}\n </a>\n );\n } else {\n const {\n href: _href,\n type,\n ...buttonProps\n } = rest as Omit<SidebarItemButtonProps, keyof SidebarItemBaseProps>;\n element = (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type={type ?? 'button'}\n aria-current={active ? 'page' : undefined}\n className={classes}\n {...buttonProps}\n >\n {content}\n </button>\n );\n }\n\n return (\n <li className=\"px-2\">\n {showTooltip ? (\n <Tooltip label={tip} side=\"right\">\n {element}\n </Tooltip>\n ) : (\n element\n )}\n </li>\n );\n },\n);\nSidebarItem.displayName = 'SidebarItem';\n\n/** Lightweight collapsible sub-section inside the sidebar. */\nexport interface SidebarGroupProps extends Omit<HTMLAttributes<HTMLLIElement>, 'children'> {\n icon?: ReactNode;\n label: ReactNode;\n /** Initial open state (uncontrolled). */\n defaultOpen?: boolean;\n /** Controlled open state. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n children: ReactNode;\n}\n\nexport const SidebarGroup = forwardRef<HTMLLIElement, SidebarGroupProps>(function SidebarGroup(\n {\n icon,\n label,\n defaultOpen = true,\n open: controlled,\n onOpenChange,\n className,\n children,\n ...props\n },\n ref,\n) {\n const { collapsed } = useContext(SidebarContext);\n const [internal, setInternal] = useState(defaultOpen);\n const open = controlled ?? internal;\n const listId = useId();\n const toggle = () => {\n const next = !open;\n if (controlled === undefined) setInternal(next);\n onOpenChange?.(next);\n };\n if (collapsed) return <>{children}</>;\n return (\n <li ref={ref} className={className} {...props}>\n <button\n type=\"button\"\n onClick={toggle}\n aria-controls={open ? listId : undefined}\n aria-expanded={open}\n className={cn(\n 'text-foreground-muted mx-2 flex h-8 w-[calc(100%-1rem)] items-center gap-2 rounded-md px-2 text-sm outline-none',\n 'transition-colors duration-[var(--duration-fast)]',\n 'hover:bg-background-muted hover:text-foreground',\n 'focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2',\n )}\n >\n {icon && <span className=\"flex shrink-0 items-center [&_svg]:size-4\">{icon}</span>}\n <span className=\"flex-1 text-left\">{label}</span>\n <ChevronDown\n className={cn('size-3.5 transition-transform', open && 'rotate-180')}\n aria-hidden\n />\n </button>\n {open && (\n <ul id={listId} className=\"flex flex-col gap-px\">\n {children}\n </ul>\n )}\n </li>\n );\n});\nSidebarGroup.displayName = 'SidebarGroup';\n"],"names":["SidebarContext","createContext","useSidebar","useContext","Sidebar","forwardRef","defaultCollapsed","controlled","onCollapsedChange","header","footer","className","children","ariaLabel","props","ref","strings","useStrings","internal","setInternal","useState","collapsed","setCollapsed","next","jsxs","cn","jsx","ChevronsRight","ChevronsLeft","SidebarSection","label","labelId","useId","SidebarItem","icon","active","trailing","sub","tooltip","asChild","rest","classes","labelTitle","tip","showTooltip","content","Fragment","element","_href","_type","slotProps","Slot","href","anchorProps","type","buttonProps","Tooltip","SidebarGroup","defaultOpen","onOpenChange","open","listId","toggle","ChevronDown"],"mappings":"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"}