@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":"questionnaire.js","names":[],"sources":["../../../src/components/ui/questionnaire.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * Questionnaire — multi-step form that shows one question at a time.\n *\n * Wraps the `@shadcn/react` Questionnaire primitive (Root, Item, Choice,\n * Input, Previous/Skip/Next/Submit), which handles step sequencing,\n * navigation, and validation; the root renders a <form> that tracks the\n * active item. MMDS styles choices as bordered, checkbox/radio-style cards\n * and lays out Previous/Skip/Next/Submit in a fixed 3-column grid.\n */\n\nimport * as React from \"react\"\nimport { Questionnaire as QuestionnairePrimitive } from \"@shadcn/react/questionnaire\"\n\nimport { cn } from \"@/lib/utils\"\nimport { buttonVariants, type Button } from \"@/components/ui/button\"\nimport { CheckIcon } from \"lucide-react\"\n\n// QuestionnaireTitle only ever renders a <legend> (labels the surrounding\n// <fieldset>, not any control inside it) and QuestionnaireInput's\n// underlying primitive carries no aria-labelledby/aria-describedby link\n// back to it — unlike Choice steps, which get a real <label> for free.\n// This threads Title's/Description's ids to the Input within the same\n// QuestionnaireItem so free-text steps get an accessible name and\n// description without every consumer wiring it by hand.\nconst QuestionnaireLabelContext = React.createContext<{\n titleId: string | null\n setTitleId: (id: string | null) => void\n descriptionId: string | null\n setDescriptionId: (id: string | null) => void\n} | null>(null)\n\nfunction Questionnaire({\n className,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Root>) {\n return (\n <QuestionnairePrimitive.Root\n data-slot=\"questionnaire\"\n className={cn(\"flex w-full min-w-0 flex-col gap-4\", className)}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireProgress({\n className,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Progress>) {\n return (\n <QuestionnairePrimitive.Progress\n data-slot=\"questionnaire-progress\"\n className={cn(\n \"min-h-[1lh] w-fit min-w-[14ch] text-xs font-medium text-muted-foreground tabular-nums\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireItem({\n className,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Item>) {\n const [titleId, setTitleId] = React.useState<string | null>(null)\n const [descriptionId, setDescriptionId] = React.useState<string | null>(\n null\n )\n const labelContext = React.useMemo(\n () => ({ titleId, setTitleId, descriptionId, setDescriptionId }),\n [titleId, descriptionId]\n )\n\n return (\n <QuestionnaireLabelContext.Provider value={labelContext}>\n <QuestionnairePrimitive.Item\n data-slot=\"questionnaire-item\"\n className={cn(\n \"flex min-w-0 flex-col gap-4 border-0 p-0 outline-none\",\n className\n )}\n {...props}\n />\n </QuestionnaireLabelContext.Provider>\n )\n}\n\nfunction QuestionnaireTitle({\n className,\n id,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Title>) {\n const generatedId = React.useId()\n const titleId = id ?? generatedId\n const labelContext = React.useContext(QuestionnaireLabelContext)\n\n React.useLayoutEffect(() => {\n labelContext?.setTitleId(titleId)\n return () => labelContext?.setTitleId(null)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [titleId])\n\n return (\n <QuestionnairePrimitive.Title\n data-slot=\"questionnaire-title\"\n id={titleId}\n className={cn(\n \"text-base leading-snug font-medium text-pretty [&:not(:has(~[data-slot=questionnaire-description]))]:mb-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Description>) {\n const generatedId = React.useId()\n const descriptionId = id ?? generatedId\n const labelContext = React.useContext(QuestionnaireLabelContext)\n\n React.useLayoutEffect(() => {\n labelContext?.setDescriptionId(descriptionId)\n return () => labelContext?.setDescriptionId(null)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [descriptionId])\n\n return (\n <QuestionnairePrimitive.Description\n data-slot=\"questionnaire-description\"\n id={descriptionId}\n className={cn(\"text-sm text-pretty text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireChoices({\n className,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Choices>) {\n return (\n <QuestionnairePrimitive.Choices\n data-slot=\"questionnaire-choices\"\n className={cn(\n \"group/questionnaire-choices grid min-w-0 gap-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireChoice({\n children,\n className,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Choice>) {\n return (\n <QuestionnairePrimitive.Choice\n data-slot=\"questionnaire-choice\"\n className={cn(\n \"group/questionnaire-choice relative flex min-h-11 cursor-pointer items-start gap-2.5 rounded-lg border border-input bg-transparent px-3 py-2.5 text-start text-sm transition-colors outline-none select-none hover:bg-muted/50 has-[>input:focus-visible]:border-ring has-[>input:focus-visible]:ring-3 has-[>input:focus-visible]:ring-ring/50 data-invalid:border-destructive dark:bg-input/20 data-checked:border-primary/40 data-checked:bg-muted dark:data-checked:bg-muted\",\n \"data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <QuestionnairePrimitive.ChoiceInput\n data-slot=\"questionnaire-choice-input\"\n className=\"absolute inset-0 z-10 size-full cursor-pointer opacity-0\"\n />\n <span\n aria-hidden=\"true\"\n data-slot=\"questionnaire-choice-indicator\"\n className=\"pointer-events-none relative flex size-4 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-[4px] border border-input group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[type=radio]/questionnaire-choice:rounded-full group-data-checked/questionnaire-choice:border-primary group-data-checked/questionnaire-choice:bg-primary group-data-checked/questionnaire-choice:text-primary-foreground dark:bg-input/30 dark:group-data-checked/questionnaire-choice:bg-primary\"\n >\n <span\n data-slot=\"questionnaire-choice-indicator-dot\"\n className=\"hidden size-2 rounded-full bg-primary-foreground group-data-[type=checkbox]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block\"\n />\n <CheckIcon\n data-slot=\"questionnaire-choice-indicator-check\"\n className=\"hidden size-3.5 group-data-[type=radio]/questionnaire-choice:hidden group-data-checked/questionnaire-choice:block\"\n />\n </span>\n <QuestionnairePrimitive.ChoiceLabel\n data-slot=\"questionnaire-choice-label\"\n className=\"flex min-w-0 flex-1 flex-col gap-0.5 leading-snug\"\n >\n {children}\n </QuestionnairePrimitive.ChoiceLabel>\n <QuestionnairePrimitive.ChoiceShortcut\n data-slot=\"questionnaire-choice-shortcut\"\n className=\"pointer-events-none ms-auto hidden size-5 shrink-0 translate-y-[--spacing(0.45)] items-center justify-center rounded-md border border-input bg-background font-mono text-[0.625rem] leading-none font-medium text-muted-foreground group-has-data-[slot=questionnaire-choice-description]/questionnaire-choice:translate-y-0.5 group-data-[shortcut]/questionnaire-choice:inline-flex\"\n />\n </QuestionnairePrimitive.Choice>\n )\n}\n\nfunction QuestionnaireChoiceDescription({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"questionnaire-choice-description\"\n className={cn(\"text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireInput({\n className,\n \"aria-labelledby\": ariaLabelledby,\n \"aria-describedby\": ariaDescribedby,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Input>) {\n const labelContext = React.useContext(QuestionnaireLabelContext)\n // Only fall back to Title/Description's ids when the consumer hasn't\n // already supplied their own — an explicit aria-label/aria-labelledby\n // always wins.\n const resolvedLabelledby =\n ariaLabelledby ??\n (!props[\"aria-label\"] ? labelContext?.titleId ?? undefined : undefined)\n const resolvedDescribedby =\n ariaDescribedby ?? labelContext?.descriptionId ?? undefined\n\n return (\n <div\n data-slot=\"questionnaire-input-wrapper\"\n className=\"group/questionnaire-input relative w-full min-w-0\"\n >\n <QuestionnairePrimitive.Input\n data-slot=\"questionnaire-input\"\n aria-labelledby={resolvedLabelledby}\n aria-describedby={resolvedDescribedby}\n className={cn(\n \"h-8 min-h-11 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-[color,box-shadow,background-color] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 sm:min-h-0 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n \"selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground\",\n className\n )}\n {...props}\n />\n </div>\n )\n}\n\nfunction QuestionnaireError({\n className,\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Error>) {\n return (\n <QuestionnairePrimitive.Error\n data-slot=\"questionnaire-error\"\n className={cn(\"mt-2 text-sm text-destructive\", className)}\n {...props}\n />\n )\n}\n\nfunction QuestionnaireActions({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"questionnaire-actions\"\n className={cn(\n \"grid min-h-11 w-full grid-cols-[minmax(0,1fr)_auto_auto] items-center gap-2 sm:min-h-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction QuestionnairePrevious({\n children,\n className,\n size = \"default\",\n variant = \"outline\",\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Previous> &\n Pick<React.ComponentProps<typeof Button>, \"size\" | \"variant\">) {\n return (\n <QuestionnairePrimitive.Previous\n data-slot=\"questionnaire-previous\"\n data-size={size}\n data-variant={variant}\n className={cn(\n buttonVariants({ size, variant }),\n \"col-start-1 row-start-1 min-h-11 justify-self-start sm:min-h-0\",\n className\n )}\n {...props}\n >\n {children ?? \"Previous\"}\n </QuestionnairePrimitive.Previous>\n )\n}\n\nfunction QuestionnaireSkip({\n children,\n className,\n size = \"default\",\n variant = \"outline\",\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Skip> &\n Pick<React.ComponentProps<typeof Button>, \"size\" | \"variant\">) {\n return (\n <QuestionnairePrimitive.Skip\n data-slot=\"questionnaire-skip\"\n data-size={size}\n data-variant={variant}\n className={cn(\n buttonVariants({ size, variant }),\n \"col-start-2 row-start-1 min-h-11 justify-self-end sm:min-h-0\",\n className\n )}\n {...props}\n >\n {children ?? \"Skip\"}\n </QuestionnairePrimitive.Skip>\n )\n}\n\nfunction QuestionnaireNext({\n children,\n className,\n size = \"default\",\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Next> &\n Pick<React.ComponentProps<typeof Button>, \"size\" | \"variant\">) {\n return (\n <QuestionnairePrimitive.Next\n data-slot=\"questionnaire-next\"\n data-size={size}\n data-variant={variant}\n className={cn(\n buttonVariants({ size, variant }),\n \"col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0\",\n className\n )}\n {...props}\n >\n {children ?? \"Next\"}\n </QuestionnairePrimitive.Next>\n )\n}\n\nfunction QuestionnaireSubmit({\n children,\n className,\n size = \"default\",\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof QuestionnairePrimitive.Submit> &\n Pick<React.ComponentProps<typeof Button>, \"size\" | \"variant\">) {\n return (\n <QuestionnairePrimitive.Submit\n data-slot=\"questionnaire-submit\"\n data-size={size}\n data-variant={variant}\n className={cn(\n buttonVariants({ size, variant }),\n \"col-start-3 row-start-1 min-h-11 justify-self-end sm:min-h-0\",\n className\n )}\n {...props}\n >\n {children ?? \"Submit\"}\n </QuestionnairePrimitive.Submit>\n )\n}\n\nexport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoiceDescription,\n QuestionnaireChoices,\n QuestionnaireDescription,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireNext,\n QuestionnairePrevious,\n QuestionnaireProgress,\n QuestionnaireSkip,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n}\n\n/**\n * WHEN TO USE\n * - Guided multi-step intake, onboarding, or surveys where only one question is shown at a time.\n * - Flows that need per-step required/skip logic and a progress indicator.\n *\n * NOT WHEN\n * - All fields should be visible at once in a single form — use Field + FieldSet instead.\n * - Sections don't need to be shown in sequence — use Tabs instead.\n *\n * KEY RULES\n * - `items` on Questionnaire declares the sequence of entries and which are `required`; each QuestionnaireItem matches an entry by `name`.\n * - A QuestionnaireItem's `required`/`multiple` props should match its entry in `items` — `multiple` renders a checkbox-style choice group instead of radio-style.\n * - `shortcuts=\"letters\"` on Questionnaire adds A/B/C key hints to each QuestionnaireChoice.\n * - QuestionnairePrevious / QuestionnaireSkip / QuestionnaireNext / QuestionnaireSubmit manage their own visibility based on step position — render all of them and let the primitive decide which shows.\n * - QuestionnaireError only renders when the active item fails validation (e.g. a required choice wasn't picked).\n * - QuestionnaireInput automatically picks up `aria-labelledby`/`aria-describedby` from the\n * QuestionnaireTitle/QuestionnaireDescription rendered in the same QuestionnaireItem (unlike\n * Choice steps, a free-text step has no native `<label>` wrapping it) — pass an explicit\n * `aria-label`/`aria-labelledby` yourself only if you need to override that default.\n *\n * USAGE\n * <Questionnaire\n * items={[\n * { name: \"base\", required: true, choices: [{ value: \"radix\" }, { value: \"base-ui\" }] },\n * { name: \"notes\" },\n * ]}\n * >\n * <QuestionnaireProgress />\n * <QuestionnaireItem name=\"base\" required>\n * <QuestionnaireTitle>Which primitive base do you use?</QuestionnaireTitle>\n * <QuestionnaireChoices>\n * <QuestionnaireChoice value=\"radix\">Radix UI</QuestionnaireChoice>\n * <QuestionnaireChoice value=\"base-ui\">Base UI</QuestionnaireChoice>\n * </QuestionnaireChoices>\n * <QuestionnaireError>Pick one to continue.</QuestionnaireError>\n * </QuestionnaireItem>\n * <QuestionnaireItem name=\"notes\">\n * <QuestionnaireTitle>Anything else?</QuestionnaireTitle>\n * <QuestionnaireInput type=\"text\" placeholder=\"Optional\" />\n * </QuestionnaireItem>\n * <QuestionnaireActions>\n * <QuestionnairePrevious>Back</QuestionnairePrevious>\n * <QuestionnaireNext>Next</QuestionnaireNext>\n * <QuestionnaireSubmit>Submit</QuestionnaireSubmit>\n * </QuestionnaireActions>\n * </Questionnaire>\n *\n * // Letter shortcuts (A/B/C hints on choices)\n * <Questionnaire\n * shortcuts=\"letters\"\n * items={[{ name: \"spice\", required: true, choices: [{ value: \"turmeric\" }] }]}\n * >\n * <QuestionnaireItem name=\"spice\" required>\n * <QuestionnaireTitle>Pick a spice</QuestionnaireTitle>\n * <QuestionnaireChoices>\n * <QuestionnaireChoice value=\"turmeric\">Turmeric</QuestionnaireChoice>\n * </QuestionnaireChoices>\n * </QuestionnaireItem>\n * <QuestionnaireActions>\n * <QuestionnaireSubmit>Submit</QuestionnaireSubmit>\n * </QuestionnaireActions>\n * </Questionnaire>\n */\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * RadioGroup — exclusive selection from a small, always-visible set.
3
+ *
4
+ * Built on the Radix RadioGroup primitive. Error styling is driven off
5
+ * `aria-invalid` on the group/items instead of a prop, and the selected-dot
6
+ * indicator is a plain filled circle rather than an icon.
7
+ */
8
+ import * as React from "react";
9
+ import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
10
+ declare function RadioGroup({ className, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Root>): React.JSX.Element;
11
+ declare function RadioGroupItem({ className, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Item>): React.JSX.Element;
12
+ export { RadioGroup, RadioGroupItem };
13
+ /**
14
+ * WHEN TO USE
15
+ * - Choosing exactly one option from roughly 2–5 choices that should all stay visible at once
16
+ *
17
+ * NOT WHEN
18
+ * - More than ~5 options, or the list is dynamic/long — use Select
19
+ * - A single boolean — use Checkbox or Switch
20
+ * - More than one option can be chosen — use a list of Checkbox
21
+ *
22
+ * KEY RULES
23
+ * - RadioGroup lays out its items in a grid (vertical by default); pass a `className`
24
+ * like `flex gap-4` for a horizontal row
25
+ * - Wrap each RadioGroupItem in a Label so its text is a clickable target and is announced
26
+ * - Error state is driven entirely by `aria-invalid` — there is no `error` prop
27
+ * - `disabled` on an individual RadioGroupItem disables just that option
28
+ * - An AI-recommended choice is marked once, at the GROUP, never beside an individual option:
29
+ * a radio group holds exactly one value, so AI chose for the group (unlike Checkbox, where
30
+ * each option is its own boolean and can carry its own marker). Put `AILabel` beside the
31
+ * FieldLegend in a `flex items-center` row (`mb-0` on the legend, `mb-1.5` on the row so the
32
+ * two share a centre line; `aria-labelledby` on the FieldSet since the legend is no longer
33
+ * its first child) and keep the options as plain `<Label>`-wrapped items. Pass AILabel
34
+ * `edited={value !== aiValue}` and an `onRevert` that re-selects it, so picking another option
35
+ * turns the marker into an undo button (AILabel's own override/undo morph, same as
36
+ * Input/Select/Textarea/Checkbox). See AI/RadioGroup.
37
+ *
38
+ * USAGE
39
+ * <RadioGroup defaultValue="comfortable">
40
+ * <Label className="flex items-center gap-2">
41
+ * <RadioGroupItem value="comfortable" />
42
+ * Comfortable
43
+ * </Label>
44
+ * <Label className="flex items-center gap-2">
45
+ * <RadioGroupItem value="compact" />
46
+ * Compact
47
+ * </Label>
48
+ * </RadioGroup>
49
+ */
50
+ //# sourceMappingURL=radio-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../../src/components/ui/radio-group.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAI5D,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC,qBAQvD;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC,qBAkBvD;AAED,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,CAAA;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG"}
@@ -0,0 +1,65 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import "react";
3
+ import { RadioGroup as RadioGroup$1 } from "radix-ui";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/ui/radio-group.tsx
6
+ function RadioGroup({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx(RadioGroup$1.Root, {
8
+ "data-slot": "radio-group",
9
+ className: cn("grid w-full gap-2", className),
10
+ ...props
11
+ });
12
+ }
13
+ function RadioGroupItem({ className, ...props }) {
14
+ return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
15
+ "data-slot": "radio-group-item",
16
+ className: cn("group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 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 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary", className),
17
+ ...props,
18
+ children: /* @__PURE__ */ jsx(RadioGroup$1.Indicator, {
19
+ "data-slot": "radio-group-indicator",
20
+ className: "flex size-4 items-center justify-center",
21
+ children: /* @__PURE__ */ jsx("span", { className: "absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground" })
22
+ })
23
+ });
24
+ }
25
+ /**
26
+ * WHEN TO USE
27
+ * - Choosing exactly one option from roughly 2–5 choices that should all stay visible at once
28
+ *
29
+ * NOT WHEN
30
+ * - More than ~5 options, or the list is dynamic/long — use Select
31
+ * - A single boolean — use Checkbox or Switch
32
+ * - More than one option can be chosen — use a list of Checkbox
33
+ *
34
+ * KEY RULES
35
+ * - RadioGroup lays out its items in a grid (vertical by default); pass a `className`
36
+ * like `flex gap-4` for a horizontal row
37
+ * - Wrap each RadioGroupItem in a Label so its text is a clickable target and is announced
38
+ * - Error state is driven entirely by `aria-invalid` — there is no `error` prop
39
+ * - `disabled` on an individual RadioGroupItem disables just that option
40
+ * - An AI-recommended choice is marked once, at the GROUP, never beside an individual option:
41
+ * a radio group holds exactly one value, so AI chose for the group (unlike Checkbox, where
42
+ * each option is its own boolean and can carry its own marker). Put `AILabel` beside the
43
+ * FieldLegend in a `flex items-center` row (`mb-0` on the legend, `mb-1.5` on the row so the
44
+ * two share a centre line; `aria-labelledby` on the FieldSet since the legend is no longer
45
+ * its first child) and keep the options as plain `<Label>`-wrapped items. Pass AILabel
46
+ * `edited={value !== aiValue}` and an `onRevert` that re-selects it, so picking another option
47
+ * turns the marker into an undo button (AILabel's own override/undo morph, same as
48
+ * Input/Select/Textarea/Checkbox). See AI/RadioGroup.
49
+ *
50
+ * USAGE
51
+ * <RadioGroup defaultValue="comfortable">
52
+ * <Label className="flex items-center gap-2">
53
+ * <RadioGroupItem value="comfortable" />
54
+ * Comfortable
55
+ * </Label>
56
+ * <Label className="flex items-center gap-2">
57
+ * <RadioGroupItem value="compact" />
58
+ * Compact
59
+ * </Label>
60
+ * </RadioGroup>
61
+ */
62
+ //#endregion
63
+ export { RadioGroup, RadioGroupItem };
64
+
65
+ //# sourceMappingURL=radio-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group.js","names":[],"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["/**\n * RadioGroup — exclusive selection from a small, always-visible set.\n *\n * Built on the Radix RadioGroup primitive. Error styling is driven off\n * `aria-invalid` on the group/items instead of a prop, and the selected-dot\n * indicator is a plain filled circle rather than an icon.\n */\n\nimport * as React from \"react\"\nimport { RadioGroup as RadioGroupPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction RadioGroup({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {\n return (\n <RadioGroupPrimitive.Root\n data-slot=\"radio-group\"\n className={cn(\"grid w-full gap-2\", className)}\n {...props}\n />\n )\n}\n\nfunction RadioGroupItem({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return (\n <RadioGroupPrimitive.Item\n data-slot=\"radio-group-item\"\n className={cn(\n \"group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 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 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary\",\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className=\"flex size-4 items-center justify-center\"\n >\n <span className=\"absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n}\n\nexport { RadioGroup, RadioGroupItem }\n\n/**\n * WHEN TO USE\n * - Choosing exactly one option from roughly 2–5 choices that should all stay visible at once\n *\n * NOT WHEN\n * - More than ~5 options, or the list is dynamic/long — use Select\n * - A single boolean — use Checkbox or Switch\n * - More than one option can be chosen — use a list of Checkbox\n *\n * KEY RULES\n * - RadioGroup lays out its items in a grid (vertical by default); pass a `className`\n * like `flex gap-4` for a horizontal row\n * - Wrap each RadioGroupItem in a Label so its text is a clickable target and is announced\n * - Error state is driven entirely by `aria-invalid` — there is no `error` prop\n * - `disabled` on an individual RadioGroupItem disables just that option\n * - An AI-recommended choice is marked once, at the GROUP, never beside an individual option:\n * a radio group holds exactly one value, so AI chose for the group (unlike Checkbox, where\n * each option is its own boolean and can carry its own marker). Put `AILabel` beside the\n * FieldLegend in a `flex items-center` row (`mb-0` on the legend, `mb-1.5` on the row so the\n * two share a centre line; `aria-labelledby` on the FieldSet since the legend is no longer\n * its first child) and keep the options as plain `<Label>`-wrapped items. Pass AILabel\n * `edited={value !== aiValue}` and an `onRevert` that re-selects it, so picking another option\n * turns the marker into an undo button (AILabel's own override/undo morph, same as\n * Input/Select/Textarea/Checkbox). See AI/RadioGroup.\n *\n * USAGE\n * <RadioGroup defaultValue=\"comfortable\">\n * <Label className=\"flex items-center gap-2\">\n * <RadioGroupItem value=\"comfortable\" />\n * Comfortable\n * </Label>\n * <Label className=\"flex items-center gap-2\">\n * <RadioGroupItem value=\"compact\" />\n * Compact\n * </Label>\n * </RadioGroup>\n */\n"],"mappings":";;;;;AAaA,SAAS,WAAW,EAClB,WACA,GAAG,SACqD;CACxD,OACE,oBAAC,aAAoB,MAArB;EACE,aAAU;EACV,WAAW,GAAG,qBAAqB,SAAS;EAC5C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,WACA,GAAG,SACqD;CACxD,OACE,oBAAC,aAAoB,MAArB;EACE,aAAU;EACV,WAAW,GACT,upBACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,aAAoB,WAArB;GACE,aAAU;GACV,WAAU;GAEV,UAAA,oBAAC,QAAD,EAAM,WAAU,wGAAyG,CAAA;EAC5F,CAAA;CACP,CAAA;AAE9B"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * ResizablePanelGroup — draggable split panes, on react-resizable-panels v4.
3
+ *
4
+ * Follows the react-resizable-panels v4 API: orientation is set via
5
+ * `orientation` ("horizontal" | "vertical"), not the older `direction` prop.
6
+ */
7
+ import * as React from "react";
8
+ import * as ResizablePrimitive from "react-resizable-panels";
9
+ declare function ResizablePanelGroup({ className, ...props }: ResizablePrimitive.GroupProps): React.JSX.Element;
10
+ declare function ResizablePanel({ elementRef, ...props }: ResizablePrimitive.PanelProps): React.JSX.Element;
11
+ declare function ResizableHandle({ withHandle, className, "aria-label": ariaLabel, ...props }: ResizablePrimitive.SeparatorProps & {
12
+ withHandle?: boolean;
13
+ }): React.JSX.Element;
14
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
15
+ /**
16
+ * WHEN TO USE
17
+ * - User-adjustable split layouts — editor plus preview, list plus detail,
18
+ * IDE-style panes where the split ratio should be draggable.
19
+ *
20
+ * NOT WHEN
21
+ * - A fixed layout where the split never needs to change — use CSS grid,
22
+ * it's lighter weight.
23
+ * - Collapsible primary side navigation — use Sidebar, which has its own
24
+ * offcanvas/icon-collapse behavior; this is for peer content panes.
25
+ * - Content that should float above the page — use an overlay component.
26
+ *
27
+ * KEY RULES
28
+ * - Orientation is `orientation` ("horizontal" | "vertical") on
29
+ * ResizablePanelGroup — this is the v4 react-resizable-panels API; it is
30
+ * NOT `direction`, which is the older/deprecated prop name.
31
+ * - Give each ResizablePanel a `defaultSize` (percentage) so the initial
32
+ * split is deterministic — sizes across panels in a group should sum to 100.
33
+ * - `ResizableHandle withHandle` draws a visible grip; omit it for a bare
34
+ * drag line.
35
+ * - Groups can nest for layouts split on more than one axis.
36
+ *
37
+ * USAGE
38
+ * <ResizablePanelGroup orientation="horizontal" className="h-48 rounded-xl border">
39
+ * <ResizablePanel defaultSize={50}>...</ResizablePanel>
40
+ * <ResizableHandle withHandle />
41
+ * <ResizablePanel defaultSize={50}>...</ResizablePanel>
42
+ * </ResizablePanelGroup>
43
+ */
44
+ //# sourceMappingURL=resizable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizable.d.ts","sourceRoot":"","sources":["../../../src/components/ui/resizable.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,kBAAkB,MAAM,wBAAwB,CAAA;AAI5D,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,UAAU,qBAW/B;AAED,iBAAS,cAAc,CAAC,EACtB,UAAU,EACV,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,UAAU,qBA0B/B;AAED,iBAAS,eAAe,CAAC,EACvB,UAAU,EACV,SAAS,EACT,YAAY,EAAE,SAAS,EACvB,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,cAAc,GAAG;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,qBAqBA;AAED,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAA;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG"}
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { cn } from "../../lib/utils.js";
3
+ import * as React from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import * as ResizablePrimitive from "react-resizable-panels";
6
+ //#region src/components/ui/resizable.tsx
7
+ /**
8
+ * ResizablePanelGroup — draggable split panes, on react-resizable-panels v4.
9
+ *
10
+ * Follows the react-resizable-panels v4 API: orientation is set via
11
+ * `orientation` ("horizontal" | "vertical"), not the older `direction` prop.
12
+ */
13
+ function ResizablePanelGroup({ className, ...props }) {
14
+ return /* @__PURE__ */ jsx(ResizablePrimitive.Group, {
15
+ "data-slot": "resizable-panel-group",
16
+ className: cn("flex h-full w-full aria-[orientation=vertical]:flex-col", className),
17
+ ...props
18
+ });
19
+ }
20
+ function ResizablePanel({ elementRef, ...props }) {
21
+ const setElementRef = React.useCallback((el) => {
22
+ if (el?.firstElementChild instanceof HTMLElement) el.firstElementChild.tabIndex = 0;
23
+ if (typeof elementRef === "function") elementRef(el);
24
+ else if (elementRef) elementRef.current = el;
25
+ }, [elementRef]);
26
+ return /* @__PURE__ */ jsx(ResizablePrimitive.Panel, {
27
+ "data-slot": "resizable-panel",
28
+ elementRef: setElementRef,
29
+ ...props
30
+ });
31
+ }
32
+ function ResizableHandle({ withHandle, className, "aria-label": ariaLabel, ...props }) {
33
+ return /* @__PURE__ */ jsx(ResizablePrimitive.Separator, {
34
+ "data-slot": "resizable-handle",
35
+ "aria-label": ariaLabel ?? "Resize panel",
36
+ className: cn("relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90", className),
37
+ ...props,
38
+ children: withHandle && /* @__PURE__ */ jsx("div", { className: "z-10 flex h-6 w-1 shrink-0 rounded-lg bg-border" })
39
+ });
40
+ }
41
+ /**
42
+ * WHEN TO USE
43
+ * - User-adjustable split layouts — editor plus preview, list plus detail,
44
+ * IDE-style panes where the split ratio should be draggable.
45
+ *
46
+ * NOT WHEN
47
+ * - A fixed layout where the split never needs to change — use CSS grid,
48
+ * it's lighter weight.
49
+ * - Collapsible primary side navigation — use Sidebar, which has its own
50
+ * offcanvas/icon-collapse behavior; this is for peer content panes.
51
+ * - Content that should float above the page — use an overlay component.
52
+ *
53
+ * KEY RULES
54
+ * - Orientation is `orientation` ("horizontal" | "vertical") on
55
+ * ResizablePanelGroup — this is the v4 react-resizable-panels API; it is
56
+ * NOT `direction`, which is the older/deprecated prop name.
57
+ * - Give each ResizablePanel a `defaultSize` (percentage) so the initial
58
+ * split is deterministic — sizes across panels in a group should sum to 100.
59
+ * - `ResizableHandle withHandle` draws a visible grip; omit it for a bare
60
+ * drag line.
61
+ * - Groups can nest for layouts split on more than one axis.
62
+ *
63
+ * USAGE
64
+ * <ResizablePanelGroup orientation="horizontal" className="h-48 rounded-xl border">
65
+ * <ResizablePanel defaultSize={50}>...</ResizablePanel>
66
+ * <ResizableHandle withHandle />
67
+ * <ResizablePanel defaultSize={50}>...</ResizablePanel>
68
+ * </ResizablePanelGroup>
69
+ */
70
+ //#endregion
71
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
72
+
73
+ //# sourceMappingURL=resizable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizable.js","names":[],"sources":["../../../src/components/ui/resizable.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * ResizablePanelGroup — draggable split panes, on react-resizable-panels v4.\n *\n * Follows the react-resizable-panels v4 API: orientation is set via\n * `orientation` (\"horizontal\" | \"vertical\"), not the older `direction` prop.\n */\n\nimport * as React from \"react\"\nimport * as ResizablePrimitive from \"react-resizable-panels\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction ResizablePanelGroup({\n className,\n ...props\n}: ResizablePrimitive.GroupProps) {\n return (\n <ResizablePrimitive.Group\n data-slot=\"resizable-panel-group\"\n className={cn(\n \"flex h-full w-full aria-[orientation=vertical]:flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ResizablePanel({\n elementRef,\n ...props\n}: ResizablePrimitive.PanelProps) {\n // react-resizable-panels renders Panel as two nested divs — an outer one\n // (where `elementRef`/arbitrary props land) and an inner one, not exposed\n // via props at all, that actually carries `overflow: auto`. A tabIndex on\n // the outer div doesn't help a keyboard user reach the part that scrolls,\n // so this reaches one level in via the DOM to tag that inner div directly.\n const setElementRef = React.useCallback(\n (el: HTMLDivElement | null) => {\n if (el?.firstElementChild instanceof HTMLElement) {\n el.firstElementChild.tabIndex = 0\n }\n if (typeof elementRef === \"function\") elementRef(el)\n else if (elementRef) {\n ;(elementRef as React.RefObject<HTMLDivElement | null>).current = el\n }\n },\n [elementRef]\n )\n\n return (\n <ResizablePrimitive.Panel\n data-slot=\"resizable-panel\"\n elementRef={setElementRef}\n {...props}\n />\n )\n}\n\nfunction ResizableHandle({\n withHandle,\n className,\n \"aria-label\": ariaLabel,\n ...props\n}: ResizablePrimitive.SeparatorProps & {\n withHandle?: boolean\n}) {\n return (\n <ResizablePrimitive.Separator\n data-slot=\"resizable-handle\"\n // Falls back to a generic accessible name when the consumer doesn't\n // pass one — this keyboard-focusable, arrow-key-resizable control had\n // none at all otherwise (4.1.2). Direction-agnostic text since the\n // handle's own orientation is a runtime `aria-orientation`, not\n // knowable here at the type level.\n aria-label={ariaLabel ?? \"Resize panel\"}\n className={cn(\n \"relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90\",\n className\n )}\n {...props}\n >\n {withHandle && (\n <div className=\"z-10 flex h-6 w-1 shrink-0 rounded-lg bg-border\" />\n )}\n </ResizablePrimitive.Separator>\n )\n}\n\nexport { ResizableHandle, ResizablePanel, ResizablePanelGroup }\n\n/**\n * WHEN TO USE\n * - User-adjustable split layouts — editor plus preview, list plus detail,\n * IDE-style panes where the split ratio should be draggable.\n *\n * NOT WHEN\n * - A fixed layout where the split never needs to change — use CSS grid,\n * it's lighter weight.\n * - Collapsible primary side navigation — use Sidebar, which has its own\n * offcanvas/icon-collapse behavior; this is for peer content panes.\n * - Content that should float above the page — use an overlay component.\n *\n * KEY RULES\n * - Orientation is `orientation` (\"horizontal\" | \"vertical\") on\n * ResizablePanelGroup — this is the v4 react-resizable-panels API; it is\n * NOT `direction`, which is the older/deprecated prop name.\n * - Give each ResizablePanel a `defaultSize` (percentage) so the initial\n * split is deterministic — sizes across panels in a group should sum to 100.\n * - `ResizableHandle withHandle` draws a visible grip; omit it for a bare\n * drag line.\n * - Groups can nest for layouts split on more than one axis.\n *\n * USAGE\n * <ResizablePanelGroup orientation=\"horizontal\" className=\"h-48 rounded-xl border\">\n * <ResizablePanel defaultSize={50}>...</ResizablePanel>\n * <ResizableHandle withHandle />\n * <ResizablePanel defaultSize={50}>...</ResizablePanel>\n * </ResizablePanelGroup>\n */\n"],"mappings":";;;;;;;;;;;;AAcA,SAAS,oBAAoB,EAC3B,WACA,GAAG,SAC6B;CAChC,OACE,oBAAC,mBAAmB,OAApB;EACE,aAAU;EACV,WAAW,GACT,2DACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,YACA,GAAG,SAC6B;CAMhC,MAAM,gBAAgB,MAAM,aACzB,OAA8B;EAC7B,IAAI,IAAI,6BAA6B,aACnC,GAAG,kBAAkB,WAAW;EAElC,IAAI,OAAO,eAAe,YAAY,WAAW,EAAE;OAC9C,IAAI,YACN,WAAuD,UAAU;CAEtE,GACA,CAAC,UAAU,CACb;CAEA,OACE,oBAAC,mBAAmB,OAApB;EACE,aAAU;EACV,YAAY;EACZ,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EACvB,YACA,WACA,cAAc,WACd,GAAG,SAGF;CACD,OACE,oBAAC,mBAAmB,WAApB;EACE,aAAU;EAMV,cAAY,aAAa;EACzB,WAAW,GACT,wkBACA,SACF;EACA,GAAI;EAEH,UAAA,cACC,oBAAC,OAAD,EAAK,WAAU,kDAAmD,CAAA;CAExC,CAAA;AAElC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * ScrollArea — region with a styled custom scrollbar.
3
+ *
4
+ * Built on the Radix ScrollArea primitive. The thumb is styled from the
5
+ * `--color-border` token, a vertical ScrollBar is rendered by default, and
6
+ * the viewport's edges fade toward whatever's
7
+ * scrolled past (via the `scroll-fade` utility shipped in `shadcn/tailwind.css`,
8
+ * already imported in index.css) — same mechanism MessageScroller's viewport
9
+ * already uses, here defaulted to the vertical axis via `viewportClassName`.
10
+ */
11
+ import * as React from "react";
12
+ import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
13
+ declare function ScrollArea({ className, viewportClassName, children, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Root> & {
14
+ /** Defaults to `scroll-fade-y` — pass `scroll-fade-x` for a horizontal
15
+ * ScrollArea (paired with `<ScrollBar orientation="horizontal" />`), or
16
+ * `scroll-fade-none` to turn it off. Full replacement, not merged with
17
+ * the default, since only one scroll axis fades at a time. */
18
+ viewportClassName?: string;
19
+ }): React.JSX.Element;
20
+ declare function ScrollBar({ className, orientation, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): React.JSX.Element;
21
+ export { ScrollArea, ScrollBar };
22
+ /**
23
+ * WHEN TO USE
24
+ * - A list or panel constrained to a fixed height that needs a scrollbar
25
+ * matching the design system instead of the browser's native one.
26
+ * - Horizontal card/chip strips (e.g. a filmstrip of thumbnails).
27
+ *
28
+ * NOT WHEN
29
+ * - Whole-page scrolling — leave that to the browser; wrapping the page
30
+ * root in ScrollArea fights native scroll restoration and anchor links.
31
+ * - Content that already fits without overflow — it adds DOM/JS for nothing.
32
+ *
33
+ * KEY RULES
34
+ * - A vertical scrollbar renders by default. For horizontal overflow you
35
+ * must add an explicit `<ScrollBar orientation="horizontal" />` child —
36
+ * it is not inferred from content width.
37
+ * - The scrollable region needs an explicit height (or a bounded flex/grid
38
+ * ancestor) via `className` on ScrollArea — it doesn't scroll on its own.
39
+ * - The viewport fades vertically by default; pass `viewportClassName="scroll-fade-x"`
40
+ * for a horizontal ScrollArea, or `"scroll-fade-none"` to turn the fade off entirely.
41
+ *
42
+ * USAGE
43
+ * <ScrollArea className="h-64 w-56 rounded-md border">
44
+ * <div className="p-4">...</div>
45
+ * </ScrollArea>
46
+ *
47
+ * <ScrollArea
48
+ * className="w-80 rounded-md border whitespace-nowrap"
49
+ * viewportClassName="scroll-fade-x"
50
+ * >
51
+ * <div className="flex gap-3 p-4">...</div>
52
+ * <ScrollBar orientation="horizontal" />
53
+ * </ScrollArea>
54
+ */
55
+ //# sourceMappingURL=scroll-area.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-area.d.ts","sourceRoot":"","sources":["../../../src/components/ui/scroll-area.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAI5D,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,iBAAmC,EACnC,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC,GAAG;IACzD;;;kEAG8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,qBAqBA;AAED,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,WAAwB,EACxB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,mBAAmB,CAAC,mBAAmB,CAAC,qBAkBtE;AAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG"}
@@ -0,0 +1,72 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import "react";
3
+ import { ScrollArea as ScrollArea$1 } from "radix-ui";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/ui/scroll-area.tsx
6
+ function ScrollArea({ className, viewportClassName = "scroll-fade-y", children, ...props }) {
7
+ return /* @__PURE__ */ jsxs(ScrollArea$1.Root, {
8
+ "data-slot": "scroll-area",
9
+ className: cn("relative", className),
10
+ ...props,
11
+ children: [
12
+ /* @__PURE__ */ jsx(ScrollArea$1.Viewport, {
13
+ "data-slot": "scroll-area-viewport",
14
+ tabIndex: 0,
15
+ className: cn("size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1", viewportClassName),
16
+ children
17
+ }),
18
+ /* @__PURE__ */ jsx(ScrollBar, {}),
19
+ /* @__PURE__ */ jsx(ScrollArea$1.Corner, {})
20
+ ]
21
+ });
22
+ }
23
+ function ScrollBar({ className, orientation = "vertical", ...props }) {
24
+ return /* @__PURE__ */ jsx(ScrollArea$1.ScrollAreaScrollbar, {
25
+ "data-slot": "scroll-area-scrollbar",
26
+ "data-orientation": orientation,
27
+ orientation,
28
+ className: cn("flex touch-none p-px transition-colors select-none data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-l data-[orientation=vertical]:border-l-transparent", className),
29
+ ...props,
30
+ children: /* @__PURE__ */ jsx(ScrollArea$1.ScrollAreaThumb, {
31
+ "data-slot": "scroll-area-thumb",
32
+ className: "relative flex-1 rounded-full bg-border"
33
+ })
34
+ });
35
+ }
36
+ /**
37
+ * WHEN TO USE
38
+ * - A list or panel constrained to a fixed height that needs a scrollbar
39
+ * matching the design system instead of the browser's native one.
40
+ * - Horizontal card/chip strips (e.g. a filmstrip of thumbnails).
41
+ *
42
+ * NOT WHEN
43
+ * - Whole-page scrolling — leave that to the browser; wrapping the page
44
+ * root in ScrollArea fights native scroll restoration and anchor links.
45
+ * - Content that already fits without overflow — it adds DOM/JS for nothing.
46
+ *
47
+ * KEY RULES
48
+ * - A vertical scrollbar renders by default. For horizontal overflow you
49
+ * must add an explicit `<ScrollBar orientation="horizontal" />` child —
50
+ * it is not inferred from content width.
51
+ * - The scrollable region needs an explicit height (or a bounded flex/grid
52
+ * ancestor) via `className` on ScrollArea — it doesn't scroll on its own.
53
+ * - The viewport fades vertically by default; pass `viewportClassName="scroll-fade-x"`
54
+ * for a horizontal ScrollArea, or `"scroll-fade-none"` to turn the fade off entirely.
55
+ *
56
+ * USAGE
57
+ * <ScrollArea className="h-64 w-56 rounded-md border">
58
+ * <div className="p-4">...</div>
59
+ * </ScrollArea>
60
+ *
61
+ * <ScrollArea
62
+ * className="w-80 rounded-md border whitespace-nowrap"
63
+ * viewportClassName="scroll-fade-x"
64
+ * >
65
+ * <div className="flex gap-3 p-4">...</div>
66
+ * <ScrollBar orientation="horizontal" />
67
+ * </ScrollArea>
68
+ */
69
+ //#endregion
70
+ export { ScrollArea, ScrollBar };
71
+
72
+ //# sourceMappingURL=scroll-area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-area.js","names":[],"sources":["../../../src/components/ui/scroll-area.tsx"],"sourcesContent":["/**\n * ScrollArea — region with a styled custom scrollbar.\n *\n * Built on the Radix ScrollArea primitive. The thumb is styled from the\n * `--color-border` token, a vertical ScrollBar is rendered by default, and\n * the viewport's edges fade toward whatever's\n * scrolled past (via the `scroll-fade` utility shipped in `shadcn/tailwind.css`,\n * already imported in index.css) — same mechanism MessageScroller's viewport\n * already uses, here defaulted to the vertical axis via `viewportClassName`.\n */\n\nimport * as React from \"react\"\nimport { ScrollArea as ScrollAreaPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction ScrollArea({\n className,\n viewportClassName = \"scroll-fade-y\",\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root> & {\n /** Defaults to `scroll-fade-y` — pass `scroll-fade-x` for a horizontal\n * ScrollArea (paired with `<ScrollBar orientation=\"horizontal\" />`), or\n * `scroll-fade-none` to turn it off. Full replacement, not merged with\n * the default, since only one scroll axis fades at a time. */\n viewportClassName?: string\n}) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n tabIndex={0}\n className={cn(\n \"size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1\",\n viewportClassName\n )}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n )\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n data-orientation={orientation}\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-l data-[orientation=vertical]:border-l-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"relative flex-1 rounded-full bg-border\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n )\n}\n\nexport { ScrollArea, ScrollBar }\n\n/**\n * WHEN TO USE\n * - A list or panel constrained to a fixed height that needs a scrollbar\n * matching the design system instead of the browser's native one.\n * - Horizontal card/chip strips (e.g. a filmstrip of thumbnails).\n *\n * NOT WHEN\n * - Whole-page scrolling — leave that to the browser; wrapping the page\n * root in ScrollArea fights native scroll restoration and anchor links.\n * - Content that already fits without overflow — it adds DOM/JS for nothing.\n *\n * KEY RULES\n * - A vertical scrollbar renders by default. For horizontal overflow you\n * must add an explicit `<ScrollBar orientation=\"horizontal\" />` child —\n * it is not inferred from content width.\n * - The scrollable region needs an explicit height (or a bounded flex/grid\n * ancestor) via `className` on ScrollArea — it doesn't scroll on its own.\n * - The viewport fades vertically by default; pass `viewportClassName=\"scroll-fade-x\"`\n * for a horizontal ScrollArea, or `\"scroll-fade-none\"` to turn the fade off entirely.\n *\n * USAGE\n * <ScrollArea className=\"h-64 w-56 rounded-md border\">\n * <div className=\"p-4\">...</div>\n * </ScrollArea>\n *\n * <ScrollArea\n * className=\"w-80 rounded-md border whitespace-nowrap\"\n * viewportClassName=\"scroll-fade-x\"\n * >\n * <div className=\"flex gap-3 p-4\">...</div>\n * <ScrollBar orientation=\"horizontal\" />\n * </ScrollArea>\n */\n"],"mappings":";;;;;AAgBA,SAAS,WAAW,EAClB,WACA,oBAAoB,iBACpB,UACA,GAAG,SAOF;CACD,OACE,qBAAC,aAAoB,MAArB;EACE,aAAU;EACV,WAAW,GAAG,YAAY,SAAS;EACnC,GAAI;EAHN,UAAA;GAKE,oBAAC,aAAoB,UAArB;IACE,aAAU;IACV,UAAU;IACV,WAAW,GACT,sJACA,iBACF;IAEC;GAC2B,CAAA;GAC9B,oBAAC,WAAD,CAAY,CAAA;GACZ,oBAAC,aAAoB,QAArB,CAA6B,CAAA;EACL;;AAE9B;AAEA,SAAS,UAAU,EACjB,WACA,cAAc,YACd,GAAG,SACoE;CACvE,OACE,oBAAC,aAAoB,qBAArB;EACE,aAAU;EACV,oBAAkB;EACL;EACb,WAAW,GACT,sXACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,aAAoB,iBAArB;GACE,aAAU;GACV,WAAU;EACX,CAAA;CACsC,CAAA;AAE7C"}