@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 @@
1
+ {"version":3,"file":"select.js","names":[],"sources":["../../../src/components/ui/select.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * Select — single-value dropdown over a fixed, bounded option list.\n *\n * Built on the Radix Select primitive with MMDS token-based styling. Size\n * variants (default/sm/xs) are layered on via a `data-size` attribute.\n */\n\nimport * as React from \"react\"\nimport {\n Select as SelectPrimitive,\n Popover as PopoverPrimitive,\n} from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\nimport { getPortalContainer } from \"@/lib/scope\"\nimport { Button } from \"@/components/ui/button\"\nimport { ChevronDownIcon, CheckIcon, ChevronUpIcon, XIcon } from \"lucide-react\"\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return (\n <SelectPrimitive.Group\n data-slot=\"select-group\"\n className={cn(\"scroll-my-1 p-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectValue({\n inlineLabel,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value> & {\n /**\n * Prefixes the value with \"{inlineLabel}: \" once `children` is given — e.g.\n * inlineLabel=\"Assignee\" + children=\"James\" renders \"Assignee: James\".\n * Only takes effect together with an explicit `children`: Select.Value\n * otherwise auto-fills from the selected Item's own text, which this\n * prefix can't attach to without replacing that auto-fill (Radix disables\n * it the moment `children` is passed at all, regardless of value) — so\n * pass the current value's own display text as `children` yourself, and\n * leave both unset (not `children={undefined}`, which still counts as\n * \"no children\" for that auto-fill) when nothing is selected.\n */\n inlineLabel?: string\n}) {\n return (\n <SelectPrimitive.Value data-slot=\"select-value\" {...props}>\n {children != null && inlineLabel ? (\n <>\n <span className=\"text-muted-foreground\">{inlineLabel}: </span>\n {children}\n </>\n ) : (\n children\n )}\n </SelectPrimitive.Value>\n )\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\" | \"xs\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md,0.375rem),10px)] data-[size=xs]:h-6 data-[size=xs]:gap-1 data-[size=xs]:rounded-[min(var(--radius-md,0.375rem),8px)] data-[size=xs]:pr-1.5 data-[size=xs]:pl-2 data-[size=xs]:text-xs *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal container={getPortalContainer()}>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n data-align-trigger={position === \"item-aligned\"}\n className={cn(\n \"relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-popover ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n data-position={position}\n className={cn(\n \"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)\",\n position === \"popper\" && \"\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-1.5 py-1 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"pointer-events-none\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <ChevronUpIcon />\n </SelectPrimitive.ScrollUpButton>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <ChevronDownIcon />\n </SelectPrimitive.ScrollDownButton>\n )\n}\n\n/**\n * SelectMultiple — checkbox-list multi-select variant of Select.\n *\n * Radix's Select primitive is single-value only (no `multiple` mode, no\n * array `value`), so this is built on Popover instead of SelectPrimitive —\n * a separate set of components, not a `multiple` prop on Select. Each\n * item's checkbox look is a decorative `aria-hidden` span, not a real\n * Checkbox — the row itself already carries the actual selected state via\n * `role=\"option\"`/`aria-selected`, so a second interactive checkbox role\n * nested inside it would be a real (axe-flagged) `nested-interactive`\n * violation, not just redundant. The trigger shows a comma-joined list of\n * selected labels\n * (falling back to `placeholder`) plus\n * a clear-all \"x\", and the popover stays open across clicks so several\n * items can be picked in one visit — unlike Combobox, there's no search\n * input and unlike Select, clicking an item never closes the list.\n */\n\ntype SelectMultipleContextValue = {\n value: string[]\n onItemSelect: (itemValue: string) => void\n clear: () => void\n labels: Map<string, string>\n registerLabel: (itemValue: string, label: string) => void\n unregisterLabel: (itemValue: string) => void\n size: \"sm\" | \"default\" | \"xs\"\n triggerRef: React.RefObject<HTMLElement | null>\n contentRef: React.RefObject<HTMLElement | null>\n /** Mirrors SelectMultiple's own `closeOnSelect` — SelectMultipleItem uses it to swap its decorative indicator from a checkbox square to a radio dot, since a checkbox otherwise visually promises \"pick as many as you want\" while this mode closes after exactly one. */\n closeOnSelect: boolean\n /**\n * The trigger's own rendered width, captured the moment the popover\n * opens — not the same as Radix's live `--radix-popover-trigger-width`\n * CSS var, which keeps tracking the trigger's *current* width for as\n * long as the popover stays open. The trigger's label (and so its own\n * width) changes as picks are made — without freezing this at open time,\n * `SelectMultipleContent`'s min-width would recompute on every pick,\n * visibly resizing the still-open popover instead of holding still.\n */\n triggerWidthOnOpen: number | undefined\n}\n\nconst SelectMultipleContext =\n React.createContext<SelectMultipleContextValue | null>(null)\n\nfunction useSelectMultipleContext(component: string) {\n const context = React.useContext(SelectMultipleContext)\n if (!context) {\n throw new Error(`${component} must be used within <SelectMultiple>.`)\n }\n return context\n}\n\nfunction SelectMultiple({\n value,\n onValueChange,\n size = \"default\",\n children,\n open: openProp,\n onOpenChange,\n closeOnSelect = false,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root> & {\n value: string[]\n onValueChange: (value: string[]) => void\n size?: \"sm\" | \"default\" | \"xs\"\n /** Closes the popover immediately after any pick, instead of staying open for more — for a single-effective-choice usage (cap `value` at one entry yourself) that still wants Popover's non-modal behavior (label stays visible, rest of the page stays interactive/scrollable) instead of Select's modal one. Default `false` — a real multi-select should stay open across picks, which is the whole reason this component exists over Select. */\n closeOnSelect?: boolean\n}) {\n const labelsRef = React.useRef(new Map<string, string>())\n const [labelsVersion, forceUpdate] = React.useReducer((n: number) => n + 1, 0)\n const triggerRef = React.useRef<HTMLElement | null>(null)\n const contentRef = React.useRef<HTMLElement | null>(null)\n\n // Uncontrolled unless the consumer passes `open` themselves (e.g. the\n // Apply/Cancel pattern) — needed so the outside-pointerdown workaround\n // below has a `setOpen` it can call directly, the same way Radix's own\n // `useControllableState` backs every other controlled/uncontrolled prop\n // in this library.\n const [internalOpen, setInternalOpen] = React.useState(false)\n const open = openProp ?? internalOpen\n const [triggerWidthOnOpen, setTriggerWidthOnOpen] = React.useState<\n number | undefined\n >(undefined)\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (next) {\n setTriggerWidthOnOpen(triggerRef.current?.getBoundingClientRect().width)\n }\n onOpenChange?.(next)\n if (openProp === undefined) setInternalOpen(next)\n },\n [onOpenChange, openProp]\n )\n\n // Radix Popover's own outside-dismiss defers to the next `click` event\n // (`deferPointerDownOutside`, hardcoded in its source) rather than\n // acting on `pointerdown` immediately — which normally doesn't matter,\n // but Radix's `Select.Trigger` calls `preventDefault()` on `pointerdown`\n // for mouse clicks, and per the Pointer Events spec that suppresses the\n // browser's follow-up `click` for that same gesture. Clicking a `Select`\n // trigger while this popover is open therefore never fires the `click`\n // Popover was waiting for, and it silently never closes. This listener\n // closes on `pointerdown` itself instead of waiting for a `click` that\n // might not come — Radix's own dismiss logic keeps running too, it's\n // just redundant (and harmless) on the paths where the `click` does\n // arrive normally.\n React.useEffect(() => {\n function handlePointerDown(event: PointerEvent) {\n const contentEl = contentRef.current\n if (!contentEl || contentEl.getAttribute(\"data-state\") !== \"open\") return\n const target = event.target\n if (!(target instanceof Node)) return\n if (contentEl.contains(target)) return\n if (triggerRef.current?.contains(target)) return\n setOpen(false)\n }\n document.addEventListener(\"pointerdown\", handlePointerDown)\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown)\n }, [setOpen])\n\n const registerLabel = React.useCallback(\n (itemValue: string, label: string) => {\n labelsRef.current.set(itemValue, label)\n forceUpdate()\n },\n []\n )\n const unregisterLabel = React.useCallback((itemValue: string) => {\n labelsRef.current.delete(itemValue)\n forceUpdate()\n }, [])\n const onItemSelect = React.useCallback(\n (itemValue: string) => {\n onValueChange(\n value.includes(itemValue)\n ? value.filter((v) => v !== itemValue)\n : [...value, itemValue]\n )\n if (closeOnSelect) setOpen(false)\n },\n [value, onValueChange, closeOnSelect, setOpen]\n )\n const clear = React.useCallback(() => onValueChange([]), [onValueChange])\n\n const context = React.useMemo<SelectMultipleContextValue>(\n () => ({\n value,\n onItemSelect,\n clear,\n labels: labelsRef.current,\n registerLabel,\n unregisterLabel,\n size,\n triggerRef,\n contentRef,\n closeOnSelect,\n triggerWidthOnOpen,\n }),\n [\n value,\n onItemSelect,\n clear,\n registerLabel,\n unregisterLabel,\n labelsVersion,\n size,\n closeOnSelect,\n triggerWidthOnOpen,\n ]\n )\n\n return (\n <SelectMultipleContext.Provider value={context}>\n <PopoverPrimitive.Root\n data-slot=\"select-multiple\"\n open={open}\n onOpenChange={setOpen}\n {...props}\n >\n {children}\n </PopoverPrimitive.Root>\n </SelectMultipleContext.Provider>\n )\n}\n\n/** Shows only the first selected label — ellipsis-truncated at a character cap, applied whether or not anything else is selected, since the label alone can be too long to show whole in a `w-fit` trigger with no width of its own to truncate against — plus \"+N\" for the rest once there's more than one. No cap: the first label in full, still just the first. */\nfunction buildMultiValueLabel(\n value: string[],\n labels: Map<string, React.ReactNode>,\n maxChars: number | undefined\n) {\n if (value.length === 0) return \"\"\n const [first, ...rest] = value.map((v) => String(labels.get(v) ?? v))\n const shown =\n maxChars !== undefined && first.length > maxChars\n ? `${first.slice(0, maxChars)}…`\n : first\n return rest.length > 0 ? `${shown} +${rest.length}` : shown\n}\n\nfunction SelectMultipleTrigger({\n className,\n placeholder,\n disabled,\n maxLabelChars,\n inlineLabel,\n ...props\n}: Omit<React.ComponentProps<typeof PopoverPrimitive.Trigger>, \"children\"> & {\n placeholder?: React.ReactNode\n /** Character cap on the one label the trigger ever shows (only the first selected value — every additional selection folds into a trailing \"+N\", never listed by name). Applies even with a single value selected, since a lone long value can blow out the trigger just as badly as a long list would. Unset (default): that first label in full, however long. */\n maxLabelChars?: number\n /** Prefixes the value with \"{inlineLabel}: \" once something's selected — e.g. inlineLabel=\"Assignee\" + one pick renders \"Assignee: James\" instead of just \"James\". `placeholder` still shows alone (no prefix) while nothing is. */\n inlineLabel?: string\n}) {\n const { value, labels, clear, size, triggerRef } = useSelectMultipleContext(\n \"SelectMultipleTrigger\"\n )\n const hasValue = value.length > 0\n const valueLabel = buildMultiValueLabel(value, labels, maxLabelChars)\n\n return (\n // One real Popover.Trigger around the whole visible box (via\n // `asChild`, so it renders as this `<div>` instead of a `<button>` —\n // required since the clear button below is a real nested `<button>`,\n // and a button can't nest inside another button) — not `role=\"button\"`\n // bolted onto a span, and not split across multiple inner triggers\n // (a chevron-only one, a text-only one) that left the rest of the\n // box's own padding non-interactive. `asChild` on Trigger still also\n // serves as the anchor for `--radix-popover-trigger-width` (read by\n // SelectMultipleContent), matching this trigger's full rendered\n // width — clear button and chevron included, not some narrower\n // sub-region of it.\n <PopoverPrimitive.Trigger disabled={disabled} asChild {...props}>\n <div\n ref={triggerRef as React.RefObject<HTMLDivElement>}\n data-slot=\"select-multiple-trigger\"\n data-size={size}\n data-placeholder={hasValue ? undefined : \"\"}\n // Radix's Popover.Trigger assumes it's rendering a real `<button>`\n // for focusability/Enter-Space activation — true by default, but\n // lost the moment `asChild` swaps it for this `<div>` (required\n // above so the clear button can nest inside without two buttons\n // nesting). `role`/`tabIndex`/`onKeyDown` below manually restore\n // exactly what a native button would have given for free.\n role=\"button\"\n // Popover.Trigger unconditionally sets aria-haspopup=\"dialog\" on\n // whatever it clones onto — Radix Slot lets a child's own explicit\n // prop win over the same key from the slot, so setting it here\n // overrides that. This popup is a checkable options list, not a\n // dialog; misreporting it tells AT the wrong thing about what\n // follows.\n aria-haspopup=\"listbox\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled || undefined}\n onKeyDown={(event) => {\n if (disabled) return\n // Guards against the clear button's own Enter/Space activation\n // (a real nested `<button>`) bubbling up to this handler too —\n // without it, clearing via keyboard would also immediately\n // reopen the popover right after, same fix `RowActions`/Radix's\n // own Tabs.Trigger apply for the identical bubbling reason.\n if (event.target !== event.currentTarget) return\n if (event.key !== \"Enter\" && event.key !== \" \") return\n event.preventDefault()\n event.currentTarget.click()\n }}\n className={cn(\n \"group flex w-fit items-center gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md,0.375rem),10px)] data-[size=xs]:h-6 data-[size=xs]:gap-1 data-[size=xs]:rounded-[min(var(--radius-md,0.375rem),8px)] data-[size=xs]:pr-1.5 data-[size=xs]:pl-2 data-[size=xs]:text-xs dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n disabled ? \"cursor-not-allowed opacity-50\" : \"cursor-pointer\",\n className\n )}\n aria-invalid={props[\"aria-invalid\"]}\n >\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {hasValue ? (\n <>\n {inlineLabel && (\n <span className=\"text-muted-foreground\">{inlineLabel}: </span>\n )}\n {valueLabel}\n </>\n ) : (\n placeholder\n )}\n </span>\n {hasValue && !disabled && (\n // A real Button (not a bare `<button>`) — it's the only thing that\n // hits the 24×24 target-size floor (SC 2.5.8) and a real focus-visible\n // ring (2.4.7) for free, same as ComboboxClear's identical pattern.\n // `stopPropagation` keeps this click from also reaching the\n // trigger div wrapping it, which would otherwise immediately\n // toggle the popover open again right as it's being cleared.\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n iconOnly\n aria-label=\"Clear selection\"\n onClick={(event) => {\n event.stopPropagation()\n clear()\n }}\n className=\"shrink-0 text-muted-foreground\"\n >\n <XIcon className=\"pointer-events-none\" />\n </Button>\n )}\n {/* Selecting/clearing items happens with focus still inside the\n popover, not on this trigger — the visible label text above\n updates in place with no live region, so a screen reader user\n never hears the running count change until they close the\n popover and re-read the trigger. This mirrors the same visible\n text into a status region instead of duplicating it visibly. */}\n <span role=\"status\" className=\"sr-only\">\n {hasValue ? `${value.length} selected` : \"None selected\"}\n </span>\n <ChevronDownIcon\n aria-hidden=\"true\"\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-180\"\n />\n </div>\n </PopoverPrimitive.Trigger>\n )\n}\n\nfunction SelectMultipleContent({\n className,\n align = \"start\",\n sideOffset = 4,\n children,\n style,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n const { size, contentRef, triggerWidthOnOpen } = useSelectMultipleContext(\n \"SelectMultipleContent\"\n )\n\n // A `SelectMultipleFooter` (if present) renders as a sibling of the\n // listbox `<div>` below, not inside it — nesting non-`option` footer\n // buttons inside `role=\"listbox\"` would be an ARIA violation the same way\n // a checkbox nested inside a `role=\"option\"` already is (see\n // `SelectMultipleItem`'s own comment above). Every other child (the real\n // `SelectMultipleItem`s) still goes into the listbox as before — this\n // pulls the footer out without changing anything for a consumer that\n // never renders one.\n const childArray = React.Children.toArray(children)\n const isFooter = (child: React.ReactNode) =>\n React.isValidElement(child) && child.type === SelectMultipleFooter\n const footer = childArray.filter(isFooter)\n const items = childArray.filter((child) => !isFooter(child))\n\n return (\n <PopoverPrimitive.Portal container={getPortalContainer()} forceMount>\n <PopoverPrimitive.Content\n ref={contentRef as React.RefObject<HTMLDivElement>}\n data-slot=\"select-multiple-content\"\n data-size={size}\n forceMount\n align={align}\n sideOffset={sideOffset}\n className={cn(\n // Standard width range — 240px floor, 400px ceiling — regardless\n // of the trigger, unless a designer overrides via `className`\n // (a later `min-w-*`/`max-w-*` in that string wins the same way\n // it would against any other Tailwind utility here, since these\n // are the same conflict groups tailwind-merge already\n // recognizes). The floor still grows to match a genuinely wider\n // trigger (a toolbar filter chip's own rendered width, via\n // `--trigger-width-on-open` below) rather than clipping every\n // item's text to a fixed 240px box regardless of how long the\n // real values are — `max(...)`, not a straight swap, so whichever\n // of the two is actually larger wins. The ceiling composes with\n // Radix's own collision-avoidance size the same way — `min(...)`\n // so a narrow viewport still wins over the 400px default instead\n // of pushing the popover off-screen; `truncate` below is what\n // actually clips the text once content hits whichever ceiling\n // applies. `--trigger-width-on-open` (set below) is `SelectMultiple`'s\n // own one-time capture of the trigger's width when it opens — not\n // a live `--radix-popover-trigger-width` class, which tracks the\n // trigger's *current* width and would otherwise visibly resize\n // this popover on every pick as that live width changes.\n \"z-50 max-h-(--radix-popover-content-available-height) max-w-[min(400px,var(--radix-popover-content-available-width))] min-w-[max(240px,var(--trigger-width-on-open,0px))] origin-(--radix-popover-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-popover ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[size=xs]:p-0.5 data-[state=closed]:hidden data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n className\n )}\n style={{\n ...(triggerWidthOnOpen !== undefined && {\n \"--trigger-width-on-open\": `${triggerWidthOnOpen}px`,\n }),\n ...style,\n }}\n {...props}\n >\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n className=\"contents\"\n // A role=\"listbox\" of role=\"option\"s reads to both sighted users\n // and AT as arrow-key/Home/End navigable — same model as this\n // library's own Radix-backed Select/Combobox — but nothing wired\n // that up here; only Tab moved focus, one item at a time. This\n // doesn't change the existing per-item tabIndex=0 (Tab still\n // reaches every item individually) — it only adds the arrow-key\n // path on top, since removing Tab-stops would be a bigger,\n // separately-scoped behavior change.\n onKeyDown={(event) => {\n if (![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key))\n return\n const options = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>(\n '[role=\"option\"]:not([data-disabled])'\n )\n )\n if (options.length === 0) return\n const currentIndex = options.indexOf(\n document.activeElement as HTMLElement\n )\n event.preventDefault()\n const nextIndex =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? options.length - 1\n : event.key === \"ArrowDown\"\n ? currentIndex < 0\n ? 0\n : (currentIndex + 1) % options.length\n : currentIndex < 0\n ? options.length - 1\n : (currentIndex - 1 + options.length) % options.length\n options[nextIndex]?.focus()\n }}\n >\n {items}\n </div>\n {footer}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n )\n}\n\n/**\n * Optional Cancel/Apply footer for `SelectMultipleContent` — pass a\n * controlled `open` to `SelectMultiple` itself (see its own comment) and\n * feed it a local pending draft instead of the real `value`/`onValueChange`\n * while open, so picks only land for real once Apply commits that draft;\n * Cancel just closes, discarding it. Renders as a sibling of the listbox,\n * never inside it — see `SelectMultipleContent`'s own comment for why.\n */\nfunction SelectMultipleFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n const { size } = useSelectMultipleContext(\"SelectMultipleFooter\")\n return (\n <div\n data-slot=\"select-multiple-footer\"\n className={cn(\n // Edge-to-edge divider against `SelectMultipleContent`'s own\n // padding (`p-1`, or `p-0.5` at `size=\"xs\"`) — same bleed/pad-back-in\n // trick as the Columns menu's footer — only the border reaches the\n // popover's true left/right edges; the buttons stay padded back in\n // to that same inset instead of sitting flush against it too.\n \"mt-1 flex items-center justify-end gap-1 border-t border-border pt-1.5\",\n size === \"xs\"\n ? \"-mx-0.5 w-[calc(100%+--spacing(1))] px-0.5\"\n : \"-mx-1 w-[calc(100%+--spacing(2))] px-1\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SelectMultipleGroup({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"select-multiple-group\"\n role=\"group\"\n className={cn(\"scroll-my-1 p-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectMultipleLabel({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"select-multiple-label\"\n className={cn(\"px-1.5 py-1 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectMultipleItem({\n className,\n children,\n value: itemValue,\n textValue,\n disabled,\n onClick,\n onKeyDown,\n ...props\n}: Omit<React.ComponentProps<\"div\">, \"onSelect\"> & {\n value: string\n textValue?: string\n disabled?: boolean\n}) {\n const {\n value,\n onItemSelect,\n registerLabel,\n unregisterLabel,\n size,\n closeOnSelect,\n } = useSelectMultipleContext(\"SelectMultipleItem\")\n const checked = value.includes(itemValue)\n\n React.useEffect(() => {\n registerLabel(\n itemValue,\n textValue ?? (typeof children === \"string\" ? children : itemValue)\n )\n return () => unregisterLabel(itemValue)\n }, [itemValue, textValue, children, registerLabel, unregisterLabel])\n\n const select = () => {\n if (disabled) return\n onItemSelect(itemValue)\n }\n\n return (\n <div\n data-slot=\"select-multiple-item\"\n role=\"option\"\n aria-selected={checked}\n aria-disabled={disabled}\n data-disabled={disabled ? \"\" : undefined}\n data-size={size}\n tabIndex={disabled ? -1 : 0}\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-md py-1.5 pr-1.5 pl-1.5 text-sm outline-hidden select-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[size=sm]:py-1 data-[size=xs]:gap-1.5 data-[size=xs]:py-0.5 data-[size=xs]:text-xs data-disabled:pointer-events-none data-disabled:opacity-50\",\n className\n )}\n onClick={(e) => {\n onClick?.(e)\n select()\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e)\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault()\n select()\n }\n }}\n {...props}\n >\n <span\n aria-hidden=\"true\"\n data-slot=\"select-multiple-item-checkbox\"\n className={cn(\n \"relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors\",\n // `closeOnSelect` means this is standing in for a single-effective-\n // choice pick (see SelectMultiple's own doc comment) — a checkbox\n // square visually promises \"pick as many as you want\", which is\n // exactly wrong there, so it renders as a radio dot instead.\n closeOnSelect && \"rounded-full\",\n checked &&\n (closeOnSelect\n ? \"border-primary\"\n : \"border-primary bg-primary text-primary-foreground\"),\n disabled && \"opacity-50\"\n )}\n >\n {checked &&\n (closeOnSelect ? (\n <span className=\"size-2 rounded-full bg-primary\" />\n ) : (\n <CheckIcon className=\"size-3.5\" />\n ))}\n </span>\n <span className=\"inline-flex min-w-0 flex-1 items-center gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\">\n {/*\n `truncate` (overflow:hidden + text-overflow:ellipsis +\n white-space:nowrap) never actually ellipsizes on the element that\n declares it a flex container for its own children — confirmed\n directly (an isolated flex/inline-flex span with a bare text\n child doesn't clip *or* ellipsize, only a non-flex block does).\n The outer span above has to stay flex to lay out an icon beside\n text (see the WithIcon story); wrapping bare-string children in\n this plain (non-flex) inner span is what actually makes ellipsis\n render for the common case. Skipped for non-string children\n (WithSubinfo's two-line label, WithIcon's icon+text) — those\n already own their own layout, and forcing `white-space:nowrap`\n onto WithSubinfo's intentionally-two-line content would break it.\n */}\n {typeof children === \"string\" ? (\n <span className=\"min-w-0 flex-1 truncate\">{children}</span>\n ) : (\n children\n )}\n </span>\n </div>\n )\n}\n\nfunction SelectMultipleSeparator({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"select-multiple-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n SelectMultiple,\n SelectMultipleContent,\n SelectMultipleFooter,\n SelectMultipleGroup,\n SelectMultipleItem,\n SelectMultipleLabel,\n SelectMultipleSeparator,\n SelectMultipleTrigger,\n}\n\n/**\n * WHEN TO USE\n * - Picking one value from a short, known, bounded list (settings, filters, form fields).\n * - Options need grouping (SelectGroup + SelectLabel) or per-item disabling.\n *\n * NOT WHEN\n * - The list is long enough to need type-to-filter — use Combobox instead.\n * - Multiple values from a list that also needs search/filter — use Combobox's multi-select mode.\n * - Native OS picker behavior (better on mobile, zero extra JS) is preferable — use NativeSelect instead.\n *\n * KEY RULES\n * - SelectTrigger's `size` is \"default\" | \"sm\" | \"xs\" (default \"default\"); controls trigger\n * height (h-8/h-7/h-6) and text size — same default/sm/xs vocabulary as Button/Item/\n * Attachment/Tabs, not Select-specific naming.\n * - SelectContent portals its content; `position=\"item-aligned\"` (default) aligns to the trigger like a native select, `position=\"popper\"` behaves like a standard popover.\n * - Every SelectItem needs a `value`; the check indicator renders automatically for the selected item.\n * - Put SelectSeparator between SelectGroups, not inside one.\n * - SelectValue with no `children` auto-fills from the selected Item's own text — that's the\n * normal, no-`inlineLabel` usage below. For \"Label: Value\" (e.g. \"Assignee: James\"), give\n * SelectValue both `inlineLabel` and the current value's display text as `children` yourself —\n * the auto-fill only runs with zero children, so a label prefix can't attach to it in place.\n * - An AI-filled value is a plain composition, not a dedicated prop, and the same shape as\n * Input's and Textarea's: put `AILabel` in the label row as a sibling of FieldLabel — never\n * beside or inside SelectTrigger, which is itself a `<button>` (a button inside a button is\n * invalid HTML, and would also open the listbox on every click of the marker) — while the\n * value still matches what AI picked. Pass AILabel `edited={value !== aiValue}` and an\n * `onRevert` that restores it, so picking a different value turns the marker into a ghost undo\n * button (AILabel's own override/undo morph, same as Input/Textarea/Checkbox/RadioGroup). See\n * Forms/Select.\n *\n * USAGE\n * <Select>\n * <SelectTrigger className=\"w-56\">\n * <SelectValue placeholder=\"Select a spice\" />\n * </SelectTrigger>\n * <SelectContent>\n * <SelectItem value=\"turmeric\">Turmeric</SelectItem>\n * <SelectItem value=\"cardamom\">Cardamom</SelectItem>\n * </SelectContent>\n * </Select>\n *\n * // Inline-labeled trigger — \"Spice: Turmeric\" once a value is picked, plain\n * // placeholder (\"Select a spice\") while nothing is\n * <Select value={value} onValueChange={setValue}>\n * <SelectTrigger className=\"w-56\">\n * <SelectValue placeholder=\"Select a spice\" inlineLabel=\"Spice\">\n * {value || undefined}\n * </SelectValue>\n * </SelectTrigger>\n * <SelectContent>\n * <SelectItem value=\"turmeric\">Turmeric</SelectItem>\n * <SelectItem value=\"cardamom\">Cardamom</SelectItem>\n * </SelectContent>\n * </Select>\n *\n * // Grouped, with a disabled item\n * <Select defaultValue=\"cumin\">\n * <SelectTrigger className=\"w-56\"><SelectValue placeholder=\"Select a spice\" /></SelectTrigger>\n * <SelectContent>\n * <SelectGroup>\n * <SelectLabel>Whole</SelectLabel>\n * <SelectItem value=\"cardamom\">Cardamom pod</SelectItem>\n * </SelectGroup>\n * <SelectSeparator />\n * <SelectGroup>\n * <SelectLabel>Ground</SelectLabel>\n * <SelectItem value=\"turmeric\">Turmeric</SelectItem>\n * <SelectItem value=\"saffron\" disabled>Saffron (out of stock)</SelectItem>\n * </SelectGroup>\n * </SelectContent>\n * </Select>\n *\n * ---\n *\n * SelectMultiple — checkbox-list multi-select, no search/filter (see the\n * doc block above SelectMultiple's definition for why this is a separate\n * component tree rather than a `multiple` prop on Select).\n *\n * WHEN TO USE (SelectMultiple)\n * - Picking several values from a short, known, bounded list where a search box\n * would be overkill — settings toggles, tag pickers, filter panels.\n *\n * NOT WHEN (SelectMultiple)\n * - The list is long enough to need type-to-filter — use Combobox's `multiple` mode instead.\n *\n * KEY RULES (SelectMultiple)\n * - `value`/`onValueChange` are required and always an array — there is no uncontrolled mode.\n * - `size` (\"default\" | \"sm\" | \"xs\", default \"default\") is set ONCE on SelectMultiple itself,\n * not on Trigger or Content — it flows to both via context (Content is portaled, so it's\n * never a CSS descendant of Trigger; a `group-data-[size]` selector couldn't reach it, which\n * is why this is context-driven instead of the group/data-attribute trick Select/Tabs use).\n * Trigger height/text and Content/Item padding/text/gap all scale together from this one prop.\n * - The trigger shows only the first selected item's label (auto-collected from mounted\n * SelectMultipleItems; pass `textValue` on an item if its children aren't plain text — e.g.\n * an item with a leading icon or a secondary description line) plus \"+N\" once more than one\n * is selected — never every label listed by name. Falls back to `placeholder` when empty,\n * plus a clear-all \"x\" once non-empty. Pass `maxLabelChars` on SelectMultipleTrigger to\n * ellipsis-truncate that one label past a character cap — applies even with a single value\n * selected, since one long label can blow out a `w-fit` trigger same as a long list would\n * (e.g. a narrow toolbar filter trigger). Pass\n * `inlineLabel` to prefix the non-empty value with \"{inlineLabel}: \" (e.g. \"Assignee: James\") —\n * `placeholder` alone still covers the empty state, no prefix there.\n * - Clicking a SelectMultipleItem toggles it and leaves the popover open — this is the whole\n * point of the variant; it never auto-closes on select the way Select/Combobox do. Pass\n * `closeOnSelect` on SelectMultiple to close after any pick instead — for a single-effective-\n * choice usage (cap `value` at one entry yourself) that still wants this component's non-modal\n * Popover behavior (label stays visible while open, rest of the page stays interactive/\n * scrollable) instead of Select's modal one. Don't reach for this as a general Select\n * replacement — Select's native form participation, typeahead, and modality are worth keeping\n * for ordinary form fields; this is for the specific case where a filter/action control needs\n * to coexist non-modally with other controls the user is actively using (see DataTable's\n * `singleSelect` inline filter for a real example). Also swaps every SelectMultipleItem's\n * decorative indicator from a checkbox square to a radio dot — a checkbox otherwise visually\n * promises \"pick as many as you want\", which is exactly wrong once picking one closes it.\n * - SelectMultipleGroup/SelectMultipleLabel/SelectMultipleSeparator mirror Select's grouping API.\n * - SelectMultiple forwards Radix Popover.Root's own props (`open`/`onOpenChange`/`defaultOpen`\n * etc.) — useful for the Apply/Cancel pattern below, where something other than a plain click\n * needs to control when the popover closes.\n * - SelectMultipleContent/Portal use `forceMount` and hide via `data-[state=closed]:hidden` (a plain\n * `display:none`) instead of letting Radix unmount on close — items must stay mounted while\n * closed so their labels are already registered for the trigger's very first render, before\n * the popover has ever been opened. `hidden` (not `invisible`) matters here specifically:\n * `visibility:hidden` on the inner Content still lets Radix's outer popper-position wrapper\n * div keep its layout box, which then silently intercepts clicks meant for elements behind\n * it; `display:none` collapses that wrapper to nothing.\n *\n * USAGE\n * const [value, setValue] = React.useState<string[]>([\"cardamom\"])\n * <SelectMultiple value={value} onValueChange={setValue}>\n * <SelectMultipleTrigger className=\"w-56\" placeholder=\"Select spices\" />\n * <SelectMultipleContent>\n * <SelectMultipleItem value=\"turmeric\">Turmeric</SelectMultipleItem>\n * <SelectMultipleItem value=\"cardamom\">Cardamom</SelectMultipleItem>\n * <SelectMultipleItem value=\"chili\">Chili</SelectMultipleItem>\n * </SelectMultipleContent>\n * </SelectMultiple>\n *\n * // Dense popover — one prop scales trigger height AND item padding/text together\n * <SelectMultiple value={value} onValueChange={setValue} size=\"xs\">\n * <SelectMultipleTrigger className=\"w-48\" placeholder=\"Select spices\" />\n * <SelectMultipleContent>...</SelectMultipleContent>\n * </SelectMultiple>\n *\n * // With an icon or a secondary description line — SelectMultipleItem's children is any\n * // ReactNode; pass `textValue` so the trigger's comma-list still shows plain text\n * <SelectMultipleItem value=\"cardamom\" textValue=\"Cardamom\">\n * <LeafIcon />\n * <span className=\"flex flex-col\">\n * Cardamom\n * <span className=\"text-xs text-muted-foreground\">Whole pods</span>\n * </span>\n * </SelectMultipleItem>\n *\n * // With search — filter by hiding non-matches, NOT by unmounting them: an unmounted\n * // SelectMultipleItem unregisters its label, so a selected-but-filtered-out item would\n * // fall back to showing its raw value in the trigger instead of its real label.\n * const [query, setQuery] = React.useState(\"\")\n * <SelectMultipleContent>\n * <Input value={query} onChange={(e) => setQuery(e.target.value)} placeholder=\"Search...\" className=\"mb-1\" />\n * {spices.map((spice) => (\n * <SelectMultipleItem\n * key={spice}\n * value={spice}\n * className={cn(!spice.toLowerCase().includes(query.toLowerCase()) && \"hidden\")}\n * >\n * {spice}\n * </SelectMultipleItem>\n * ))}\n * </SelectMultipleContent>\n *\n * // \"Add option\" (creatable) — the consumer already owns the list of items being mapped\n * // over, so a no-results affordance is just appending to that list, same as any\n * // Combobox-style creatable pattern; SelectMultiple needs no API for this.\n * {query && !spices.some((s) => s.toLowerCase() === query.toLowerCase()) && (\n * <button onClick={() => { setSpices((prev) => [...prev, query]); setValue((prev) => [...prev, query]) }}>\n * Add \"{query}\"\n * </button>\n * )}\n *\n * // With a footer (Cancel | Apply) — stage picks in a local draft, only commit on Apply;\n * // Cancel just closes without touching the real value. Uses the forwarded `open` prop.\n * const [open, setOpen] = React.useState(false)\n * const [applied, setApplied] = React.useState<string[]>([])\n * const [draft, setDraft] = React.useState<string[]>(applied)\n * <SelectMultiple\n * value={draft}\n * onValueChange={setDraft}\n * open={open}\n * onOpenChange={(next) => { if (next) setDraft(applied); setOpen(next) }}\n * >\n * <SelectMultipleTrigger className=\"w-56\" placeholder=\"Select spices\" />\n * <SelectMultipleContent>\n * {spices.map((spice) => <SelectMultipleItem key={spice} value={spice}>{spice}</SelectMultipleItem>)}\n * <SelectMultipleSeparator />\n * <div className=\"flex justify-end gap-1 p-1\">\n * <Button size=\"sm\" variant=\"ghost\" onClick={() => { setDraft(applied); setOpen(false) }}>Cancel</Button>\n * <Button size=\"sm\" onClick={() => { setApplied(draft); setOpen(false) }}>Apply</Button>\n * </div>\n * </SelectMultipleContent>\n * </SelectMultiple>\n *\n * // \"Select all\" — a plain composition using the same Checkbox, no dedicated API:\n * <Checkbox\n * checked={value.length === 0 ? false : value.length === allValues.length ? true : \"indeterminate\"}\n * onCheckedChange={(c) => setValue(c ? allValues : [])}\n * />\n */\n"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Separator — one-pixel divider.
3
+ *
4
+ * Built on the Radix Separator primitive, drawn from the `--color-border`
5
+ * token rather than a hardcoded gray.
6
+ */
7
+ import * as React from "react";
8
+ import { Separator as SeparatorPrimitive } from "radix-ui";
9
+ declare function Separator({ className, orientation, decorative, ...props }: React.ComponentProps<typeof SeparatorPrimitive.Root>): React.JSX.Element;
10
+ export { Separator };
11
+ /**
12
+ * WHEN TO USE
13
+ * - Dividing related items within a card, menu, dropdown, or toolbar.
14
+ *
15
+ * NOT WHEN
16
+ * - Marking a major page boundary — use a heading or a Card edge instead;
17
+ * a hairline reads as too subtle for that weight of division.
18
+ * - Just adding visual space — use gap/margin utilities, not a rule line.
19
+ *
20
+ * KEY RULES
21
+ * - `orientation="vertical"` needs an explicit height from its flex/grid
22
+ * container — the element itself has no intrinsic height.
23
+ * - `decorative` defaults to true (role="none", hidden from assistive tech).
24
+ * Only set it false if the separator is semantically meaningful content,
25
+ * not just a visual rule.
26
+ *
27
+ * USAGE
28
+ * <Separator />
29
+ * <Separator orientation="vertical" className="h-6" />
30
+ */
31
+ //# sourceMappingURL=separator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"separator.d.ts","sourceRoot":"","sources":["../../../src/components/ui/separator.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAI1D,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,WAA0B,EAC1B,UAAiB,EACjB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,IAAI,CAAC,qBAatD;AAED,OAAO,EAAE,SAAS,EAAE,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;GAmBG"}
@@ -0,0 +1,38 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import "react";
3
+ import { Separator as Separator$1 } from "radix-ui";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/ui/separator.tsx
6
+ function Separator({ className, orientation = "horizontal", decorative = true, ...props }) {
7
+ return /* @__PURE__ */ jsx(Separator$1.Root, {
8
+ "data-slot": "separator",
9
+ decorative,
10
+ orientation,
11
+ className: cn("shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch", className),
12
+ ...props
13
+ });
14
+ }
15
+ /**
16
+ * WHEN TO USE
17
+ * - Dividing related items within a card, menu, dropdown, or toolbar.
18
+ *
19
+ * NOT WHEN
20
+ * - Marking a major page boundary — use a heading or a Card edge instead;
21
+ * a hairline reads as too subtle for that weight of division.
22
+ * - Just adding visual space — use gap/margin utilities, not a rule line.
23
+ *
24
+ * KEY RULES
25
+ * - `orientation="vertical"` needs an explicit height from its flex/grid
26
+ * container — the element itself has no intrinsic height.
27
+ * - `decorative` defaults to true (role="none", hidden from assistive tech).
28
+ * Only set it false if the separator is semantically meaningful content,
29
+ * not just a visual rule.
30
+ *
31
+ * USAGE
32
+ * <Separator />
33
+ * <Separator orientation="vertical" className="h-6" />
34
+ */
35
+ //#endregion
36
+ export { Separator };
37
+
38
+ //# sourceMappingURL=separator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"separator.js","names":[],"sources":["../../../src/components/ui/separator.tsx"],"sourcesContent":["/**\n * Separator — one-pixel divider.\n *\n * Built on the Radix Separator primitive, drawn from the `--color-border`\n * token rather than a hardcoded gray.\n */\n\nimport * as React from \"react\"\nimport { Separator as SeparatorPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n\n/**\n * WHEN TO USE\n * - Dividing related items within a card, menu, dropdown, or toolbar.\n *\n * NOT WHEN\n * - Marking a major page boundary — use a heading or a Card edge instead;\n * a hairline reads as too subtle for that weight of division.\n * - Just adding visual space — use gap/margin utilities, not a rule line.\n *\n * KEY RULES\n * - `orientation=\"vertical\"` needs an explicit height from its flex/grid\n * container — the element itself has no intrinsic height.\n * - `decorative` defaults to true (role=\"none\", hidden from assistive tech).\n * Only set it false if the separator is semantically meaningful content,\n * not just a visual rule.\n *\n * USAGE\n * <Separator />\n * <Separator orientation=\"vertical\" className=\"h-6\" />\n */\n"],"mappings":";;;;;AAYA,SAAS,UAAU,EACjB,WACA,cAAc,cACd,aAAa,MACb,GAAG,SACoD;CACvD,OACE,oBAAC,YAAmB,MAApB;EACE,aAAU;EACE;EACC;EACb,WAAW,GACT,wKACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Sheet — panel that slides in from a screen edge, keeping page context visible.
3
+ *
4
+ * Same modal mechanics as Dialog, but renders as an edge-anchored panel
5
+ * instead of a centered one — a "Dialog with a side", built on the Radix
6
+ * Dialog primitive. `side` controls which edge it enters from: top, right
7
+ * (default), bottom, left.
8
+ */
9
+ import * as React from "react";
10
+ import { Dialog as SheetPrimitive } from "radix-ui";
11
+ declare function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>): React.JSX.Element;
12
+ declare function SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>): React.JSX.Element;
13
+ declare function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>): React.JSX.Element;
14
+ declare function SheetContent({ className, children, side, showCloseButton, fullWidth, bordered, ...props }: React.ComponentProps<typeof SheetPrimitive.Content> & {
15
+ side?: "top" | "right" | "bottom" | "left";
16
+ showCloseButton?: boolean;
17
+ /** Fills the whole viewport width (`left`/`right` only — `top`/`bottom` already do) instead of capping at `@sm:max-w-sm`. For sheets used as detail panes rather than drawers. */
18
+ fullWidth?: boolean;
19
+ /** Draws the edge border on the side facing the page — default `true`. `false` for a borderless pane. */
20
+ bordered?: boolean;
21
+ }): React.JSX.Element;
22
+ declare function SheetHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
23
+ declare function SheetFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
24
+ declare function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>): React.JSX.Element;
25
+ declare function SheetDescription({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Description>): React.JSX.Element;
26
+ export { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription, };
27
+ /**
28
+ * WHEN TO USE
29
+ * - A detail view, filter panel, or settings the user returns from without navigating away
30
+ * - Content that should stay anchored to an edge while page context remains visible behind it
31
+ *
32
+ * NOT WHEN
33
+ * - Destructive confirmation — use AlertDialog
34
+ * - Touch-drag bottom sheets — use Drawer (built for the swipe-to-dismiss gesture)
35
+ * - A full task flow with its own navigation — use a page, not a Sheet
36
+ *
37
+ * KEY RULES
38
+ * - `side` defaults to "right"; left/right cap at `@sm:max-w-sm` (a container query against the shared portal container — see Dialog's own doc comment for why), top/bottom are full-width and auto-height
39
+ * - `fullWidth` (left/right only) fills the viewport instead of capping at `@sm:max-w-sm`, and `bordered={false}` drops the edge border — for a Sheet standing in as a detail pane rather than a drawer
40
+ * - `showCloseButton` defaults to true — the close X sits top-right of the panel
41
+ * - SheetHeader/SheetFooter carry their own padding; content between them needs its own (e.g. `px-4`)
42
+ * - Same dismiss behavior as Dialog: Escape and backdrop click close it
43
+ *
44
+ * USAGE
45
+ * <Sheet>
46
+ * <SheetTrigger asChild><Button variant="outline">Open sheet</Button></SheetTrigger>
47
+ * <SheetContent>
48
+ * <SheetHeader>
49
+ * <SheetTitle>Edit profile</SheetTitle>
50
+ * <SheetDescription>Update your details, then save to apply them.</SheetDescription>
51
+ * </SheetHeader>
52
+ * <SheetFooter><Button>Save changes</Button></SheetFooter>
53
+ * </SheetContent>
54
+ * </Sheet>
55
+ *
56
+ * // Enter from a specific edge
57
+ * <SheetContent side="left">...</SheetContent>
58
+ */
59
+ //# sourceMappingURL=sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../src/components/ui/sheet.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,UAAU,CAAA;AAOnD,iBAAS,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,IAAI,CAAC,qBAE5E;AAED,iBAAS,YAAY,CAAC,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,qBAErD;AAED,iBAAS,UAAU,CAAC,EAClB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,KAAK,CAAC,qBAEnD;AA8BD,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,QAAQ,EACR,IAAc,EACd,eAAsB,EACtB,SAAiB,EACjB,QAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,GAAG;IACvD,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,kLAAkL;IAClL,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,qBAoCA;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAUxE;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,KAAK,CAAC,qBAQnD;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,cAAc,CAAC,WAAW,CAAC,qBAQzD;AAED,OAAO,EACL,KAAK,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,GACjB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG"}
@@ -0,0 +1,128 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import { getPortalContainer } from "../../lib/scope.js";
3
+ import { Button } from "./button.js";
4
+ import "react";
5
+ import { Dialog } from "radix-ui";
6
+ import { XIcon } from "lucide-react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/ui/sheet.tsx
9
+ function Sheet({ ...props }) {
10
+ return /* @__PURE__ */ jsx(Dialog.Root, {
11
+ "data-slot": "sheet",
12
+ ...props
13
+ });
14
+ }
15
+ function SheetTrigger({ ...props }) {
16
+ return /* @__PURE__ */ jsx(Dialog.Trigger, {
17
+ "data-slot": "sheet-trigger",
18
+ ...props
19
+ });
20
+ }
21
+ function SheetClose({ ...props }) {
22
+ return /* @__PURE__ */ jsx(Dialog.Close, {
23
+ "data-slot": "sheet-close",
24
+ ...props
25
+ });
26
+ }
27
+ function SheetPortal({ ...props }) {
28
+ return /* @__PURE__ */ jsx(Dialog.Portal, {
29
+ "data-slot": "sheet-portal",
30
+ container: getPortalContainer(),
31
+ ...props
32
+ });
33
+ }
34
+ function SheetOverlay({ className, ...props }) {
35
+ return /* @__PURE__ */ jsx(Dialog.Overlay, {
36
+ "data-slot": "sheet-overlay",
37
+ className: cn("fixed inset-0 z-50 bg-black/10 duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 supports-backdrop-filter:backdrop-blur-xs", className),
38
+ ...props
39
+ });
40
+ }
41
+ function SheetContent({ className, children, side = "right", showCloseButton = true, fullWidth = false, bordered = true, ...props }) {
42
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */ jsxs(Dialog.Content, {
43
+ "data-slot": "sheet-content",
44
+ "data-side": side,
45
+ "data-full-width": fullWidth || void 0,
46
+ className: cn("fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[side=bottom]:data-[state=closed]:slide-out-to-bottom-10 data-[side=left]:data-[state=closed]:slide-out-to-left-10 data-[side=right]:data-[state=closed]:slide-out-to-right-10 data-[side=top]:data-[state=closed]:slide-out-to-top-10 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[side=bottom]:data-[state=open]:slide-in-from-bottom-10 data-[side=left]:data-[state=open]:slide-in-from-left-10 data-[side=right]:data-[state=open]:slide-in-from-right-10 data-[side=top]:data-[state=open]:slide-in-from-top-10 data-[side=left]:@sm:max-w-sm data-[side=right]:@sm:max-w-sm", fullWidth && "data-[side=left]:w-screen data-[side=right]:w-screen data-[side=left]:@sm:max-w-none data-[side=right]:@sm:max-w-none", !bordered && "data-[side=bottom]:border-t-0 data-[side=left]:border-r-0 data-[side=right]:border-l-0 data-[side=top]:border-b-0", className),
47
+ ...props,
48
+ children: [children, showCloseButton && /* @__PURE__ */ jsx(Dialog.Close, {
49
+ "data-slot": "sheet-close",
50
+ asChild: true,
51
+ children: /* @__PURE__ */ jsxs(Button, {
52
+ variant: "ghost",
53
+ className: "absolute top-3 right-3",
54
+ size: "sm",
55
+ iconOnly: true,
56
+ "aria-label": "Close",
57
+ children: [/* @__PURE__ */ jsx(XIcon, {}), /* @__PURE__ */ jsx("span", {
58
+ className: "sr-only",
59
+ children: "Close"
60
+ })]
61
+ })
62
+ })]
63
+ })] });
64
+ }
65
+ function SheetHeader({ className, ...props }) {
66
+ return /* @__PURE__ */ jsx("div", {
67
+ "data-slot": "sheet-header",
68
+ className: cn("flex flex-col gap-0.5 p-4", className),
69
+ ...props
70
+ });
71
+ }
72
+ function SheetFooter({ className, ...props }) {
73
+ return /* @__PURE__ */ jsx("div", {
74
+ "data-slot": "sheet-footer",
75
+ className: cn("mt-auto flex flex-col gap-1 p-4", className),
76
+ ...props
77
+ });
78
+ }
79
+ function SheetTitle({ className, ...props }) {
80
+ return /* @__PURE__ */ jsx(Dialog.Title, {
81
+ "data-slot": "sheet-title",
82
+ className: cn("text-base font-medium text-foreground", className),
83
+ ...props
84
+ });
85
+ }
86
+ function SheetDescription({ className, ...props }) {
87
+ return /* @__PURE__ */ jsx(Dialog.Description, {
88
+ "data-slot": "sheet-description",
89
+ className: cn("text-sm text-muted-foreground", className),
90
+ ...props
91
+ });
92
+ }
93
+ /**
94
+ * WHEN TO USE
95
+ * - A detail view, filter panel, or settings the user returns from without navigating away
96
+ * - Content that should stay anchored to an edge while page context remains visible behind it
97
+ *
98
+ * NOT WHEN
99
+ * - Destructive confirmation — use AlertDialog
100
+ * - Touch-drag bottom sheets — use Drawer (built for the swipe-to-dismiss gesture)
101
+ * - A full task flow with its own navigation — use a page, not a Sheet
102
+ *
103
+ * KEY RULES
104
+ * - `side` defaults to "right"; left/right cap at `@sm:max-w-sm` (a container query against the shared portal container — see Dialog's own doc comment for why), top/bottom are full-width and auto-height
105
+ * - `fullWidth` (left/right only) fills the viewport instead of capping at `@sm:max-w-sm`, and `bordered={false}` drops the edge border — for a Sheet standing in as a detail pane rather than a drawer
106
+ * - `showCloseButton` defaults to true — the close X sits top-right of the panel
107
+ * - SheetHeader/SheetFooter carry their own padding; content between them needs its own (e.g. `px-4`)
108
+ * - Same dismiss behavior as Dialog: Escape and backdrop click close it
109
+ *
110
+ * USAGE
111
+ * <Sheet>
112
+ * <SheetTrigger asChild><Button variant="outline">Open sheet</Button></SheetTrigger>
113
+ * <SheetContent>
114
+ * <SheetHeader>
115
+ * <SheetTitle>Edit profile</SheetTitle>
116
+ * <SheetDescription>Update your details, then save to apply them.</SheetDescription>
117
+ * </SheetHeader>
118
+ * <SheetFooter><Button>Save changes</Button></SheetFooter>
119
+ * </SheetContent>
120
+ * </Sheet>
121
+ *
122
+ * // Enter from a specific edge
123
+ * <SheetContent side="left">...</SheetContent>
124
+ */
125
+ //#endregion
126
+ export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger };
127
+
128
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.js","names":[],"sources":["../../../src/components/ui/sheet.tsx"],"sourcesContent":["/**\n * Sheet — panel that slides in from a screen edge, keeping page context visible.\n *\n * Same modal mechanics as Dialog, but renders as an edge-anchored panel\n * instead of a centered one — a \"Dialog with a side\", built on the Radix\n * Dialog primitive. `side` controls which edge it enters from: top, right\n * (default), bottom, left.\n */\n\nimport * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\nimport { getPortalContainer } from \"@/lib/scope\"\nimport { Button } from \"@/components/ui/button\"\nimport { XIcon } from \"lucide-react\"\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return (\n <SheetPrimitive.Portal\n data-slot=\"sheet-portal\"\n container={getPortalContainer()}\n {...props}\n />\n )\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/10 duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 supports-backdrop-filter:backdrop-blur-xs\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n fullWidth = false,\n bordered = true,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n /** Fills the whole viewport width (`left`/`right` only — `top`/`bottom` already do) instead of capping at `@sm:max-w-sm`. For sheets used as detail panes rather than drawers. */\n fullWidth?: boolean\n /** Draws the edge border on the side facing the page — default `true`. `false` for a borderless pane. */\n bordered?: boolean\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n data-full-width={fullWidth || undefined}\n className={cn(\n \"fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[side=bottom]:data-[state=closed]:slide-out-to-bottom-10 data-[side=left]:data-[state=closed]:slide-out-to-left-10 data-[side=right]:data-[state=closed]:slide-out-to-right-10 data-[side=top]:data-[state=closed]:slide-out-to-top-10 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[side=bottom]:data-[state=open]:slide-in-from-bottom-10 data-[side=left]:data-[state=open]:slide-in-from-left-10 data-[side=right]:data-[state=open]:slide-in-from-right-10 data-[side=top]:data-[state=open]:slide-in-from-top-10 data-[side=left]:@sm:max-w-sm data-[side=right]:@sm:max-w-sm\",\n fullWidth &&\n \"data-[side=left]:w-screen data-[side=right]:w-screen data-[side=left]:@sm:max-w-none data-[side=right]:@sm:max-w-none\",\n !bordered &&\n \"data-[side=bottom]:border-t-0 data-[side=left]:border-r-0 data-[side=right]:border-l-0 data-[side=top]:border-b-0\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close data-slot=\"sheet-close\" asChild>\n <Button\n variant=\"ghost\"\n className=\"absolute top-3 right-3\"\n size=\"sm\"\n iconOnly\n aria-label=\"Close\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </Button>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-0.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n // gap-1, not gap-2 — same action-grouping convention as DialogFooter:\n // the footer's buttons resolve one decision together, a tight cluster.\n className={cn(\"mt-auto flex flex-col gap-1 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-base font-medium text-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n\n/**\n * WHEN TO USE\n * - A detail view, filter panel, or settings the user returns from without navigating away\n * - Content that should stay anchored to an edge while page context remains visible behind it\n *\n * NOT WHEN\n * - Destructive confirmation — use AlertDialog\n * - Touch-drag bottom sheets — use Drawer (built for the swipe-to-dismiss gesture)\n * - A full task flow with its own navigation — use a page, not a Sheet\n *\n * KEY RULES\n * - `side` defaults to \"right\"; left/right cap at `@sm:max-w-sm` (a container query against the shared portal container — see Dialog's own doc comment for why), top/bottom are full-width and auto-height\n * - `fullWidth` (left/right only) fills the viewport instead of capping at `@sm:max-w-sm`, and `bordered={false}` drops the edge border — for a Sheet standing in as a detail pane rather than a drawer\n * - `showCloseButton` defaults to true — the close X sits top-right of the panel\n * - SheetHeader/SheetFooter carry their own padding; content between them needs its own (e.g. `px-4`)\n * - Same dismiss behavior as Dialog: Escape and backdrop click close it\n *\n * USAGE\n * <Sheet>\n * <SheetTrigger asChild><Button variant=\"outline\">Open sheet</Button></SheetTrigger>\n * <SheetContent>\n * <SheetHeader>\n * <SheetTitle>Edit profile</SheetTitle>\n * <SheetDescription>Update your details, then save to apply them.</SheetDescription>\n * </SheetHeader>\n * <SheetFooter><Button>Save changes</Button></SheetFooter>\n * </SheetContent>\n * </Sheet>\n *\n * // Enter from a specific edge\n * <SheetContent side=\"left\">...</SheetContent>\n */\n"],"mappings":";;;;;;;;AAiBA,SAAS,MAAM,EAAE,GAAG,SAA2D;CAC7E,OAAO,oBAAC,OAAe,MAAhB;EAAqB,aAAU;EAAQ,GAAI;CAAQ,CAAA;AAC5D;AAEA,SAAS,aAAa,EACpB,GAAG,SACmD;CACtD,OAAO,oBAAC,OAAe,SAAhB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAEA,SAAS,WAAW,EAClB,GAAG,SACiD;CACpD,OAAO,oBAAC,OAAe,OAAhB;EAAsB,aAAU;EAAc,GAAI;CAAQ,CAAA;AACnE;AAEA,SAAS,YAAY,EACnB,GAAG,SACkD;CACrD,OACE,oBAAC,OAAe,QAAhB;EACE,aAAU;EACV,WAAW,mBAAmB;EAC9B,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAAC,OAAe,SAAhB;EACE,aAAU;EACV,WAAW,GACT,iNACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,UACA,OAAO,SACP,kBAAkB,MAClB,YAAY,OACZ,WAAW,MACX,GAAG,SAQF;CACD,OACE,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,cAAD,CAAe,CAAA,GACf,qBAAC,OAAe,SAAhB;EACE,aAAU;EACV,aAAW;EACX,mBAAiB,aAAa,KAAA;EAC9B,WAAW,GACT,iuCACA,aACE,yHACF,CAAC,YACC,qHACF,SACF;EACA,GAAI;EAZN,UAAA,CAcG,UACA,mBACC,oBAAC,OAAe,OAAhB;GAAsB,aAAU;GAAc,SAAA;GAC5C,UAAA,qBAAC,QAAD;IACE,SAAQ;IACR,WAAU;IACV,MAAK;IACL,UAAA;IACA,cAAW;IALb,UAAA,CAOE,oBAAC,OAAD,CAAQ,CAAA,GACR,oBAAC,QAAD;KAAM,WAAU;KAAU,UAAA;IAAW,CAAA,CAC/B;;EACY,CAAA,CAEF;CACb,CAAA,CAAA,EAAA,CAAA;AAEjB;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,6BAA6B,SAAS;EACpD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,oBAAC,OAAD;EACE,aAAU;EAGV,WAAW,GAAG,mCAAmC,SAAS;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAClB,WACA,GAAG,SACiD;CACpD,OACE,oBAAC,OAAe,OAAhB;EACE,aAAU;EACV,WAAW,GAAG,yCAAyC,SAAS;EAChE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAAC,OAAe,aAAhB;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Sidebar — full application side-navigation shell.
3
+ *
4
+ * Includes SidebarMenuCollapsible, an animated, disclosable nav "folder"
5
+ * that pairs SidebarMenuButton with Collapsible (see its own doc comment above
6
+ * its definition). Composed from many sub-exports; see the WHEN TO USE /
7
+ * KEY RULES block at the end of this file for the family as a whole.
8
+ */
9
+ import * as React from "react";
10
+ import { type VariantProps } from "class-variance-authority";
11
+ import { Button } from "../../components/ui/button";
12
+ import { Input } from "../../components/ui/input";
13
+ import { Separator } from "../../components/ui/separator";
14
+ import { TooltipContent } from "../../components/ui/tooltip";
15
+ type SidebarContextProps = {
16
+ state: "expanded" | "collapsed";
17
+ open: boolean;
18
+ setOpen: (open: boolean) => void;
19
+ openMobile: boolean;
20
+ setOpenMobile: (open: boolean) => void;
21
+ isMobile: boolean;
22
+ toggleSidebar: () => void;
23
+ /** 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. */
24
+ contentId: string;
25
+ };
26
+ declare function useSidebar(): SidebarContextProps;
27
+ declare function SidebarProvider({ defaultOpen, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }: React.ComponentProps<"div"> & {
28
+ defaultOpen?: boolean;
29
+ open?: boolean;
30
+ onOpenChange?: (open: boolean) => void;
31
+ }): React.JSX.Element;
32
+ declare function Sidebar({ side, variant, collapsible, className, children, dir, ...props }: React.ComponentProps<"div"> & {
33
+ side?: "left" | "right";
34
+ variant?: "sidebar" | "floating" | "inset";
35
+ collapsible?: "offcanvas" | "icon" | "none";
36
+ }): React.JSX.Element;
37
+ declare function SidebarTrigger({ className, onClick, ...props }: Omit<React.ComponentProps<typeof Button>, "size" | "iconOnly" | "asChild" | "aria-label" | "variant">): React.JSX.Element;
38
+ declare function SidebarRail({ className, ...props }: React.ComponentProps<"button">): React.JSX.Element;
39
+ declare function SidebarInset({ className, ...props }: React.ComponentProps<"main">): React.JSX.Element;
40
+ declare function SidebarInput({ className, ...props }: React.ComponentProps<typeof Input>): React.JSX.Element;
41
+ declare function SidebarHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
42
+ declare function SidebarFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
43
+ declare function SidebarSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): React.JSX.Element;
44
+ declare function SidebarContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
45
+ declare function SidebarGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
46
+ declare function SidebarGroupLabel({ className, asChild, ...props }: React.ComponentProps<"div"> & {
47
+ asChild?: boolean;
48
+ }): React.JSX.Element;
49
+ declare function SidebarGroupAction({ className, asChild, ...props }: React.ComponentProps<"button"> & {
50
+ asChild?: boolean;
51
+ }): React.JSX.Element;
52
+ declare function SidebarGroupContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
53
+ declare function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
54
+ declare function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
55
+ declare const sidebarMenuButtonVariants: (props?: ({
56
+ variant?: "default" | "outline" | null | undefined;
57
+ size?: "sm" | "lg" | "default" | null | undefined;
58
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
59
+ declare function SidebarMenuButton({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<"button"> & {
60
+ asChild?: boolean;
61
+ isActive?: boolean;
62
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>;
63
+ } & VariantProps<typeof sidebarMenuButtonVariants>): React.JSX.Element;
64
+ declare function SidebarMenuAction({ className, asChild, showOnHover, ...props }: React.ComponentProps<"button"> & {
65
+ asChild?: boolean;
66
+ showOnHover?: boolean;
67
+ }): React.JSX.Element;
68
+ declare function SidebarMenuBadge({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
69
+ declare function SidebarMenuSkeleton({ className, showIcon, ...props }: React.ComponentProps<"div"> & {
70
+ showIcon?: boolean;
71
+ }): React.JSX.Element;
72
+ declare function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">): React.JSX.Element;
73
+ declare function SidebarMenuSubItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
74
+ declare function SidebarMenuSubButton({ asChild, size, isActive, className, ...props }: React.ComponentProps<"a"> & {
75
+ asChild?: boolean;
76
+ size?: "sm" | "md";
77
+ isActive?: boolean;
78
+ }): React.JSX.Element;
79
+ /**
80
+ * A SidebarMenuButton that discloses a set of child rows underneath it
81
+ * instead of navigating — a "folder" of related destinations in the rail.
82
+ *
83
+ * SidebarMenuSub is a static indented list with no disclosure state of its
84
+ * own; this pairs it with Collapsible so opening/closing actually animates,
85
+ * and flattens the indent to 0 once the sidebar collapses to icon-only
86
+ * (`group-data-[collapsible=icon]`), matching how every other menu row in
87
+ * this family already collapses.
88
+ *
89
+ * `open`/`onOpenChange` are owned by the caller, same as SidebarMenuButton's
90
+ * `isActive` — this component holds no state of its own, so multiple
91
+ * instances of the same rail (e.g. a docked sidebar and its own hover
92
+ * overlay) can share one open/closed answer instead of disagreeing.
93
+ */
94
+ declare function SidebarMenuCollapsible({ icon, label, children, open, onOpenChange, isActive, className, ...props }: Omit<React.ComponentProps<typeof SidebarMenuButton>, "children"> & {
95
+ icon?: React.ReactNode;
96
+ /** The trigger row's own text — distinct from `children`, which is the disclosed row list. */
97
+ label: React.ReactNode;
98
+ /** Child rows, revealed when open. */
99
+ children: React.ReactNode;
100
+ open: boolean;
101
+ onOpenChange: (open: boolean) => void;
102
+ }): React.JSX.Element;
103
+ 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, };
104
+ /**
105
+ * WHEN TO USE
106
+ * - Persistent primary navigation in an app-shell layout — the main way
107
+ * users move between top-level sections of the product.
108
+ *
109
+ * NOT WHEN
110
+ * - A temporary/dismissible panel — use Sheet (Sidebar itself renders as a
111
+ * Sheet on mobile automatically, but don't reach for Sidebar to build a
112
+ * one-off drawer).
113
+ * - Top-bar navigation — use NavigationMenu.
114
+ * - A plain, non-collapsible list with no app-shell chrome — use Item.
115
+ *
116
+ * KEY RULES
117
+ * - Requires SidebarProvider wrapping both the Sidebar and the SidebarInset
118
+ * content — it owns the open/collapsed state via context (`useSidebar`);
119
+ * Sidebar and SidebarInset don't work standalone.
120
+ * - `side`: "left" | "right". `variant`: "sidebar" (flush) | "floating"
121
+ * (rounded, ringed) | "inset" (content insets around it). `collapsible`:
122
+ * "offcanvas" (slides fully away) | "icon" (shrinks to icon rail) | "none"
123
+ * (always expanded, no collapse control).
124
+ * - Below the `md` breakpoint the sidebar always renders as a Sheet
125
+ * regardless of `collapsible`, via `useIsMobile` — don't special-case
126
+ * mobile yourself.
127
+ * - SidebarMenuButton's `isActive` and SidebarMenuCollapsible's `open` are
128
+ * both caller-owned — this file holds no "current route" state.
129
+ * - SidebarMenuSub is a static indented list; SidebarMenuCollapsible is the
130
+ * version with its own open/close disclosure and icon-collapse indent
131
+ * flattening — don't use Sub when you need a toggleable "folder".
132
+ * - Cmd/Ctrl+B toggles the sidebar globally (wired inside SidebarProvider).
133
+ *
134
+ * USAGE
135
+ * <SidebarProvider>
136
+ * <Sidebar>
137
+ * <SidebarHeader>...</SidebarHeader>
138
+ * <SidebarContent>
139
+ * <SidebarGroup>
140
+ * <SidebarGroupLabel>Platform</SidebarGroupLabel>
141
+ * <SidebarGroupContent>
142
+ * <SidebarMenu>
143
+ * <SidebarMenuItem>
144
+ * <SidebarMenuButton isActive>
145
+ * <HomeIcon />Overview
146
+ * </SidebarMenuButton>
147
+ * </SidebarMenuItem>
148
+ * <SidebarMenuItem>
149
+ * <SidebarMenuCollapsible
150
+ * icon={<FolderIcon />}
151
+ * label="Analytics"
152
+ * open={open}
153
+ * onOpenChange={setOpen}
154
+ * >
155
+ * <SidebarMenuButton><BarChartIcon />Cohort Builder</SidebarMenuButton>
156
+ * </SidebarMenuCollapsible>
157
+ * </SidebarMenuItem>
158
+ * </SidebarMenu>
159
+ * </SidebarGroupContent>
160
+ * </SidebarGroup>
161
+ * </SidebarContent>
162
+ * </Sidebar>
163
+ * <SidebarInset>{"<page content>"}</SidebarInset>
164
+ * </SidebarProvider>
165
+ */
166
+ //# sourceMappingURL=sidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/sidebar.tsx"],"names":[],"mappings":"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"}