@burtson-labs/ui 0.13.0 → 0.14.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 (391) hide show
  1. package/LICENSES/DEPENDENCIES.txt +2745 -0
  2. package/LICENSES/Radix-MIT.txt +21 -0
  3. package/LICENSES/cmdk-MIT.txt +21 -0
  4. package/LICENSES/overrides/react-remove-scroll-bar.txt +26 -0
  5. package/LICENSES/shadcn-MIT.txt +21 -0
  6. package/README.md +5 -1
  7. package/THIRD_PARTY_NOTICES.md +15 -3
  8. package/dist/components/accordion.d.ts +1 -1
  9. package/dist/components/accordion.js +9 -8
  10. package/dist/components/accordion.js.map +1 -1
  11. package/dist/components/alert-dialog.d.ts +1 -1
  12. package/dist/components/alert-dialog.js +12 -11
  13. package/dist/components/alert-dialog.js.map +1 -1
  14. package/dist/components/alert.js +1 -0
  15. package/dist/components/alert.js.map +1 -1
  16. package/dist/components/app-shell.js +1 -0
  17. package/dist/components/app-shell.js.map +1 -1
  18. package/dist/components/attachment.js +1 -0
  19. package/dist/components/attachment.js.map +1 -1
  20. package/dist/components/audio-player.js +1 -0
  21. package/dist/components/audio-player.js.map +1 -1
  22. package/dist/components/avatar.d.ts +1 -1
  23. package/dist/components/avatar.js +7 -6
  24. package/dist/components/avatar.js.map +1 -1
  25. package/dist/components/badge.js +3 -3
  26. package/dist/components/badge.js.map +1 -1
  27. package/dist/components/breadcrumb.js +3 -3
  28. package/dist/components/breadcrumb.js.map +1 -1
  29. package/dist/components/button.d.ts +2 -2
  30. package/dist/components/button.js +3 -3
  31. package/dist/components/button.js.map +1 -1
  32. package/dist/components/card.d.ts +1 -1
  33. package/dist/components/card.js +1 -0
  34. package/dist/components/card.js.map +1 -1
  35. package/dist/components/chat-history.js +1 -0
  36. package/dist/components/chat-history.js.map +1 -1
  37. package/dist/components/chat-layout.js +1 -0
  38. package/dist/components/chat-layout.js.map +1 -1
  39. package/dist/components/checkbox-card.d.ts +1 -1
  40. package/dist/components/checkbox-card.js +3 -3
  41. package/dist/components/checkbox-card.js.map +1 -1
  42. package/dist/components/checkbox.d.ts +1 -1
  43. package/dist/components/checkbox.js +6 -5
  44. package/dist/components/checkbox.js.map +1 -1
  45. package/dist/components/collapsible.d.ts +1 -1
  46. package/dist/components/collapsible.js +7 -6
  47. package/dist/components/collapsible.js.map +1 -1
  48. package/dist/components/combobox.js +1 -0
  49. package/dist/components/combobox.js.map +1 -1
  50. package/dist/components/command.d.ts +1 -1
  51. package/dist/components/command.js +12 -11
  52. package/dist/components/command.js.map +1 -1
  53. package/dist/components/composer.js +1 -0
  54. package/dist/components/composer.js.map +1 -1
  55. package/dist/components/connection-status.js +1 -0
  56. package/dist/components/connection-status.js.map +1 -1
  57. package/dist/components/context-menu.d.ts +1 -1
  58. package/dist/components/context-menu.js +19 -18
  59. package/dist/components/context-menu.js.map +1 -1
  60. package/dist/components/conversation.js +1 -0
  61. package/dist/components/conversation.js.map +1 -1
  62. package/dist/components/copy-button.js +1 -0
  63. package/dist/components/copy-button.js.map +1 -1
  64. package/dist/components/data-table.js +4 -2
  65. package/dist/components/data-table.js.map +1 -1
  66. package/dist/components/dialog.d.ts +1 -1
  67. package/dist/components/dialog.js +13 -12
  68. package/dist/components/dialog.js.map +1 -1
  69. package/dist/components/dropdown-menu.d.ts +1 -1
  70. package/dist/components/dropdown-menu.js +19 -18
  71. package/dist/components/dropdown-menu.js.map +1 -1
  72. package/dist/components/editor-tabs.js +1 -0
  73. package/dist/components/editor-tabs.js.map +1 -1
  74. package/dist/components/empty-state.js +1 -0
  75. package/dist/components/empty-state.js.map +1 -1
  76. package/dist/components/field.js +1 -0
  77. package/dist/components/field.js.map +1 -1
  78. package/dist/components/icon-button.js +1 -0
  79. package/dist/components/icon-button.js.map +1 -1
  80. package/dist/components/input.js +1 -0
  81. package/dist/components/input.js.map +1 -1
  82. package/dist/components/kbd.js +1 -0
  83. package/dist/components/kbd.js.map +1 -1
  84. package/dist/components/label.d.ts +1 -1
  85. package/dist/components/label.js +5 -4
  86. package/dist/components/label.js.map +1 -1
  87. package/dist/components/markdown.js +1 -0
  88. package/dist/components/markdown.js.map +1 -1
  89. package/dist/components/menubar.d.ts +1 -1
  90. package/dist/components/menubar.js +20 -19
  91. package/dist/components/menubar.js.map +1 -1
  92. package/dist/components/message-actions.js +1 -0
  93. package/dist/components/message-actions.js.map +1 -1
  94. package/dist/components/message.js +1 -0
  95. package/dist/components/message.js.map +1 -1
  96. package/dist/components/mobile-nav.js +1 -0
  97. package/dist/components/mobile-nav.js.map +1 -1
  98. package/dist/components/navigation-menu.d.ts +1 -1
  99. package/dist/components/navigation-menu.js +12 -11
  100. package/dist/components/navigation-menu.js.map +1 -1
  101. package/dist/components/onboarding-checklist.js +1 -0
  102. package/dist/components/onboarding-checklist.js.map +1 -1
  103. package/dist/components/page-header.js +1 -0
  104. package/dist/components/page-header.js.map +1 -1
  105. package/dist/components/pagination.js +3 -2
  106. package/dist/components/pagination.js.map +1 -1
  107. package/dist/components/popover.d.ts +1 -1
  108. package/dist/components/popover.js +8 -7
  109. package/dist/components/popover.js.map +1 -1
  110. package/dist/components/progress.d.ts +1 -1
  111. package/dist/components/progress.js +6 -5
  112. package/dist/components/progress.js.map +1 -1
  113. package/dist/components/radio-group.d.ts +1 -1
  114. package/dist/components/radio-group.js +7 -6
  115. package/dist/components/radio-group.js.map +1 -1
  116. package/dist/components/reasoning.js +5 -4
  117. package/dist/components/reasoning.js.map +1 -1
  118. package/dist/components/resizable.js +1 -0
  119. package/dist/components/resizable.js.map +1 -1
  120. package/dist/components/scroll-area.d.ts +1 -1
  121. package/dist/components/scroll-area.js +9 -8
  122. package/dist/components/scroll-area.js.map +1 -1
  123. package/dist/components/secret-input.js +1 -0
  124. package/dist/components/secret-input.js.map +1 -1
  125. package/dist/components/select.d.ts +1 -1
  126. package/dist/components/select.js +23 -18
  127. package/dist/components/select.js.map +1 -1
  128. package/dist/components/separator.d.ts +1 -1
  129. package/dist/components/separator.js +5 -4
  130. package/dist/components/separator.js.map +1 -1
  131. package/dist/components/sheet.d.ts +1 -1
  132. package/dist/components/sheet.js +10 -9
  133. package/dist/components/sheet.js.map +1 -1
  134. package/dist/components/skeleton.js +1 -0
  135. package/dist/components/skeleton.js.map +1 -1
  136. package/dist/components/slider.js +1 -0
  137. package/dist/components/slider.js.map +1 -1
  138. package/dist/components/source.js +1 -0
  139. package/dist/components/source.js.map +1 -1
  140. package/dist/components/spinner.js +1 -0
  141. package/dist/components/spinner.js.map +1 -1
  142. package/dist/components/stat-card.js +1 -0
  143. package/dist/components/stat-card.js.map +1 -1
  144. package/dist/components/status.js +1 -0
  145. package/dist/components/status.js.map +1 -1
  146. package/dist/components/steps.js +1 -0
  147. package/dist/components/steps.js.map +1 -1
  148. package/dist/components/switch.d.ts +1 -1
  149. package/dist/components/switch.js +6 -5
  150. package/dist/components/switch.js.map +1 -1
  151. package/dist/components/table.js +1 -0
  152. package/dist/components/table.js.map +1 -1
  153. package/dist/components/tabs.d.ts +1 -1
  154. package/dist/components/tabs.js +8 -7
  155. package/dist/components/tabs.js.map +1 -1
  156. package/dist/components/textarea.js +1 -0
  157. package/dist/components/textarea.js.map +1 -1
  158. package/dist/components/toast.d.ts +1 -1
  159. package/dist/components/toast.js +11 -10
  160. package/dist/components/toast.js.map +1 -1
  161. package/dist/components/toaster.js +1 -0
  162. package/dist/components/toaster.js.map +1 -1
  163. package/dist/components/tool-call.js +5 -4
  164. package/dist/components/tool-call.js.map +1 -1
  165. package/dist/components/toolbar.js +1 -0
  166. package/dist/components/toolbar.js.map +1 -1
  167. package/dist/components/tooltip.d.ts +1 -1
  168. package/dist/components/tooltip.js +10 -9
  169. package/dist/components/tooltip.js.map +1 -1
  170. package/dist/components/tour.js +8 -6
  171. package/dist/components/tour.js.map +1 -1
  172. package/dist/components/tree-view.js +1 -0
  173. package/dist/components/tree-view.js.map +1 -1
  174. package/dist/components/voice-recorder.js +1 -0
  175. package/dist/components/voice-recorder.js.map +1 -1
  176. package/dist/primitives/vendor/cmdk/command-score.d.ts +1 -0
  177. package/dist/primitives/vendor/cmdk/command-score.js +64 -0
  178. package/dist/primitives/vendor/cmdk/command-score.js.map +1 -0
  179. package/dist/primitives/vendor/cmdk/index.d.ts +384 -0
  180. package/dist/primitives/vendor/cmdk/index.js +687 -0
  181. package/dist/primitives/vendor/cmdk/index.js.map +1 -0
  182. package/dist/primitives/vendor/radix/number/index.d.ts +1 -0
  183. package/dist/primitives/vendor/radix/number/number.d.ts +2 -0
  184. package/dist/primitives/vendor/radix/number/number.js +9 -0
  185. package/dist/primitives/vendor/radix/number/number.js.map +1 -0
  186. package/dist/primitives/vendor/radix/primitive/index.d.ts +2 -0
  187. package/dist/primitives/vendor/radix/primitive/is-development.d.ts +1 -0
  188. package/dist/primitives/vendor/radix/primitive/is-development.js +7 -0
  189. package/dist/primitives/vendor/radix/primitive/is-development.js.map +1 -0
  190. package/dist/primitives/vendor/radix/primitive/primitive.d.ts +14 -0
  191. package/dist/primitives/vendor/radix/primitive/primitive.js +12 -0
  192. package/dist/primitives/vendor/radix/primitive/primitive.js.map +1 -0
  193. package/dist/primitives/vendor/radix/primitive/types.d.ts +5 -0
  194. package/dist/primitives/vendor/radix/react-accordion/accordion.d.ts +112 -0
  195. package/dist/primitives/vendor/radix/react-accordion/accordion.js +266 -0
  196. package/dist/primitives/vendor/radix/react-accordion/accordion.js.map +1 -0
  197. package/dist/primitives/vendor/radix/react-accordion/index.d.ts +2 -0
  198. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.d.ts +49 -0
  199. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js +122 -0
  200. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js.map +1 -0
  201. package/dist/primitives/vendor/radix/react-alert-dialog/index.d.ts +2 -0
  202. package/dist/primitives/vendor/radix/react-arrow/arrow.d.ts +9 -0
  203. package/dist/primitives/vendor/radix/react-arrow/arrow.js +22 -0
  204. package/dist/primitives/vendor/radix/react-arrow/arrow.js.map +1 -0
  205. package/dist/primitives/vendor/radix/react-arrow/index.d.ts +2 -0
  206. package/dist/primitives/vendor/radix/react-avatar/avatar.d.ts +19 -0
  207. package/dist/primitives/vendor/radix/react-avatar/avatar.js +132 -0
  208. package/dist/primitives/vendor/radix/react-avatar/avatar.js.map +1 -0
  209. package/dist/primitives/vendor/radix/react-avatar/index.d.ts +2 -0
  210. package/dist/primitives/vendor/radix/react-checkbox/checkbox.d.ts +47 -0
  211. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js +197 -0
  212. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js.map +1 -0
  213. package/dist/primitives/vendor/radix/react-checkbox/index.d.ts +2 -0
  214. package/dist/primitives/vendor/radix/react-collapsible/collapsible.d.ts +31 -0
  215. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js +133 -0
  216. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js.map +1 -0
  217. package/dist/primitives/vendor/radix/react-collapsible/index.d.ts +2 -0
  218. package/dist/primitives/vendor/radix/react-collection/collection-legacy.d.ts +21 -0
  219. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js +84 -0
  220. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js.map +1 -0
  221. package/dist/primitives/vendor/radix/react-collection/collection.d.ts +32 -0
  222. package/dist/primitives/vendor/radix/react-collection/index.d.ts +4 -0
  223. package/dist/primitives/vendor/radix/react-collection/ordered-dictionary.d.ts +51 -0
  224. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.d.ts +13 -0
  225. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js +43 -0
  226. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js.map +1 -0
  227. package/dist/primitives/vendor/radix/react-compose-refs/index.d.ts +1 -0
  228. package/dist/primitives/vendor/radix/react-context/create-context.d.ts +45 -0
  229. package/dist/primitives/vendor/radix/react-context/create-context.js +74 -0
  230. package/dist/primitives/vendor/radix/react-context/create-context.js.map +1 -0
  231. package/dist/primitives/vendor/radix/react-context/index.d.ts +2 -0
  232. package/dist/primitives/vendor/radix/react-context-menu/context-menu.d.ts +95 -0
  233. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js +279 -0
  234. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js.map +1 -0
  235. package/dist/primitives/vendor/radix/react-context-menu/index.d.ts +2 -0
  236. package/dist/primitives/vendor/radix/react-dialog/dialog.d.ts +97 -0
  237. package/dist/primitives/vendor/radix/react-dialog/dialog.js +262 -0
  238. package/dist/primitives/vendor/radix/react-dialog/dialog.js.map +1 -0
  239. package/dist/primitives/vendor/radix/react-dialog/index.d.ts +4 -0
  240. package/dist/primitives/vendor/radix/react-direction/direction.d.ts +10 -0
  241. package/dist/primitives/vendor/radix/react-direction/direction.js +13 -0
  242. package/dist/primitives/vendor/radix/react-direction/direction.js.map +1 -0
  243. package/dist/primitives/vendor/radix/react-direction/index.d.ts +1 -0
  244. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.d.ts +61 -0
  245. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js +336 -0
  246. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js.map +1 -0
  247. package/dist/primitives/vendor/radix/react-dismissable-layer/index.d.ts +4 -0
  248. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.d.ts +95 -0
  249. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js +257 -0
  250. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js.map +1 -0
  251. package/dist/primitives/vendor/radix/react-dropdown-menu/index.d.ts +2 -0
  252. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.d.ts +11 -0
  253. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js +49 -0
  254. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js.map +1 -0
  255. package/dist/primitives/vendor/radix/react-focus-guards/index.d.ts +1 -0
  256. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.d.ts +31 -0
  257. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js +221 -0
  258. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js.map +1 -0
  259. package/dist/primitives/vendor/radix/react-focus-scope/index.d.ts +1 -0
  260. package/dist/primitives/vendor/radix/react-id/id.d.ts +2 -0
  261. package/dist/primitives/vendor/radix/react-id/id.js +17 -0
  262. package/dist/primitives/vendor/radix/react-id/id.js.map +1 -0
  263. package/dist/primitives/vendor/radix/react-id/index.d.ts +1 -0
  264. package/dist/primitives/vendor/radix/react-label/index.d.ts +2 -0
  265. package/dist/primitives/vendor/radix/react-label/label.d.ts +9 -0
  266. package/dist/primitives/vendor/radix/react-label/label.js +21 -0
  267. package/dist/primitives/vendor/radix/react-label/label.js.map +1 -0
  268. package/dist/primitives/vendor/radix/react-menu/index.d.ts +2 -0
  269. package/dist/primitives/vendor/radix/react-menu/menu.d.ts +173 -0
  270. package/dist/primitives/vendor/radix/react-menu/menu.js +806 -0
  271. package/dist/primitives/vendor/radix/react-menu/menu.js.map +1 -0
  272. package/dist/primitives/vendor/radix/react-menubar/index.d.ts +2 -0
  273. package/dist/primitives/vendor/radix/react-menubar/menubar.d.ts +106 -0
  274. package/dist/primitives/vendor/radix/react-menubar/menubar.js +377 -0
  275. package/dist/primitives/vendor/radix/react-menubar/menubar.js.map +1 -0
  276. package/dist/primitives/vendor/radix/react-navigation-menu/index.d.ts +2 -0
  277. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.d.ts +124 -0
  278. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js +743 -0
  279. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js.map +1 -0
  280. package/dist/primitives/vendor/radix/react-popover/index.d.ts +1 -0
  281. package/dist/primitives/vendor/radix/react-popover/popover.d.ts +83 -0
  282. package/dist/primitives/vendor/radix/react-popover/popover.js +236 -0
  283. package/dist/primitives/vendor/radix/react-popover/popover.js.map +1 -0
  284. package/dist/primitives/vendor/radix/react-popper/index.d.ts +2 -0
  285. package/dist/primitives/vendor/radix/react-popper/popper.d.ts +44 -0
  286. package/dist/primitives/vendor/radix/react-popper/popper.js +276 -0
  287. package/dist/primitives/vendor/radix/react-popper/popper.js.map +1 -0
  288. package/dist/primitives/vendor/radix/react-portal/index.d.ts +2 -0
  289. package/dist/primitives/vendor/radix/react-portal/portal.d.ts +13 -0
  290. package/dist/primitives/vendor/radix/react-portal/portal.js +21 -0
  291. package/dist/primitives/vendor/radix/react-portal/portal.js.map +1 -0
  292. package/dist/primitives/vendor/radix/react-presence/index.d.ts +2 -0
  293. package/dist/primitives/vendor/radix/react-presence/presence.d.ts +11 -0
  294. package/dist/primitives/vendor/radix/react-presence/presence.js +152 -0
  295. package/dist/primitives/vendor/radix/react-presence/presence.js.map +1 -0
  296. package/dist/primitives/vendor/radix/react-presence/use-state-machine.d.ts +10 -0
  297. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js +12 -0
  298. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js.map +1 -0
  299. package/dist/primitives/vendor/radix/react-primitive/index.d.ts +2 -0
  300. package/dist/primitives/vendor/radix/react-primitive/primitive.d.ts +56 -0
  301. package/dist/primitives/vendor/radix/react-primitive/primitive.js +84 -0
  302. package/dist/primitives/vendor/radix/react-primitive/primitive.js.map +1 -0
  303. package/dist/primitives/vendor/radix/react-progress/index.d.ts +2 -0
  304. package/dist/primitives/vendor/radix/react-progress/progress.d.ts +17 -0
  305. package/dist/primitives/vendor/radix/react-progress/progress.js +79 -0
  306. package/dist/primitives/vendor/radix/react-progress/progress.js.map +1 -0
  307. package/dist/primitives/vendor/radix/react-radio-group/index.d.ts +2 -0
  308. package/dist/primitives/vendor/radix/react-radio-group/radio-group.d.ts +55 -0
  309. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js +173 -0
  310. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js.map +1 -0
  311. package/dist/primitives/vendor/radix/react-radio-group/radio.d.ts +62 -0
  312. package/dist/primitives/vendor/radix/react-radio-group/radio.js +150 -0
  313. package/dist/primitives/vendor/radix/react-radio-group/radio.js.map +1 -0
  314. package/dist/primitives/vendor/radix/react-roving-focus/index.d.ts +2 -0
  315. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.d.ts +47 -0
  316. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js +218 -0
  317. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js.map +1 -0
  318. package/dist/primitives/vendor/radix/react-scroll-area/index.d.ts +2 -0
  319. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.d.ts +121 -0
  320. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js +713 -0
  321. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js.map +1 -0
  322. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.d.ts +10 -0
  323. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js +12 -0
  324. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js.map +1 -0
  325. package/dist/primitives/vendor/radix/react-select/index.d.ts +2 -0
  326. package/dist/primitives/vendor/radix/react-select/select.d.ts +163 -0
  327. package/dist/primitives/vendor/radix/react-select/select.js +1040 -0
  328. package/dist/primitives/vendor/radix/react-select/select.js.map +1 -0
  329. package/dist/primitives/vendor/radix/react-separator/index.d.ts +2 -0
  330. package/dist/primitives/vendor/radix/react-separator/separator.d.ts +20 -0
  331. package/dist/primitives/vendor/radix/react-separator/separator.js +29 -0
  332. package/dist/primitives/vendor/radix/react-separator/separator.js.map +1 -0
  333. package/dist/primitives/vendor/radix/react-slot/index.d.ts +1 -0
  334. package/dist/primitives/vendor/radix/react-slot/slot.d.ts +29 -0
  335. package/dist/primitives/vendor/radix/react-slot/slot.js +107 -0
  336. package/dist/primitives/vendor/radix/react-slot/slot.js.map +1 -0
  337. package/dist/primitives/vendor/radix/react-switch/index.d.ts +2 -0
  338. package/dist/primitives/vendor/radix/react-switch/switch.d.ts +41 -0
  339. package/dist/primitives/vendor/radix/react-switch/switch.js +185 -0
  340. package/dist/primitives/vendor/radix/react-switch/switch.js.map +1 -0
  341. package/dist/primitives/vendor/radix/react-tabs/index.d.ts +2 -0
  342. package/dist/primitives/vendor/radix/react-tabs/tabs.d.ts +54 -0
  343. package/dist/primitives/vendor/radix/react-tabs/tabs.js +145 -0
  344. package/dist/primitives/vendor/radix/react-tabs/tabs.js.map +1 -0
  345. package/dist/primitives/vendor/radix/react-toast/index.d.ts +2 -0
  346. package/dist/primitives/vendor/radix/react-toast/toast.d.ts +125 -0
  347. package/dist/primitives/vendor/radix/react-toast/toast.js +557 -0
  348. package/dist/primitives/vendor/radix/react-toast/toast.js.map +1 -0
  349. package/dist/primitives/vendor/radix/react-tooltip/index.d.ts +2 -0
  350. package/dist/primitives/vendor/radix/react-tooltip/tooltip.d.ts +99 -0
  351. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js +503 -0
  352. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js.map +1 -0
  353. package/dist/primitives/vendor/radix/react-use-callback-ref/index.d.ts +1 -0
  354. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.d.ts +6 -0
  355. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js +18 -0
  356. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js.map +1 -0
  357. package/dist/primitives/vendor/radix/react-use-controllable-state/index.d.ts +2 -0
  358. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state-reducer.d.ts +28 -0
  359. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.d.ts +11 -0
  360. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js +59 -0
  361. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js.map +1 -0
  362. package/dist/primitives/vendor/radix/react-use-effect-event/index.d.ts +1 -0
  363. package/dist/primitives/vendor/radix/react-use-effect-event/use-effect-event.d.ts +7 -0
  364. package/dist/primitives/vendor/radix/react-use-is-hydrated/index.d.ts +1 -0
  365. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.d.ts +1 -0
  366. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js +18 -0
  367. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js.map +1 -0
  368. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.d.ts +6 -0
  369. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js +19 -0
  370. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js.map +1 -0
  371. package/dist/primitives/vendor/radix/react-use-layout-effect/index.d.ts +1 -0
  372. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.d.ts +10 -0
  373. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js +15 -0
  374. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js.map +1 -0
  375. package/dist/primitives/vendor/radix/react-use-previous/index.d.ts +1 -0
  376. package/dist/primitives/vendor/radix/react-use-previous/use-previous.d.ts +2 -0
  377. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js +20 -0
  378. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js.map +1 -0
  379. package/dist/primitives/vendor/radix/react-use-size/index.d.ts +1 -0
  380. package/dist/primitives/vendor/radix/react-use-size/use-size.d.ts +5 -0
  381. package/dist/primitives/vendor/radix/react-use-size/use-size.js +42 -0
  382. package/dist/primitives/vendor/radix/react-use-size/use-size.js.map +1 -0
  383. package/dist/primitives/vendor/radix/react-visually-hidden/index.d.ts +2 -0
  384. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.d.ts +21 -0
  385. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js +32 -0
  386. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js.map +1 -0
  387. package/dist/primitives/vendor/radix/rect/index.d.ts +2 -0
  388. package/dist/primitives/vendor/radix/rect/observe-element-rect.d.ts +16 -0
  389. package/dist/styles.css +1 -1
  390. package/package.json +21 -11
  391. package/vendor-manifest.json +1101 -0
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Slot } from "radix-ui";
3
+ import { Root as Slot } from "../primitives/vendor/radix/react-slot/slot.js";
3
4
  import "react";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  import { cva } from "class-variance-authority";
@@ -18,8 +19,7 @@ var badgeVariants = cva("inline-flex w-fit shrink-0 items-center gap-1.5 rounded
18
19
  defaultVariants: { variant: "default" }
19
20
  });
20
21
  function Badge({ className, variant, asChild = false, ...props }) {
21
- const Comp = asChild ? Slot.Root : "span";
22
- return /* @__PURE__ */ jsx(Comp, {
22
+ return /* @__PURE__ */ jsx(asChild ? Slot : "span", {
23
23
  "data-slot": "badge",
24
24
  className: cn(badgeVariants({ variant }), className),
25
25
  ...props
@@ -1 +1 @@
1
- {"version":3,"file":"badge.js","names":[],"sources":["../../src/components/badge.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nconst badgeVariants = cva(\n 'inline-flex w-fit shrink-0 items-center gap-1.5 rounded-full border px-2 py-0.5 text-[11px] font-semibold leading-4 whitespace-nowrap outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-ring/20 [&>svg]:size-3',\n {\n variants: {\n variant: {\n default: 'border-border bg-surface-muted text-foreground',\n // 0.x name for the neutral tag; kept so existing apps keep compiling.\n secondary: 'border-border bg-surface-muted text-foreground',\n brand: 'border-brand/20 bg-brand-soft text-brand-soft-foreground',\n success: 'border-success/20 bg-success/10 text-success',\n warning: 'border-warning/20 bg-warning/10 text-warning',\n destructive: 'border-destructive/20 bg-destructive/10 text-destructive',\n info: 'border-info/20 bg-info/10 text-info',\n outline: 'border-border-strong bg-transparent text-muted-foreground',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n);\n\nexport interface BadgeProps\n extends React.ComponentProps<'span'>, VariantProps<typeof badgeVariants> {\n asChild?: boolean;\n}\n\nfunction Badge({ className, variant, asChild = false, ...props }: BadgeProps) {\n const Comp = asChild ? Slot.Root : 'span';\n return (\n <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant }), className)} {...props} />\n );\n}\n\nexport { Badge, badgeVariants };\n"],"mappings":";;;;;;AAMA,IAAM,gBAAgB,IACpB,2OACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EAET,WAAW;EACX,OAAO;EACP,SAAS;EACT,SAAS;EACT,aAAa;EACb,MAAM;EACN,SAAS;CACX,EACF;CACA,iBAAiB,EAAE,SAAS,UAAU;AACxC,CACF;AAOA,SAAS,MAAM,EAAE,WAAW,SAAS,UAAU,OAAO,GAAG,SAAqB;CAC5E,MAAM,OAAO,UAAU,KAAK,OAAO;CACnC,OACE,oBAAC,MAAD;EAAM,aAAU;EAAQ,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EAAG,GAAI;CAAQ,CAAA;AAE9F"}
1
+ {"version":3,"file":"badge.js","names":["Slot.Root"],"sources":["../../src/components/badge.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as Slot from '../primitives/vendor/radix/react-slot';\n\nconst badgeVariants = cva(\n 'inline-flex w-fit shrink-0 items-center gap-1.5 rounded-full border px-2 py-0.5 text-[11px] font-semibold leading-4 whitespace-nowrap outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-ring/20 [&>svg]:size-3',\n {\n variants: {\n variant: {\n default: 'border-border bg-surface-muted text-foreground',\n // 0.x name for the neutral tag; kept so existing apps keep compiling.\n secondary: 'border-border bg-surface-muted text-foreground',\n brand: 'border-brand/20 bg-brand-soft text-brand-soft-foreground',\n success: 'border-success/20 bg-success/10 text-success',\n warning: 'border-warning/20 bg-warning/10 text-warning',\n destructive: 'border-destructive/20 bg-destructive/10 text-destructive',\n info: 'border-info/20 bg-info/10 text-info',\n outline: 'border-border-strong bg-transparent text-muted-foreground',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n);\n\nexport interface BadgeProps\n extends React.ComponentProps<'span'>, VariantProps<typeof badgeVariants> {\n asChild?: boolean;\n}\n\nfunction Badge({ className, variant, asChild = false, ...props }: BadgeProps) {\n const Comp = asChild ? Slot.Root : 'span';\n return (\n <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant }), className)} {...props} />\n );\n}\n\nexport { Badge, badgeVariants };\n"],"mappings":";;;;;;;AAMA,IAAM,gBAAgB,IACpB,2OACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EAET,WAAW;EACX,OAAO;EACP,SAAS;EACT,SAAS;EACT,aAAa;EACb,MAAM;EACN,SAAS;CACX,EACF;CACA,iBAAiB,EAAE,SAAS,UAAU;AACxC,CACF;AAOA,SAAS,MAAM,EAAE,WAAW,SAAS,UAAU,OAAO,GAAG,SAAqB;CAE5E,OACE,oBAFW,UAAUA,OAAY,QAEjC;EAAM,aAAU;EAAQ,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EAAG,GAAI;CAAQ,CAAA;AAE9F"}
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Slot } from "radix-ui";
3
+ import { Root as Slot } from "../primitives/vendor/radix/react-slot/slot.js";
3
4
  import "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import ChevronRight from "@burtson-labs/icons/react/chevron-right";
@@ -27,8 +28,7 @@ function BreadcrumbItem({ className, ...props }) {
27
28
  });
28
29
  }
29
30
  function BreadcrumbLink({ asChild, className, ...props }) {
30
- const Comp = asChild ? Slot.Root : "a";
31
- return /* @__PURE__ */ jsx(Comp, {
31
+ return /* @__PURE__ */ jsx(asChild ? Slot : "a", {
32
32
  "data-slot": "breadcrumb-link",
33
33
  className: cn("transition-colors hover:text-foreground", className),
34
34
  ...props
@@ -1 +1 @@
1
- {"version":3,"file":"breadcrumb.js","names":[],"sources":["../../src/components/breadcrumb.tsx"],"sourcesContent":["import ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport MoreHorizontal from '@burtson-labs/icons/react/more-horizontal';\nimport { Slot } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction Breadcrumb(props: React.ComponentProps<'nav'>) {\n return <nav aria-label=\"Breadcrumb\" data-slot=\"breadcrumb\" {...props} />;\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n 'flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn('inline-flex items-center gap-1.5', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbLink({\n asChild,\n className,\n ...props\n}: React.ComponentProps<'a'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : 'a';\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn('transition-colors hover:text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('font-medium text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('[&>svg]:size-3.5', className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n );\n}\n\nfunction BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex size-9 items-center justify-center', className)}\n {...props}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n};\n"],"mappings":";;;;;;;AAOA,SAAS,WAAW,OAAoC;CACtD,OAAO,oBAAC,OAAD;EAAK,cAAW;EAAa,aAAU;EAAa,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAqC;CAC3E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,iFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAqC;CAC3E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,oCAAoC,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,SACA,WACA,GAAG,SACiD;CACpD,MAAM,OAAO,UAAU,KAAK,OAAO;CACnC,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAuC;CAC7E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,MAAK;EACL,iBAAc;EACd,gBAAa;EACb,WAAW,GAAG,+BAA+B,SAAS;EACtD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAAE,UAAU,WAAW,GAAG,SAAqC;CAC1F,OACE,oBAAC,MAAD;EACE,aAAU;EACV,MAAK;EACL,eAAY;EACZ,WAAW,GAAG,oBAAoB,SAAS;EAC3C,GAAI;EAEH,UAAA,YAAY,oBAAC,cAAD,CAAe,CAAA;CAC1B,CAAA;AAER;AAEA,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAuC;CACjF,OACE,qBAAC,QAAD;EACE,aAAU;EACV,MAAK;EACL,eAAY;EACZ,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;EALN,UAAA,CAOE,oBAAC,gBAAD,EAAgB,WAAU,SAAU,CAAA,GACpC,oBAAC,QAAD;GAAM,WAAU;GAAU,UAAA;EAAU,CAAA,CAChC;;AAEV"}
1
+ {"version":3,"file":"breadcrumb.js","names":["Slot.Root"],"sources":["../../src/components/breadcrumb.tsx"],"sourcesContent":["import ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport MoreHorizontal from '@burtson-labs/icons/react/more-horizontal';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as Slot from '../primitives/vendor/radix/react-slot';\n\nfunction Breadcrumb(props: React.ComponentProps<'nav'>) {\n return <nav aria-label=\"Breadcrumb\" data-slot=\"breadcrumb\" {...props} />;\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n 'flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn('inline-flex items-center gap-1.5', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbLink({\n asChild,\n className,\n ...props\n}: React.ComponentProps<'a'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : 'a';\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn('transition-colors hover:text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('font-medium text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('[&>svg]:size-3.5', className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n );\n}\n\nfunction BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex size-9 items-center justify-center', className)}\n {...props}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n};\n"],"mappings":";;;;;;;;AAOA,SAAS,WAAW,OAAoC;CACtD,OAAO,oBAAC,OAAD;EAAK,cAAW;EAAa,aAAU;EAAa,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAqC;CAC3E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,iFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAqC;CAC3E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,oCAAoC,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,SACA,WACA,GAAG,SACiD;CAEpD,OACE,oBAFW,UAAUA,OAAY,KAEjC;EACE,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAuC;CAC7E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,MAAK;EACL,iBAAc;EACd,gBAAa;EACb,WAAW,GAAG,+BAA+B,SAAS;EACtD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAAE,UAAU,WAAW,GAAG,SAAqC;CAC1F,OACE,oBAAC,MAAD;EACE,aAAU;EACV,MAAK;EACL,eAAY;EACZ,WAAW,GAAG,oBAAoB,SAAS;EAC3C,GAAI;EAEH,UAAA,YAAY,oBAAC,cAAD,CAAe,CAAA;CAC1B,CAAA;AAER;AAEA,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAuC;CACjF,OACE,qBAAC,QAAD;EACE,aAAU;EACV,MAAK;EACL,eAAY;EACZ,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;EALN,UAAA,CAOE,oBAAC,gBAAD,EAAgB,WAAU,SAAU,CAAA,GACpC,oBAAC,QAAD;GAAM,WAAU;GAAU,UAAA;EAAU,CAAA,CAChC;;AAEV"}
@@ -1,8 +1,8 @@
1
1
  import { type VariantProps } from 'class-variance-authority';
2
2
  import * as React from 'react';
3
3
  declare const buttonVariants: (props?: ({
4
- variant?: "secondary" | "destructive" | "brand" | "link" | "default" | "soft" | "outline" | "ghost" | null | undefined;
5
- size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | undefined;
4
+ variant?: "secondary" | "destructive" | "brand" | "link" | "default" | "outline" | "soft" | "ghost" | null | undefined;
5
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-sm" | "icon-lg" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export interface ButtonProps extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {
8
8
  asChild?: boolean;
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Slot } from "radix-ui";
3
+ import { Root as Slot } from "../primitives/vendor/radix/react-slot/slot.js";
3
4
  import * as React from "react";
4
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
6
  import { cva } from "class-variance-authority";
@@ -32,8 +33,7 @@ var buttonVariants = cva("inline-flex shrink-0 items-center justify-center gap-2
32
33
  }
33
34
  });
34
35
  var Button = React.forwardRef(function Button({ className, variant, size, asChild = false, loading = false, disabled, children, type, onClickCapture, onKeyDownCapture, ...props }, ref) {
35
- const Comp = asChild ? Slot.Root : "button";
36
- return /* @__PURE__ */ jsx(Comp, {
36
+ return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
37
37
  ref,
38
38
  type: asChild ? void 0 : type ?? "button",
39
39
  "data-slot": "button",
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","names":["_Fragment"],"sources":["../../src/components/button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-semibold tracking-[-0.01em] outline-none transition-[background-color,border-color,color,box-shadow,transform] duration-150 select-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/20 active:translate-y-px disabled:pointer-events-none disabled:opacity-45 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default:\n 'border border-primary bg-primary text-primary-foreground shadow-xs hover:brightness-90',\n brand:\n 'border border-primary bg-primary text-primary-foreground shadow-xs hover:brightness-90',\n soft: 'border border-brand/15 bg-brand-soft text-brand-soft-foreground hover:bg-brand/15',\n secondary:\n 'border border-border bg-secondary text-secondary-foreground shadow-xs hover:border-border-strong hover:bg-muted',\n outline:\n 'border border-border-strong bg-surface text-foreground shadow-xs hover:border-brand/35 hover:bg-accent/60 hover:text-accent-foreground',\n ghost: 'border border-transparent text-foreground hover:bg-muted',\n destructive:\n 'border border-destructive bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90',\n link: 'h-auto rounded-none border-0 p-0 text-brand shadow-none hover:text-brand-hover hover:underline hover:underline-offset-4 active:translate-y-0',\n },\n size: {\n xs: 'h-7 gap-1.5 rounded-sm px-2.5 text-xs [&_svg:not([class*=size-])]:size-3.5',\n sm: 'h-8 px-3 text-[13px]',\n default: 'h-9 px-3.5',\n lg: 'h-10 rounded-lg px-4 text-[15px]',\n icon: 'size-9 px-0',\n 'icon-sm': 'size-8 px-0',\n 'icon-lg': 'size-10 rounded-lg px-0',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n);\n\nexport interface ButtonProps\n extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n loading?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n disabled,\n children,\n type,\n onClickCapture,\n onKeyDownCapture,\n ...props\n }: ButtonProps,\n ref,\n) {\n const Comp = asChild ? Slot.Root : 'button';\n\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : (type ?? 'button')}\n data-slot=\"button\"\n data-loading={loading ? '' : undefined}\n aria-busy={loading || undefined}\n disabled={!asChild ? disabled || loading : undefined}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n aria-disabled={asChild && (disabled || loading) ? true : props['aria-disabled']}\n tabIndex={asChild && (disabled || loading) ? -1 : props.tabIndex}\n onClickCapture={(event) => {\n if (disabled || loading) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onClickCapture?.(event);\n }}\n onKeyDownCapture={(event) => {\n if ((disabled || loading) && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onKeyDownCapture?.(event);\n }}\n >\n {asChild ? (\n // Slot needs exactly one child to merge onto, so no spinner here.\n children\n ) : (\n <>\n {loading ? (\n <span\n aria-hidden=\"true\"\n className=\"size-3.5 animate-spin rounded-full border-2 border-current border-r-transparent opacity-70\"\n />\n ) : null}\n {children}\n </>\n )}\n </Comp>\n );\n});\n\nexport { Button, buttonVariants };\n"],"mappings":";;;;;;AAMA,IAAM,iBAAiB,IACrB,2gBACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,OACE;GACF,MAAM;GACN,WACE;GACF,SACE;GACF,OAAO;GACP,aACE;GACF,MAAM;EACR;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,SAAS;GACT,IAAI;GACJ,MAAM;GACN,WAAW;GACX,WAAW;EACb;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,MAAM;CAAU;AACzD,CACF;AAQA,IAAM,SAAS,MAAM,WAA2C,SAAS,OACvE,EACE,WACA,SACA,MACA,UAAU,OACV,UAAU,OACV,UACA,UACA,MACA,gBACA,kBACA,GAAG,SAEL,KACA;CACA,MAAM,OAAO,UAAU,KAAK,OAAO;CAEnC,OACE,oBAAC,MAAD;EACO;EACL,MAAM,UAAU,KAAA,IAAa,QAAQ;EACrC,aAAU;EACV,gBAAc,UAAU,KAAK,KAAA;EAC7B,aAAW,WAAW,KAAA;EACtB,UAAU,CAAC,UAAU,YAAY,UAAU,KAAA;EAC3C,WAAW,GAAG,eAAe;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAC1D,GAAI;EACJ,iBAAe,YAAY,YAAY,WAAW,OAAO,MAAM;EAC/D,UAAU,YAAY,YAAY,WAAW,KAAK,MAAM;EACxD,iBAAiB,UAAU;GACzB,IAAI,YAAY,SAAS;IACvB,MAAM,eAAe;IACrB,MAAM,gBAAgB;IACtB;GACF;GACA,iBAAiB,KAAK;EACxB;EACA,mBAAmB,UAAU;GAC3B,KAAK,YAAY,aAAa,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;IACzE,MAAM,eAAe;IACrB,MAAM,gBAAgB;IACtB;GACF;GACA,mBAAmB,KAAK;EAC1B;EAEC,UAAA,UAEC,WAEA,qBAAAA,UAAA,EAAA,UAAA,CACG,UACC,oBAAC,QAAD;GACE,eAAY;GACZ,WAAU;EACX,CAAA,IACC,MACH,QACD,EAAA,CAAA;CAEA,CAAA;AAEV,CAAC"}
1
+ {"version":3,"file":"button.js","names":["Slot.Root","_Fragment"],"sources":["../../src/components/button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as Slot from '../primitives/vendor/radix/react-slot';\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-semibold tracking-[-0.01em] outline-none transition-[background-color,border-color,color,box-shadow,transform] duration-150 select-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/20 active:translate-y-px disabled:pointer-events-none disabled:opacity-45 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default:\n 'border border-primary bg-primary text-primary-foreground shadow-xs hover:brightness-90',\n brand:\n 'border border-primary bg-primary text-primary-foreground shadow-xs hover:brightness-90',\n soft: 'border border-brand/15 bg-brand-soft text-brand-soft-foreground hover:bg-brand/15',\n secondary:\n 'border border-border bg-secondary text-secondary-foreground shadow-xs hover:border-border-strong hover:bg-muted',\n outline:\n 'border border-border-strong bg-surface text-foreground shadow-xs hover:border-brand/35 hover:bg-accent/60 hover:text-accent-foreground',\n ghost: 'border border-transparent text-foreground hover:bg-muted',\n destructive:\n 'border border-destructive bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90',\n link: 'h-auto rounded-none border-0 p-0 text-brand shadow-none hover:text-brand-hover hover:underline hover:underline-offset-4 active:translate-y-0',\n },\n size: {\n xs: 'h-7 gap-1.5 rounded-sm px-2.5 text-xs [&_svg:not([class*=size-])]:size-3.5',\n sm: 'h-8 px-3 text-[13px]',\n default: 'h-9 px-3.5',\n lg: 'h-10 rounded-lg px-4 text-[15px]',\n icon: 'size-9 px-0',\n 'icon-sm': 'size-8 px-0',\n 'icon-lg': 'size-10 rounded-lg px-0',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n);\n\nexport interface ButtonProps\n extends React.ComponentProps<'button'>, VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n loading?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n disabled,\n children,\n type,\n onClickCapture,\n onKeyDownCapture,\n ...props\n }: ButtonProps,\n ref,\n) {\n const Comp = asChild ? Slot.Root : 'button';\n\n return (\n <Comp\n ref={ref}\n type={asChild ? undefined : (type ?? 'button')}\n data-slot=\"button\"\n data-loading={loading ? '' : undefined}\n aria-busy={loading || undefined}\n disabled={!asChild ? disabled || loading : undefined}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n aria-disabled={asChild && (disabled || loading) ? true : props['aria-disabled']}\n tabIndex={asChild && (disabled || loading) ? -1 : props.tabIndex}\n onClickCapture={(event) => {\n if (disabled || loading) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onClickCapture?.(event);\n }}\n onKeyDownCapture={(event) => {\n if ((disabled || loading) && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onKeyDownCapture?.(event);\n }}\n >\n {asChild ? (\n // Slot needs exactly one child to merge onto, so no spinner here.\n children\n ) : (\n <>\n {loading ? (\n <span\n aria-hidden=\"true\"\n className=\"size-3.5 animate-spin rounded-full border-2 border-current border-r-transparent opacity-70\"\n />\n ) : null}\n {children}\n </>\n )}\n </Comp>\n );\n});\n\nexport { Button, buttonVariants };\n"],"mappings":";;;;;;;AAMA,IAAM,iBAAiB,IACrB,2gBACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,OACE;GACF,MAAM;GACN,WACE;GACF,SACE;GACF,OAAO;GACP,aACE;GACF,MAAM;EACR;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,SAAS;GACT,IAAI;GACJ,MAAM;GACN,WAAW;GACX,WAAW;EACb;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,MAAM;CAAU;AACzD,CACF;AAQA,IAAM,SAAS,MAAM,WAA2C,SAAS,OACvE,EACE,WACA,SACA,MACA,UAAU,OACV,UAAU,OACV,UACA,UACA,MACA,gBACA,kBACA,GAAG,SAEL,KACA;CAGA,OACE,oBAHW,UAAUA,OAAY,UAGjC;EACO;EACL,MAAM,UAAU,KAAA,IAAa,QAAQ;EACrC,aAAU;EACV,gBAAc,UAAU,KAAK,KAAA;EAC7B,aAAW,WAAW,KAAA;EACtB,UAAU,CAAC,UAAU,YAAY,UAAU,KAAA;EAC3C,WAAW,GAAG,eAAe;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAC1D,GAAI;EACJ,iBAAe,YAAY,YAAY,WAAW,OAAO,MAAM;EAC/D,UAAU,YAAY,YAAY,WAAW,KAAK,MAAM;EACxD,iBAAiB,UAAU;GACzB,IAAI,YAAY,SAAS;IACvB,MAAM,eAAe;IACrB,MAAM,gBAAgB;IACtB;GACF;GACA,iBAAiB,KAAK;EACxB;EACA,mBAAmB,UAAU;GAC3B,KAAK,YAAY,aAAa,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;IACzE,MAAM,eAAe;IACrB,MAAM,gBAAgB;IACtB;GACF;GACA,mBAAmB,KAAK;EAC1B;EAEC,UAAA,UAEC,WAEA,qBAAAC,UAAA,EAAA,UAAA,CACG,UACC,oBAAC,QAAD;GACE,eAAY;GACZ,WAAU;EACX,CAAA,IACC,MACH,QACD,EAAA,CAAA;CAEA,CAAA;AAEV,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { type VariantProps } from 'class-variance-authority';
2
2
  import * as React from 'react';
3
3
  declare const cardVariants: (props?: ({
4
- variant?: "default" | "raised" | "subtle" | "interactive" | "terminal" | null | undefined;
4
+ variant?: "terminal" | "default" | "raised" | "subtle" | "interactive" | null | undefined;
5
5
  density?: "default" | "compact" | "roomy" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export interface CardProps extends React.ComponentProps<'div'>, VariantProps<typeof cardVariants> {
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import "react";
3
4
  import { jsx } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","names":[],"sources":["../../src/components/card.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nconst cardVariants = cva(\n 'group/card relative flex flex-col overflow-hidden rounded-lg border text-card-foreground transition-[border-color,background-color,box-shadow,transform] duration-150',\n {\n variants: {\n variant: {\n default: 'border-border bg-card shadow-xs',\n raised: 'border-border bg-surface-raised shadow-md',\n subtle: 'border-border/70 bg-surface-muted shadow-none',\n interactive:\n 'border-border bg-card shadow-xs hover:-translate-y-0.5 hover:border-brand/30 hover:shadow-md',\n terminal: 'border-border-strong bg-code text-code-foreground shadow-md',\n },\n density: {\n compact:\n '[&_[data-slot=card-header]]:p-4 [&_[data-slot=card-content]]:px-4 [&_[data-slot=card-footer]]:p-4',\n default:\n '[&_[data-slot=card-header]]:p-5 [&_[data-slot=card-content]]:px-5 [&_[data-slot=card-footer]]:p-5',\n roomy:\n '[&_[data-slot=card-header]]:p-6 [&_[data-slot=card-content]]:px-6 [&_[data-slot=card-footer]]:p-6',\n },\n },\n defaultVariants: { variant: 'default', density: 'default' },\n },\n);\n\nexport interface CardProps extends React.ComponentProps<'div'>, VariantProps<typeof cardVariants> {}\n\nfunction Card({ className, variant, density, ...props }: CardProps) {\n return (\n <div\n data-slot=\"card\"\n className={cn(cardVariants({ variant, density }), className)}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n 'grid grid-cols-[1fr_auto] items-start gap-x-4 gap-y-1 border-b border-transparent pb-3',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardEyebrow({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-eyebrow\"\n className={cn(\n 'col-span-full mb-0.5 text-[11px] font-semibold tracking-[0.12em] text-muted-foreground uppercase',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn('min-w-0 text-sm font-semibold tracking-[-0.015em]', className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn('col-start-1 text-sm leading-5 text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn('col-start-2 row-span-2 row-start-1 self-start', className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-content\" className={cn('pb-5', className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn('mt-auto flex items-center gap-2 border-t pt-4', className)}\n {...props}\n />\n );\n}\n\nexport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardEyebrow,\n CardFooter,\n CardHeader,\n CardTitle,\n cardVariants,\n};\n"],"mappings":";;;;;AAKA,IAAM,eAAe,IACnB,yKACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,QAAQ;GACR,QAAQ;GACR,aACE;GACF,UAAU;EACZ;EACA,SAAS;GACP,SACE;GACF,SACE;GACF,OACE;EACJ;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,SAAS;CAAU;AAC5D,CACF;AAIA,SAAS,KAAK,EAAE,WAAW,SAAS,SAAS,GAAG,SAAoB;CAClE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,aAAa;GAAE;GAAS;EAAQ,CAAC,GAAG,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,0FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,oGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAsC;CACvE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,qDAAqD,SAAS;EAC5E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,uDAAuD,SAAS;EAC9E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iDAAiD,SAAS;EACxE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OAAO,oBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,QAAQ,SAAS;EAAG,GAAI;CAAQ,CAAA;AACrF;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iDAAiD,SAAS;EACxE,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"card.js","names":[],"sources":["../../src/components/card.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nconst cardVariants = cva(\n 'group/card relative flex flex-col overflow-hidden rounded-lg border text-card-foreground transition-[border-color,background-color,box-shadow,transform] duration-150',\n {\n variants: {\n variant: {\n default: 'border-border bg-card shadow-xs',\n raised: 'border-border bg-surface-raised shadow-md',\n subtle: 'border-border/70 bg-surface-muted shadow-none',\n interactive:\n 'border-border bg-card shadow-xs hover:-translate-y-0.5 hover:border-brand/30 hover:shadow-md',\n terminal: 'border-border-strong bg-code text-code-foreground shadow-md',\n },\n density: {\n compact:\n '[&_[data-slot=card-header]]:p-4 [&_[data-slot=card-content]]:px-4 [&_[data-slot=card-footer]]:p-4',\n default:\n '[&_[data-slot=card-header]]:p-5 [&_[data-slot=card-content]]:px-5 [&_[data-slot=card-footer]]:p-5',\n roomy:\n '[&_[data-slot=card-header]]:p-6 [&_[data-slot=card-content]]:px-6 [&_[data-slot=card-footer]]:p-6',\n },\n },\n defaultVariants: { variant: 'default', density: 'default' },\n },\n);\n\nexport interface CardProps extends React.ComponentProps<'div'>, VariantProps<typeof cardVariants> {}\n\nfunction Card({ className, variant, density, ...props }: CardProps) {\n return (\n <div\n data-slot=\"card\"\n className={cn(cardVariants({ variant, density }), className)}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n 'grid grid-cols-[1fr_auto] items-start gap-x-4 gap-y-1 border-b border-transparent pb-3',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardEyebrow({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-eyebrow\"\n className={cn(\n 'col-span-full mb-0.5 text-[11px] font-semibold tracking-[0.12em] text-muted-foreground uppercase',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn('min-w-0 text-sm font-semibold tracking-[-0.015em]', className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn('col-start-1 text-sm leading-5 text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn('col-start-2 row-span-2 row-start-1 self-start', className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-content\" className={cn('pb-5', className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn('mt-auto flex items-center gap-2 border-t pt-4', className)}\n {...props}\n />\n );\n}\n\nexport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardEyebrow,\n CardFooter,\n CardHeader,\n CardTitle,\n cardVariants,\n};\n"],"mappings":";;;;;;AAKA,IAAM,eAAe,IACnB,yKACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,QAAQ;GACR,QAAQ;GACR,aACE;GACF,UAAU;EACZ;EACA,SAAS;GACP,SACE;GACF,SACE;GACF,OACE;EACJ;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,SAAS;CAAU;AAC5D,CACF;AAIA,SAAS,KAAK,EAAE,WAAW,SAAS,SAAS,GAAG,SAAoB;CAClE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,aAAa;GAAE;GAAS;EAAQ,CAAC,GAAG,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,0FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,oGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAsC;CACvE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,qDAAqD,SAAS;EAC5E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,uDAAuD,SAAS;EAC9E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iDAAiD,SAAS;EACxE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OAAO,oBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,QAAQ,SAAS;EAAG,GAAI;CAAQ,CAAA;AACrF;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,iDAAiD,SAAS;EACxE,GAAI;CACL,CAAA;AAEL"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { Button } from "./button.js";
3
4
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "./dropdown-menu.js";
@@ -1 +1 @@
1
- {"version":3,"file":"chat-history.js","names":["_Fragment"],"sources":["../../src/components/chat-history.tsx"],"sourcesContent":["import AlertCircle from '@burtson-labs/icons/react/alert-circle';\nimport Edit from '@burtson-labs/icons/react/edit';\nimport MessageSquarePlus from '@burtson-labs/icons/react/message-square-plus';\nimport MoreHorizontal from '@burtson-labs/icons/react/more-horizontal';\nimport Pin from '@burtson-labs/icons/react/pin';\nimport PinOff from '@burtson-labs/icons/react/pin-off';\nimport Search from '@burtson-labs/icons/react/search';\nimport Trash from '@burtson-labs/icons/react/trash';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { fieldFocusClasses } from './input';\n\nexport interface ChatHistoryItem {\n id: string;\n title: string;\n /** When the conversation last changed; decides its group. */\n updatedAt: Date | string | number;\n pinned?: boolean;\n /** A line of the latest message, searched along with the title. */\n preview?: string;\n}\n\nexport type ChatHistoryGroupKey = 'pinned' | 'today' | 'yesterday' | 'week' | 'older';\n\nexport interface ChatHistoryGroup {\n key: ChatHistoryGroupKey;\n label: string;\n items: ChatHistoryItem[];\n}\n\nconst LABELS: Record<ChatHistoryGroupKey, string> = {\n pinned: 'Pinned',\n today: 'Today',\n yesterday: 'Yesterday',\n week: 'Previous 7 days',\n older: 'Older',\n};\n\nconst time = (d: ChatHistoryItem['updatedAt']) => new Date(d).getTime();\nconst startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();\n\n/**\n * Pinned first, then Today, Yesterday, Previous 7 days and Older by the\n * local calendar, newest first in each. Empty groups are left out.\n */\nexport function groupConversations(\n items: ChatHistoryItem[],\n now: Date = new Date(),\n): ChatHistoryGroup[] {\n const today = startOfDay(now);\n const day = 24 * 60 * 60 * 1000;\n const buckets: Record<ChatHistoryGroupKey, ChatHistoryItem[]> = {\n pinned: [],\n today: [],\n yesterday: [],\n week: [],\n older: [],\n };\n for (const item of [...items].sort((a, b) => time(b.updatedAt) - time(a.updatedAt))) {\n if (item.pinned) {\n buckets.pinned.push(item);\n continue;\n }\n const t = startOfDay(new Date(item.updatedAt));\n const key: ChatHistoryGroupKey =\n t >= today\n ? 'today'\n : t >= today - day\n ? 'yesterday'\n : t >= today - 7 * day\n ? 'week'\n : 'older';\n buckets[key].push(item);\n }\n return (Object.keys(buckets) as ChatHistoryGroupKey[])\n .filter((k) => buckets[k].length > 0)\n .map((k) => ({ key: k, label: LABELS[k], items: buckets[k] }));\n}\n\n/** Case-insensitive match on every word, across title and preview. */\nexport function matchesConversation(item: ChatHistoryItem, query: string): boolean {\n const hay = `${item.title} ${item.preview ?? ''}`.toLowerCase();\n return query\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean)\n .every((w) => hay.includes(w));\n}\n\nexport interface ChatHistoryProps extends Omit<React.ComponentProps<'div'>, 'onSelect'> {\n items: ChatHistoryItem[];\n activeId?: string;\n onSelect: (id: string) => void;\n /** Shows a \"New chat\" button at the top. */\n onNewChat?: () => void;\n /** Adds Rename to the row menu; the title is edited in place. */\n onRename?: (id: string, title: string) => void;\n /** Adds Delete to the row menu. Confirm or offer undo in your app. */\n onDelete?: (id: string) => void;\n /** Adds Pin / Unpin to the row menu. */\n onPinChange?: (id: string, pinned: boolean) => void;\n /** Controlled search text; leave out to let the list keep its own. */\n query?: string;\n onQueryChange?: (query: string) => void;\n /** Hides the search box, e.g. when the app searches on the server. */\n searchable?: boolean;\n loading?: boolean;\n /** Why the list could not load. Shown with Retry when `onRetry` is set. */\n error?: React.ReactNode;\n onRetry?: () => void;\n /** Shown when there are no conversations at all. */\n empty?: React.ReactNode;\n /** The clock grouping uses; pass it in tests. */\n now?: Date;\n /**\n * Virtualisation hook for long histories: receives a group's items and the\n * row renderer, returns what to render (e.g. a windowed list). Default\n * renders every row.\n */\n renderItems?: (\n items: ChatHistoryItem[],\n renderItem: (item: ChatHistoryItem) => React.ReactNode,\n ) => React.ReactNode;\n label?: string;\n}\n\n/**\n * The conversation list beside a chat: a New chat action, search, and the\n * history grouped by day with pinned chats on top. Up and Down move between\n * rows, Home and End jump, Enter opens; each row has a menu for rename, pin\n * and delete. The app owns the data; this only reports what the person did.\n */\nfunction ChatHistory({\n items,\n activeId,\n onSelect,\n onNewChat,\n onRename,\n onDelete,\n onPinChange,\n query: controlledQuery,\n onQueryChange,\n searchable = true,\n loading = false,\n error,\n onRetry,\n empty,\n now,\n renderItems,\n label = 'Chat history',\n className,\n ...props\n}: ChatHistoryProps) {\n const [ownQuery, setOwnQuery] = React.useState('');\n const query = controlledQuery ?? ownQuery;\n const setQuery = (q: string) => {\n if (controlledQuery === undefined) setOwnQuery(q);\n onQueryChange?.(q);\n };\n const [renaming, setRenaming] = React.useState<string | null>(null);\n const list = React.useRef<HTMLDivElement>(null);\n const searchId = React.useId();\n\n const visible = query.trim() ? items.filter((i) => matchesConversation(i, query)) : items;\n const groups = groupConversations(visible, now);\n\n const onRowKeyDown = (e: React.KeyboardEvent) => {\n const rows = Array.from(\n list.current?.querySelectorAll<HTMLElement>('[data-slot=\"chat-history-row\"]') ?? [],\n );\n const i = rows.indexOf(document.activeElement as HTMLElement);\n let next = -1;\n if (e.key === 'ArrowDown') next = Math.min(rows.length - 1, i + 1);\n else if (e.key === 'ArrowUp') next = Math.max(0, i - 1);\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = rows.length - 1;\n const row = next >= 0 ? rows[next] : undefined;\n if (row) {\n e.preventDefault();\n row.focus();\n }\n };\n\n const renderItem = (item: ChatHistoryItem) => (\n <HistoryRow\n key={item.id}\n item={item}\n active={item.id === activeId}\n renaming={renaming === item.id}\n onSelect={() => onSelect(item.id)}\n onStartRename={onRename ? () => setRenaming(item.id) : undefined}\n onRename={(title) => {\n setRenaming(null);\n if (onRename && title.trim() && title.trim() !== item.title)\n onRename(item.id, title.trim());\n }}\n onDelete={onDelete ? () => onDelete(item.id) : undefined}\n onPinChange={onPinChange ? (p) => onPinChange(item.id, p) : undefined}\n onKeyDown={onRowKeyDown}\n />\n );\n\n return (\n <div\n data-slot=\"chat-history\"\n aria-label={label}\n role=\"navigation\"\n className={cn('flex h-full min-h-0 flex-col', className)}\n {...props}\n >\n {(onNewChat || searchable) && (\n <div className=\"grid gap-2 p-2\">\n {onNewChat && (\n <Button variant=\"outline\" className=\"justify-start\" onClick={onNewChat}>\n <MessageSquarePlus /> New chat\n </Button>\n )}\n {searchable && (\n <label htmlFor={searchId} className=\"relative block\">\n <span className=\"sr-only\">Search chats</span>\n <Search\n aria-hidden\n className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <input\n id={searchId}\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search chats\"\n className={cn(\n 'h-8 w-full rounded-md border border-input bg-surface pr-2 pl-8 text-base placeholder:text-muted-foreground sm:text-sm',\n fieldFocusClasses,\n )}\n />\n </label>\n )}\n </div>\n )}\n <div ref={list} className=\"min-h-0 flex-1 overflow-y-auto px-2 pb-2\">\n {loading ? (\n <div role=\"status\" aria-label=\"Loading chats\" className=\"grid gap-1.5 pt-1\">\n {[72, 56, 64, 48, 60].map((w, i) => (\n <div key={i} className=\"h-8 rounded-md bg-muted/70 motion-safe:animate-pulse\">\n <span className=\"sr-only\">Loading</span>\n <span\n aria-hidden\n className=\"ml-2 inline-block h-2.5 translate-y-3 rounded bg-muted-foreground/15\"\n style={{ width: `${w}%` }}\n />\n </div>\n ))}\n </div>\n ) : error ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2 p-2 text-sm\">\n <span className=\"inline-flex items-center gap-1.5 font-medium text-destructive [&_svg]:size-4\">\n <AlertCircle aria-hidden /> Chats could not load\n </span>\n <span className=\"text-muted-foreground\">{error}</span>\n {onRetry && (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetry}>\n Try again\n </Button>\n )}\n </div>\n ) : items.length === 0 ? (\n <div className=\"p-3 text-sm text-muted-foreground\">\n {empty ?? 'No chats yet. Start one and it will appear here.'}\n </div>\n ) : groups.length === 0 ? (\n <p role=\"status\" className=\"p-3 text-sm text-muted-foreground\">\n No chats match &ldquo;{query}&rdquo;.\n </p>\n ) : (\n groups.map((g) => (\n <section key={g.key} aria-label={g.label} className=\"mt-2 first:mt-0\">\n <h3 className=\"px-2 pt-2 pb-1 text-[11px] font-semibold tracking-wide text-muted-foreground uppercase\">\n {g.label}\n </h3>\n <ul className=\"grid grid-cols-[minmax(0,1fr)] gap-0.5\">\n {renderItems ? renderItems(g.items, renderItem) : g.items.map(renderItem)}\n </ul>\n </section>\n ))\n )}\n </div>\n </div>\n );\n}\n\nfunction HistoryRow({\n item,\n active,\n renaming,\n onSelect,\n onStartRename,\n onRename,\n onDelete,\n onPinChange,\n onKeyDown,\n}: {\n item: ChatHistoryItem;\n active: boolean;\n renaming: boolean;\n onSelect: () => void;\n onStartRename?: () => void;\n onRename: (title: string) => void;\n onDelete?: () => void;\n onPinChange?: (pinned: boolean) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n}) {\n const hasMenu = Boolean(onStartRename || onDelete || onPinChange);\n if (renaming) return <RenameRow title={item.title} onDone={onRename} />;\n return (\n <li className=\"group/row relative min-w-0\">\n <button\n type=\"button\"\n data-slot=\"chat-history-row\"\n aria-current={active ? 'page' : undefined}\n onClick={onSelect}\n onKeyDown={onKeyDown}\n className={cn(\n 'flex h-8 w-full items-center gap-2 rounded-md px-2 text-left text-sm outline-none transition-colors hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20 pointer-coarse:h-11',\n hasMenu && 'pr-9',\n active && 'bg-accent font-medium text-accent-foreground hover:bg-accent',\n )}\n >\n <span className=\"min-w-0 flex-1 truncate\">{item.title || 'Untitled chat'}</span>\n </button>\n {hasMenu && (\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={`Actions for ${item.title || 'chat'}`}\n className={cn(\n 'absolute top-1/2 right-1 grid size-7 -translate-y-1/2 place-items-center rounded-sm text-muted-foreground opacity-0 outline-none transition-opacity hover:bg-background hover:text-foreground focus-visible:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/20 group-hover/row:opacity-100 data-[state=open]:opacity-100 pointer-coarse:size-9 pointer-coarse:opacity-100 [&_svg]:size-4',\n active && 'opacity-100',\n )}\n >\n <MoreHorizontal aria-hidden />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-40\">\n {onStartRename && (\n <DropdownMenuItem onSelect={onStartRename}>\n <Edit aria-hidden /> Rename\n </DropdownMenuItem>\n )}\n {onPinChange && (\n <DropdownMenuItem onSelect={() => onPinChange(!item.pinned)}>\n {item.pinned ? <PinOff aria-hidden /> : <Pin aria-hidden />}\n {item.pinned ? 'Unpin' : 'Pin'}\n </DropdownMenuItem>\n )}\n {onDelete && (\n <>\n {(onStartRename || onPinChange) && <DropdownMenuSeparator />}\n <DropdownMenuItem variant=\"destructive\" onSelect={onDelete}>\n <Trash aria-hidden /> Delete\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </li>\n );\n}\n\n/** Rename in place: Enter or leaving the field saves, Escape keeps the old title. */\nfunction RenameRow({ title, onDone }: { title: string; onDone: (title: string) => void }) {\n const [draft, setDraft] = React.useState(title);\n const input = React.useRef<HTMLInputElement>(null);\n React.useEffect(() => {\n input.current?.select();\n }, []);\n return (\n <li className=\"px-1 py-0.5\">\n <input\n ref={input}\n aria-label=\"Chat title\"\n value={draft}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- rename was just asked for\n autoFocus\n onChange={(e) => setDraft(e.target.value)}\n onBlur={() => onDone(draft)}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n onDone(draft);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n onDone(title);\n }\n }}\n className=\"h-8 w-full rounded-md border border-ring bg-surface px-2 text-base inset-ring-1 inset-ring-ring outline-hidden! sm:text-sm\"\n />\n </li>\n );\n}\n\nexport { ChatHistory };\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-history.js","names":["_Fragment"],"sources":["../../src/components/chat-history.tsx"],"sourcesContent":["import AlertCircle from '@burtson-labs/icons/react/alert-circle';\nimport Edit from '@burtson-labs/icons/react/edit';\nimport MessageSquarePlus from '@burtson-labs/icons/react/message-square-plus';\nimport MoreHorizontal from '@burtson-labs/icons/react/more-horizontal';\nimport Pin from '@burtson-labs/icons/react/pin';\nimport PinOff from '@burtson-labs/icons/react/pin-off';\nimport Search from '@burtson-labs/icons/react/search';\nimport Trash from '@burtson-labs/icons/react/trash';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { fieldFocusClasses } from './input';\n\nexport interface ChatHistoryItem {\n id: string;\n title: string;\n /** When the conversation last changed; decides its group. */\n updatedAt: Date | string | number;\n pinned?: boolean;\n /** A line of the latest message, searched along with the title. */\n preview?: string;\n}\n\nexport type ChatHistoryGroupKey = 'pinned' | 'today' | 'yesterday' | 'week' | 'older';\n\nexport interface ChatHistoryGroup {\n key: ChatHistoryGroupKey;\n label: string;\n items: ChatHistoryItem[];\n}\n\nconst LABELS: Record<ChatHistoryGroupKey, string> = {\n pinned: 'Pinned',\n today: 'Today',\n yesterday: 'Yesterday',\n week: 'Previous 7 days',\n older: 'Older',\n};\n\nconst time = (d: ChatHistoryItem['updatedAt']) => new Date(d).getTime();\nconst startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();\n\n/**\n * Pinned first, then Today, Yesterday, Previous 7 days and Older by the\n * local calendar, newest first in each. Empty groups are left out.\n */\nexport function groupConversations(\n items: ChatHistoryItem[],\n now: Date = new Date(),\n): ChatHistoryGroup[] {\n const today = startOfDay(now);\n const day = 24 * 60 * 60 * 1000;\n const buckets: Record<ChatHistoryGroupKey, ChatHistoryItem[]> = {\n pinned: [],\n today: [],\n yesterday: [],\n week: [],\n older: [],\n };\n for (const item of [...items].sort((a, b) => time(b.updatedAt) - time(a.updatedAt))) {\n if (item.pinned) {\n buckets.pinned.push(item);\n continue;\n }\n const t = startOfDay(new Date(item.updatedAt));\n const key: ChatHistoryGroupKey =\n t >= today\n ? 'today'\n : t >= today - day\n ? 'yesterday'\n : t >= today - 7 * day\n ? 'week'\n : 'older';\n buckets[key].push(item);\n }\n return (Object.keys(buckets) as ChatHistoryGroupKey[])\n .filter((k) => buckets[k].length > 0)\n .map((k) => ({ key: k, label: LABELS[k], items: buckets[k] }));\n}\n\n/** Case-insensitive match on every word, across title and preview. */\nexport function matchesConversation(item: ChatHistoryItem, query: string): boolean {\n const hay = `${item.title} ${item.preview ?? ''}`.toLowerCase();\n return query\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean)\n .every((w) => hay.includes(w));\n}\n\nexport interface ChatHistoryProps extends Omit<React.ComponentProps<'div'>, 'onSelect'> {\n items: ChatHistoryItem[];\n activeId?: string;\n onSelect: (id: string) => void;\n /** Shows a \"New chat\" button at the top. */\n onNewChat?: () => void;\n /** Adds Rename to the row menu; the title is edited in place. */\n onRename?: (id: string, title: string) => void;\n /** Adds Delete to the row menu. Confirm or offer undo in your app. */\n onDelete?: (id: string) => void;\n /** Adds Pin / Unpin to the row menu. */\n onPinChange?: (id: string, pinned: boolean) => void;\n /** Controlled search text; leave out to let the list keep its own. */\n query?: string;\n onQueryChange?: (query: string) => void;\n /** Hides the search box, e.g. when the app searches on the server. */\n searchable?: boolean;\n loading?: boolean;\n /** Why the list could not load. Shown with Retry when `onRetry` is set. */\n error?: React.ReactNode;\n onRetry?: () => void;\n /** Shown when there are no conversations at all. */\n empty?: React.ReactNode;\n /** The clock grouping uses; pass it in tests. */\n now?: Date;\n /**\n * Virtualisation hook for long histories: receives a group's items and the\n * row renderer, returns what to render (e.g. a windowed list). Default\n * renders every row.\n */\n renderItems?: (\n items: ChatHistoryItem[],\n renderItem: (item: ChatHistoryItem) => React.ReactNode,\n ) => React.ReactNode;\n label?: string;\n}\n\n/**\n * The conversation list beside a chat: a New chat action, search, and the\n * history grouped by day with pinned chats on top. Up and Down move between\n * rows, Home and End jump, Enter opens; each row has a menu for rename, pin\n * and delete. The app owns the data; this only reports what the person did.\n */\nfunction ChatHistory({\n items,\n activeId,\n onSelect,\n onNewChat,\n onRename,\n onDelete,\n onPinChange,\n query: controlledQuery,\n onQueryChange,\n searchable = true,\n loading = false,\n error,\n onRetry,\n empty,\n now,\n renderItems,\n label = 'Chat history',\n className,\n ...props\n}: ChatHistoryProps) {\n const [ownQuery, setOwnQuery] = React.useState('');\n const query = controlledQuery ?? ownQuery;\n const setQuery = (q: string) => {\n if (controlledQuery === undefined) setOwnQuery(q);\n onQueryChange?.(q);\n };\n const [renaming, setRenaming] = React.useState<string | null>(null);\n const list = React.useRef<HTMLDivElement>(null);\n const searchId = React.useId();\n\n const visible = query.trim() ? items.filter((i) => matchesConversation(i, query)) : items;\n const groups = groupConversations(visible, now);\n\n const onRowKeyDown = (e: React.KeyboardEvent) => {\n const rows = Array.from(\n list.current?.querySelectorAll<HTMLElement>('[data-slot=\"chat-history-row\"]') ?? [],\n );\n const i = rows.indexOf(document.activeElement as HTMLElement);\n let next = -1;\n if (e.key === 'ArrowDown') next = Math.min(rows.length - 1, i + 1);\n else if (e.key === 'ArrowUp') next = Math.max(0, i - 1);\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = rows.length - 1;\n const row = next >= 0 ? rows[next] : undefined;\n if (row) {\n e.preventDefault();\n row.focus();\n }\n };\n\n const renderItem = (item: ChatHistoryItem) => (\n <HistoryRow\n key={item.id}\n item={item}\n active={item.id === activeId}\n renaming={renaming === item.id}\n onSelect={() => onSelect(item.id)}\n onStartRename={onRename ? () => setRenaming(item.id) : undefined}\n onRename={(title) => {\n setRenaming(null);\n if (onRename && title.trim() && title.trim() !== item.title)\n onRename(item.id, title.trim());\n }}\n onDelete={onDelete ? () => onDelete(item.id) : undefined}\n onPinChange={onPinChange ? (p) => onPinChange(item.id, p) : undefined}\n onKeyDown={onRowKeyDown}\n />\n );\n\n return (\n <div\n data-slot=\"chat-history\"\n aria-label={label}\n role=\"navigation\"\n className={cn('flex h-full min-h-0 flex-col', className)}\n {...props}\n >\n {(onNewChat || searchable) && (\n <div className=\"grid gap-2 p-2\">\n {onNewChat && (\n <Button variant=\"outline\" className=\"justify-start\" onClick={onNewChat}>\n <MessageSquarePlus /> New chat\n </Button>\n )}\n {searchable && (\n <label htmlFor={searchId} className=\"relative block\">\n <span className=\"sr-only\">Search chats</span>\n <Search\n aria-hidden\n className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <input\n id={searchId}\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search chats\"\n className={cn(\n 'h-8 w-full rounded-md border border-input bg-surface pr-2 pl-8 text-base placeholder:text-muted-foreground sm:text-sm',\n fieldFocusClasses,\n )}\n />\n </label>\n )}\n </div>\n )}\n <div ref={list} className=\"min-h-0 flex-1 overflow-y-auto px-2 pb-2\">\n {loading ? (\n <div role=\"status\" aria-label=\"Loading chats\" className=\"grid gap-1.5 pt-1\">\n {[72, 56, 64, 48, 60].map((w, i) => (\n <div key={i} className=\"h-8 rounded-md bg-muted/70 motion-safe:animate-pulse\">\n <span className=\"sr-only\">Loading</span>\n <span\n aria-hidden\n className=\"ml-2 inline-block h-2.5 translate-y-3 rounded bg-muted-foreground/15\"\n style={{ width: `${w}%` }}\n />\n </div>\n ))}\n </div>\n ) : error ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2 p-2 text-sm\">\n <span className=\"inline-flex items-center gap-1.5 font-medium text-destructive [&_svg]:size-4\">\n <AlertCircle aria-hidden /> Chats could not load\n </span>\n <span className=\"text-muted-foreground\">{error}</span>\n {onRetry && (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetry}>\n Try again\n </Button>\n )}\n </div>\n ) : items.length === 0 ? (\n <div className=\"p-3 text-sm text-muted-foreground\">\n {empty ?? 'No chats yet. Start one and it will appear here.'}\n </div>\n ) : groups.length === 0 ? (\n <p role=\"status\" className=\"p-3 text-sm text-muted-foreground\">\n No chats match &ldquo;{query}&rdquo;.\n </p>\n ) : (\n groups.map((g) => (\n <section key={g.key} aria-label={g.label} className=\"mt-2 first:mt-0\">\n <h3 className=\"px-2 pt-2 pb-1 text-[11px] font-semibold tracking-wide text-muted-foreground uppercase\">\n {g.label}\n </h3>\n <ul className=\"grid grid-cols-[minmax(0,1fr)] gap-0.5\">\n {renderItems ? renderItems(g.items, renderItem) : g.items.map(renderItem)}\n </ul>\n </section>\n ))\n )}\n </div>\n </div>\n );\n}\n\nfunction HistoryRow({\n item,\n active,\n renaming,\n onSelect,\n onStartRename,\n onRename,\n onDelete,\n onPinChange,\n onKeyDown,\n}: {\n item: ChatHistoryItem;\n active: boolean;\n renaming: boolean;\n onSelect: () => void;\n onStartRename?: () => void;\n onRename: (title: string) => void;\n onDelete?: () => void;\n onPinChange?: (pinned: boolean) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n}) {\n const hasMenu = Boolean(onStartRename || onDelete || onPinChange);\n if (renaming) return <RenameRow title={item.title} onDone={onRename} />;\n return (\n <li className=\"group/row relative min-w-0\">\n <button\n type=\"button\"\n data-slot=\"chat-history-row\"\n aria-current={active ? 'page' : undefined}\n onClick={onSelect}\n onKeyDown={onKeyDown}\n className={cn(\n 'flex h-8 w-full items-center gap-2 rounded-md px-2 text-left text-sm outline-none transition-colors hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20 pointer-coarse:h-11',\n hasMenu && 'pr-9',\n active && 'bg-accent font-medium text-accent-foreground hover:bg-accent',\n )}\n >\n <span className=\"min-w-0 flex-1 truncate\">{item.title || 'Untitled chat'}</span>\n </button>\n {hasMenu && (\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={`Actions for ${item.title || 'chat'}`}\n className={cn(\n 'absolute top-1/2 right-1 grid size-7 -translate-y-1/2 place-items-center rounded-sm text-muted-foreground opacity-0 outline-none transition-opacity hover:bg-background hover:text-foreground focus-visible:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/20 group-hover/row:opacity-100 data-[state=open]:opacity-100 pointer-coarse:size-9 pointer-coarse:opacity-100 [&_svg]:size-4',\n active && 'opacity-100',\n )}\n >\n <MoreHorizontal aria-hidden />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-40\">\n {onStartRename && (\n <DropdownMenuItem onSelect={onStartRename}>\n <Edit aria-hidden /> Rename\n </DropdownMenuItem>\n )}\n {onPinChange && (\n <DropdownMenuItem onSelect={() => onPinChange(!item.pinned)}>\n {item.pinned ? <PinOff aria-hidden /> : <Pin aria-hidden />}\n {item.pinned ? 'Unpin' : 'Pin'}\n </DropdownMenuItem>\n )}\n {onDelete && (\n <>\n {(onStartRename || onPinChange) && <DropdownMenuSeparator />}\n <DropdownMenuItem variant=\"destructive\" onSelect={onDelete}>\n <Trash aria-hidden /> Delete\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </li>\n );\n}\n\n/** Rename in place: Enter or leaving the field saves, Escape keeps the old title. */\nfunction RenameRow({ title, onDone }: { title: string; onDone: (title: string) => void }) {\n const [draft, setDraft] = React.useState(title);\n const input = React.useRef<HTMLInputElement>(null);\n React.useEffect(() => {\n input.current?.select();\n }, []);\n return (\n <li className=\"px-1 py-0.5\">\n <input\n ref={input}\n aria-label=\"Chat title\"\n value={draft}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- rename was just asked for\n autoFocus\n onChange={(e) => setDraft(e.target.value)}\n onBlur={() => onDone(draft)}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n onDone(draft);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n onDone(title);\n }\n }}\n className=\"h-8 w-full rounded-md border border-ring bg-surface px-2 text-base inset-ring-1 inset-ring-ring outline-hidden! sm:text-sm\"\n />\n </li>\n );\n}\n\nexport { ChatHistory };\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { IconButton } from "./icon-button.js";
3
4
  import { ResizablePanel, ResizablePanelGroup, ResizeHandle } from "./resizable.js";
@@ -1 +1 @@
1
- {"version":3,"file":"chat-layout.js","names":["_Fragment"],"sources":["../../src/components/chat-layout.tsx"],"sourcesContent":["import Maximize from '@burtson-labs/icons/react/maximize';\nimport Minimize from '@burtson-labs/icons/react/minimize';\nimport PanelLeft from '@burtson-labs/icons/react/panel-left';\nimport PanelLeftClose from '@burtson-labs/icons/react/panel-left-close';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { IconButton } from './icon-button';\nimport { ResizablePanel, ResizablePanelGroup, ResizeHandle } from './resizable';\nimport { Sheet, SheetContent, SheetDescription, SheetTitle } from './sheet';\n\n/**\n * Full screen for one element: the Fullscreen API where the browser allows\n * it, otherwise the element is pinned over the page with CSS. Escape leaves\n * either way. Nothing remounts, so focus and scroll stay where they were.\n */\nexport function useFullscreen(\n ref: React.RefObject<HTMLElement | null>,\n onChange?: (fullscreen: boolean) => void,\n) {\n const [native, setNative] = React.useState(false);\n const [fallback, setFallback] = React.useState(false);\n const active = native || fallback;\n const changed = React.useRef(onChange);\n React.useEffect(() => {\n changed.current = onChange;\n }, [onChange]);\n\n React.useEffect(() => {\n const sync = () =>\n setNative(Boolean(ref.current && document.fullscreenElement === ref.current));\n document.addEventListener('fullscreenchange', sync);\n return () => document.removeEventListener('fullscreenchange', sync);\n }, [ref]);\n\n React.useEffect(() => {\n if (!fallback) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && !e.defaultPrevented) setFallback(false);\n };\n const root = document.documentElement;\n const previous = root.style.overflow;\n root.style.overflow = 'hidden';\n document.addEventListener('keydown', onKey);\n return () => {\n root.style.overflow = previous;\n document.removeEventListener('keydown', onKey);\n };\n }, [fallback]);\n\n const first = React.useRef(true);\n React.useEffect(() => {\n if (first.current) {\n first.current = false;\n return;\n }\n changed.current?.(active);\n }, [active]);\n\n const enter = React.useCallback(async () => {\n const el = ref.current;\n if (!el) return;\n const canNative = document.fullscreenEnabled && typeof el.requestFullscreen === 'function';\n // Denied (iframe without allowfullscreen, iOS) resolves false: use the CSS fallback.\n const ok = canNative\n ? await el.requestFullscreen().then(\n () => true,\n () => false,\n )\n : false;\n if (!ok) setFallback(true);\n }, [ref]);\n\n const exit = React.useCallback(async () => {\n setFallback(false);\n if (document.fullscreenElement && typeof document.exitFullscreen === 'function') {\n await document.exitFullscreen().catch(() => undefined);\n }\n }, []);\n\n const toggle = React.useCallback(() => (active ? exit() : enter()), [active, enter, exit]);\n return { fullscreen: active, native, enter, exit, toggle };\n}\n\nfunction useDesktop(query = '(min-width: 768px)') {\n const get = () => (typeof matchMedia === 'function' ? matchMedia(query).matches : true);\n const [desktop, setDesktop] = React.useState(get);\n React.useEffect(() => {\n if (typeof matchMedia !== 'function') return;\n const mq = matchMedia(query);\n const on = () => setDesktop(mq.matches);\n mq.addEventListener?.('change', on);\n return () => mq.removeEventListener?.('change', on);\n }, [query]);\n return desktop;\n}\n\nexport interface ChatLayoutProps extends Omit<React.ComponentProps<'div'>, 'title'> {\n /** The history column, usually a ChatHistory. A sheet from the left on phones. */\n sidebar?: React.ReactNode;\n sidebarLabel?: string;\n /** An optional right column: sources, files, run details. Hidden on phones. */\n details?: React.ReactNode;\n detailsLabel?: string;\n /** Shown in the header: the conversation title. */\n title?: React.ReactNode;\n /** Header controls right of the title (model picker, share). */\n actions?: React.ReactNode;\n /** Controlled sidebar state; leave out to let the layout keep its own. */\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n onSidebarOpenChange?: (open: boolean) => void;\n /** Show the Full screen button. Default true. */\n allowFullscreen?: boolean;\n onFullscreenChange?: (fullscreen: boolean) => void;\n /** Sidebar width, e.g. \"22%\" or 280 (px), as ResizablePanel sizes. */\n sidebarSize?: number | string;\n}\n\n/**\n * The frame for a chat app: header, a resizable history sidebar (a sheet on\n * phones that closes when a chat is picked), the conversation, an optional\n * details column, and a Full screen mode. Put a Conversation and a Composer\n * in `children`; the layout stacks them and keeps the composer at the bottom.\n */\nfunction ChatLayout({\n sidebar,\n sidebarLabel = 'Chats',\n details,\n detailsLabel = 'Details',\n title,\n actions,\n sidebarOpen: controlledOpen,\n defaultSidebarOpen = true,\n onSidebarOpenChange,\n allowFullscreen = true,\n onFullscreenChange,\n sidebarSize = '24%',\n children,\n className,\n ...props\n}: ChatLayoutProps) {\n const root = React.useRef<HTMLDivElement>(null);\n const desktop = useDesktop();\n const [ownOpen, setOwnOpen] = React.useState(defaultSidebarOpen);\n const [sheetOpen, setSheetOpen] = React.useState(false);\n const open = controlledOpen ?? ownOpen;\n const setOpen = (v: boolean) => {\n if (controlledOpen === undefined) setOwnOpen(v);\n onSidebarOpenChange?.(v);\n };\n const { fullscreen, toggle } = useFullscreen(root, onFullscreenChange);\n\n const sidebarToggle = sidebar ? (\n desktop ? (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label={open ? `Hide ${sidebarLabel.toLowerCase()}` : `Show ${sidebarLabel.toLowerCase()}`}\n aria-expanded={open}\n onClick={() => setOpen(!open)}\n >\n {open ? <PanelLeftClose /> : <PanelLeft />}\n </IconButton>\n ) : (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"pointer-coarse:size-11\"\n label={`Open ${sidebarLabel.toLowerCase()}`}\n aria-expanded={sheetOpen}\n onClick={() => setSheetOpen(true)}\n >\n <PanelLeft />\n </IconButton>\n )\n ) : null;\n\n const main = (\n <div data-slot=\"chat-layout-main\" className=\"flex h-full min-h-0 min-w-0 flex-col\">\n {children}\n </div>\n );\n\n return (\n <div\n ref={root}\n data-slot=\"chat-layout\"\n data-fullscreen={fullscreen || undefined}\n className={cn(\n 'flex h-full min-h-0 flex-col overflow-hidden bg-background text-foreground',\n 'data-[fullscreen]:fixed data-[fullscreen]:inset-0 data-[fullscreen]:z-50 data-[fullscreen]:h-dvh data-[fullscreen]:w-screen',\n className,\n )}\n {...props}\n >\n <header className=\"flex h-12 shrink-0 items-center gap-1 border-b px-2\">\n {sidebarToggle}\n <div className=\"min-w-0 flex-1 truncate px-1 text-sm font-medium\">{title}</div>\n {actions}\n {allowFullscreen && (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"pointer-coarse:size-11\"\n label={fullscreen ? 'Exit full screen' : 'Full screen'}\n aria-pressed={fullscreen}\n onClick={() => void toggle()}\n >\n {fullscreen ? <Minimize /> : <Maximize />}\n </IconButton>\n )}\n </header>\n <div className=\"min-h-0 flex-1\">\n {desktop && (sidebar || details) ? (\n <ResizablePanelGroup orientation=\"horizontal\">\n {sidebar && open && (\n <>\n <ResizablePanel\n id=\"chat-sidebar\"\n defaultSize={sidebarSize}\n minSize={180}\n maxSize=\"45%\"\n className=\"bg-surface-muted/50\"\n >\n <aside aria-label={sidebarLabel} className=\"h-full\">\n {sidebar}\n </aside>\n </ResizablePanel>\n <ResizeHandle aria-label={`Resize ${sidebarLabel.toLowerCase()}`} />\n </>\n )}\n <ResizablePanel id=\"chat-main\" minSize=\"30%\">\n {main}\n </ResizablePanel>\n {details && (\n <>\n <ResizeHandle aria-label={`Resize ${detailsLabel.toLowerCase()}`} />\n <ResizablePanel id=\"chat-details\" defaultSize=\"26%\" minSize={200} maxSize=\"45%\">\n <aside aria-label={detailsLabel} className=\"h-full overflow-y-auto\">\n {details}\n </aside>\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n ) : (\n main\n )}\n </div>\n {sidebar && !desktop && (\n <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <SheetContent side=\"left\" className=\"w-[min(20rem,88vw)] gap-0 p-0\">\n <SheetTitle className=\"border-b px-4 py-3.5 text-sm\">{sidebarLabel}</SheetTitle>\n <SheetDescription className=\"sr-only\">Pick a conversation.</SheetDescription>\n <div\n className=\"min-h-0 flex-1\"\n // Picking a chat (or New chat) closes the sheet, as on a phone it should.\n onClickCapture={(e) => {\n const t = e.target as HTMLElement;\n if (t.closest('[data-slot=\"chat-history-row\"], [data-close-sheet]'))\n setSheetOpen(false);\n }}\n >\n {sidebar}\n </div>\n </SheetContent>\n </Sheet>\n )}\n </div>\n );\n}\n\nexport { ChatLayout };\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-layout.js","names":["_Fragment"],"sources":["../../src/components/chat-layout.tsx"],"sourcesContent":["import Maximize from '@burtson-labs/icons/react/maximize';\nimport Minimize from '@burtson-labs/icons/react/minimize';\nimport PanelLeft from '@burtson-labs/icons/react/panel-left';\nimport PanelLeftClose from '@burtson-labs/icons/react/panel-left-close';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { IconButton } from './icon-button';\nimport { ResizablePanel, ResizablePanelGroup, ResizeHandle } from './resizable';\nimport { Sheet, SheetContent, SheetDescription, SheetTitle } from './sheet';\n\n/**\n * Full screen for one element: the Fullscreen API where the browser allows\n * it, otherwise the element is pinned over the page with CSS. Escape leaves\n * either way. Nothing remounts, so focus and scroll stay where they were.\n */\nexport function useFullscreen(\n ref: React.RefObject<HTMLElement | null>,\n onChange?: (fullscreen: boolean) => void,\n) {\n const [native, setNative] = React.useState(false);\n const [fallback, setFallback] = React.useState(false);\n const active = native || fallback;\n const changed = React.useRef(onChange);\n React.useEffect(() => {\n changed.current = onChange;\n }, [onChange]);\n\n React.useEffect(() => {\n const sync = () =>\n setNative(Boolean(ref.current && document.fullscreenElement === ref.current));\n document.addEventListener('fullscreenchange', sync);\n return () => document.removeEventListener('fullscreenchange', sync);\n }, [ref]);\n\n React.useEffect(() => {\n if (!fallback) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && !e.defaultPrevented) setFallback(false);\n };\n const root = document.documentElement;\n const previous = root.style.overflow;\n root.style.overflow = 'hidden';\n document.addEventListener('keydown', onKey);\n return () => {\n root.style.overflow = previous;\n document.removeEventListener('keydown', onKey);\n };\n }, [fallback]);\n\n const first = React.useRef(true);\n React.useEffect(() => {\n if (first.current) {\n first.current = false;\n return;\n }\n changed.current?.(active);\n }, [active]);\n\n const enter = React.useCallback(async () => {\n const el = ref.current;\n if (!el) return;\n const canNative = document.fullscreenEnabled && typeof el.requestFullscreen === 'function';\n // Denied (iframe without allowfullscreen, iOS) resolves false: use the CSS fallback.\n const ok = canNative\n ? await el.requestFullscreen().then(\n () => true,\n () => false,\n )\n : false;\n if (!ok) setFallback(true);\n }, [ref]);\n\n const exit = React.useCallback(async () => {\n setFallback(false);\n if (document.fullscreenElement && typeof document.exitFullscreen === 'function') {\n await document.exitFullscreen().catch(() => undefined);\n }\n }, []);\n\n const toggle = React.useCallback(() => (active ? exit() : enter()), [active, enter, exit]);\n return { fullscreen: active, native, enter, exit, toggle };\n}\n\nfunction useDesktop(query = '(min-width: 768px)') {\n const get = () => (typeof matchMedia === 'function' ? matchMedia(query).matches : true);\n const [desktop, setDesktop] = React.useState(get);\n React.useEffect(() => {\n if (typeof matchMedia !== 'function') return;\n const mq = matchMedia(query);\n const on = () => setDesktop(mq.matches);\n mq.addEventListener?.('change', on);\n return () => mq.removeEventListener?.('change', on);\n }, [query]);\n return desktop;\n}\n\nexport interface ChatLayoutProps extends Omit<React.ComponentProps<'div'>, 'title'> {\n /** The history column, usually a ChatHistory. A sheet from the left on phones. */\n sidebar?: React.ReactNode;\n sidebarLabel?: string;\n /** An optional right column: sources, files, run details. Hidden on phones. */\n details?: React.ReactNode;\n detailsLabel?: string;\n /** Shown in the header: the conversation title. */\n title?: React.ReactNode;\n /** Header controls right of the title (model picker, share). */\n actions?: React.ReactNode;\n /** Controlled sidebar state; leave out to let the layout keep its own. */\n sidebarOpen?: boolean;\n defaultSidebarOpen?: boolean;\n onSidebarOpenChange?: (open: boolean) => void;\n /** Show the Full screen button. Default true. */\n allowFullscreen?: boolean;\n onFullscreenChange?: (fullscreen: boolean) => void;\n /** Sidebar width, e.g. \"22%\" or 280 (px), as ResizablePanel sizes. */\n sidebarSize?: number | string;\n}\n\n/**\n * The frame for a chat app: header, a resizable history sidebar (a sheet on\n * phones that closes when a chat is picked), the conversation, an optional\n * details column, and a Full screen mode. Put a Conversation and a Composer\n * in `children`; the layout stacks them and keeps the composer at the bottom.\n */\nfunction ChatLayout({\n sidebar,\n sidebarLabel = 'Chats',\n details,\n detailsLabel = 'Details',\n title,\n actions,\n sidebarOpen: controlledOpen,\n defaultSidebarOpen = true,\n onSidebarOpenChange,\n allowFullscreen = true,\n onFullscreenChange,\n sidebarSize = '24%',\n children,\n className,\n ...props\n}: ChatLayoutProps) {\n const root = React.useRef<HTMLDivElement>(null);\n const desktop = useDesktop();\n const [ownOpen, setOwnOpen] = React.useState(defaultSidebarOpen);\n const [sheetOpen, setSheetOpen] = React.useState(false);\n const open = controlledOpen ?? ownOpen;\n const setOpen = (v: boolean) => {\n if (controlledOpen === undefined) setOwnOpen(v);\n onSidebarOpenChange?.(v);\n };\n const { fullscreen, toggle } = useFullscreen(root, onFullscreenChange);\n\n const sidebarToggle = sidebar ? (\n desktop ? (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label={open ? `Hide ${sidebarLabel.toLowerCase()}` : `Show ${sidebarLabel.toLowerCase()}`}\n aria-expanded={open}\n onClick={() => setOpen(!open)}\n >\n {open ? <PanelLeftClose /> : <PanelLeft />}\n </IconButton>\n ) : (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"pointer-coarse:size-11\"\n label={`Open ${sidebarLabel.toLowerCase()}`}\n aria-expanded={sheetOpen}\n onClick={() => setSheetOpen(true)}\n >\n <PanelLeft />\n </IconButton>\n )\n ) : null;\n\n const main = (\n <div data-slot=\"chat-layout-main\" className=\"flex h-full min-h-0 min-w-0 flex-col\">\n {children}\n </div>\n );\n\n return (\n <div\n ref={root}\n data-slot=\"chat-layout\"\n data-fullscreen={fullscreen || undefined}\n className={cn(\n 'flex h-full min-h-0 flex-col overflow-hidden bg-background text-foreground',\n 'data-[fullscreen]:fixed data-[fullscreen]:inset-0 data-[fullscreen]:z-50 data-[fullscreen]:h-dvh data-[fullscreen]:w-screen',\n className,\n )}\n {...props}\n >\n <header className=\"flex h-12 shrink-0 items-center gap-1 border-b px-2\">\n {sidebarToggle}\n <div className=\"min-w-0 flex-1 truncate px-1 text-sm font-medium\">{title}</div>\n {actions}\n {allowFullscreen && (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"pointer-coarse:size-11\"\n label={fullscreen ? 'Exit full screen' : 'Full screen'}\n aria-pressed={fullscreen}\n onClick={() => void toggle()}\n >\n {fullscreen ? <Minimize /> : <Maximize />}\n </IconButton>\n )}\n </header>\n <div className=\"min-h-0 flex-1\">\n {desktop && (sidebar || details) ? (\n <ResizablePanelGroup orientation=\"horizontal\">\n {sidebar && open && (\n <>\n <ResizablePanel\n id=\"chat-sidebar\"\n defaultSize={sidebarSize}\n minSize={180}\n maxSize=\"45%\"\n className=\"bg-surface-muted/50\"\n >\n <aside aria-label={sidebarLabel} className=\"h-full\">\n {sidebar}\n </aside>\n </ResizablePanel>\n <ResizeHandle aria-label={`Resize ${sidebarLabel.toLowerCase()}`} />\n </>\n )}\n <ResizablePanel id=\"chat-main\" minSize=\"30%\">\n {main}\n </ResizablePanel>\n {details && (\n <>\n <ResizeHandle aria-label={`Resize ${detailsLabel.toLowerCase()}`} />\n <ResizablePanel id=\"chat-details\" defaultSize=\"26%\" minSize={200} maxSize=\"45%\">\n <aside aria-label={detailsLabel} className=\"h-full overflow-y-auto\">\n {details}\n </aside>\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n ) : (\n main\n )}\n </div>\n {sidebar && !desktop && (\n <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <SheetContent side=\"left\" className=\"w-[min(20rem,88vw)] gap-0 p-0\">\n <SheetTitle className=\"border-b px-4 py-3.5 text-sm\">{sidebarLabel}</SheetTitle>\n <SheetDescription className=\"sr-only\">Pick a conversation.</SheetDescription>\n <div\n className=\"min-h-0 flex-1\"\n // Picking a chat (or New chat) closes the sheet, as on a phone it should.\n onClickCapture={(e) => {\n const t = e.target as HTMLElement;\n if (t.closest('[data-slot=\"chat-history-row\"], [data-close-sheet]'))\n setSheetOpen(false);\n }}\n >\n {sidebar}\n </div>\n </SheetContent>\n </Sheet>\n )}\n </div>\n );\n}\n\nexport { ChatLayout };\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Checkbox as CheckboxPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as CheckboxPrimitive from '../primitives/vendor/radix/react-checkbox';
3
3
  export interface CheckboxCardProps extends Omit<React.ComponentProps<typeof CheckboxPrimitive.Root>, 'title' | 'children'> {
4
4
  /** The option's name. */
5
5
  title: React.ReactNode;
@@ -1,6 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Checkbox as Checkbox$1 } from "./checkbox.js";
3
- import "radix-ui";
3
+ import { Checkbox } from "./checkbox.js";
4
4
  import * as React from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/checkbox-card.tsx
@@ -16,7 +16,7 @@ function CheckboxCard({ title, description, id: idProp, disabled, className, car
16
16
  htmlFor: id,
17
17
  "data-slot": "checkbox-card",
18
18
  className: cn("flex min-h-11 cursor-pointer items-start gap-3 rounded-md border border-border bg-surface px-3 py-2.5 transition-colors hover:border-border-strong", "has-[[data-state=checked]]:border-brand/40 has-[[data-state=checked]]:bg-brand-soft/50", "has-[:focus-visible]:border-ring has-[:focus-visible]:inset-ring-1 has-[:focus-visible]:inset-ring-ring", "has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60 has-[:disabled]:hover:border-border", cardClassName),
19
- children: [/* @__PURE__ */ jsx(Checkbox$1, {
19
+ children: [/* @__PURE__ */ jsx(Checkbox, {
20
20
  id,
21
21
  disabled,
22
22
  "aria-labelledby": `${id}-title`,
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-card.js","names":["Checkbox"],"sources":["../../src/components/checkbox-card.tsx"],"sourcesContent":["import { Checkbox as CheckboxPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Checkbox } from './checkbox';\n\nexport interface CheckboxCardProps extends Omit<\n React.ComponentProps<typeof CheckboxPrimitive.Root>,\n 'title' | 'children'\n> {\n /** The option's name. */\n title: React.ReactNode;\n /** A sentence under the name: what choosing it means. */\n description?: React.ReactNode;\n /** Extra classes for the card (the label); className goes to the checkbox. */\n cardClassName?: string;\n}\n\n/**\n * A checkbox with a title and a sentence, where the whole card is the hit\n * area (44px or taller). For choices that need explaining: roles,\n * permissions, notification types. One focus ring, on the card.\n */\nfunction CheckboxCard({\n title,\n description,\n id: idProp,\n disabled,\n className,\n cardClassName,\n ...props\n}: CheckboxCardProps) {\n const auto = React.useId();\n const id = idProp ?? auto;\n return (\n <label\n htmlFor={id}\n data-slot=\"checkbox-card\"\n className={cn(\n 'flex min-h-11 cursor-pointer items-start gap-3 rounded-md border border-border bg-surface px-3 py-2.5 transition-colors hover:border-border-strong',\n 'has-[[data-state=checked]]:border-brand/40 has-[[data-state=checked]]:bg-brand-soft/50',\n 'has-[:focus-visible]:border-ring has-[:focus-visible]:inset-ring-1 has-[:focus-visible]:inset-ring-ring',\n // :disabled also catches a disabled fieldset around the card.\n 'has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60 has-[:disabled]:hover:border-border',\n cardClassName,\n )}\n >\n <Checkbox\n id={id}\n disabled={disabled}\n aria-labelledby={`${id}-title`}\n aria-describedby={description ? `${id}-description` : undefined}\n className={cn(\n 'mt-0.5 outline-hidden! focus-visible:ring-0 focus-visible:outline-none',\n className,\n )}\n {...props}\n />\n <span className=\"grid min-w-0 gap-0.5\">\n <span id={`${id}-title`} className=\"text-sm leading-5 font-medium\">\n {title}\n </span>\n {description && (\n <span id={`${id}-description`} className=\"text-[13px] leading-5 text-muted-foreground\">\n {description}\n </span>\n )}\n </span>\n </label>\n );\n}\n\nexport interface CheckboxCardGroupProps extends React.ComponentProps<'fieldset'> {\n /** The group's name, shown as its legend. */\n label: React.ReactNode;\n /** Help under the legend. */\n description?: React.ReactNode;\n}\n\n/** A fieldset of CheckboxCards with a visible legend. `disabled` disables every card. */\nfunction CheckboxCardGroup({\n label,\n description,\n className,\n children,\n ...props\n}: CheckboxCardGroupProps) {\n const id = React.useId();\n return (\n <fieldset\n data-slot=\"checkbox-card-group\"\n aria-describedby={description ? `${id}-description` : undefined}\n className={cn('grid min-w-0 gap-2', className)}\n {...props}\n >\n <legend className=\"mb-1.5 text-sm font-medium\">{label}</legend>\n {description && (\n <p id={`${id}-description`} className=\"-mt-1.5 text-[13px] text-muted-foreground\">\n {description}\n </p>\n )}\n {children}\n </fieldset>\n );\n}\n\nexport { CheckboxCard, CheckboxCardGroup };\n"],"mappings":";;;;;;;;;;;AAwBA,SAAS,aAAa,EACpB,OACA,aACA,IAAI,QACJ,UACA,WACA,eACA,GAAG,SACiB;CACpB,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,KAAK,UAAU;CACrB,OACE,qBAAC,SAAD;EACE,SAAS;EACT,aAAU;EACV,WAAW,GACT,sJACA,0FACA,2GAEA,qGACA,aACF;EAVF,UAAA,CAYE,oBAACA,YAAD;GACM;GACM;GACV,mBAAiB,GAAG,GAAG;GACvB,oBAAkB,cAAc,GAAG,GAAG,gBAAgB,KAAA;GACtD,WAAW,GACT,0EACA,SACF;GACA,GAAI;EACL,CAAA,GACD,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,QAAD;IAAM,IAAI,GAAG,GAAG;IAAS,WAAU;IAChC,UAAA;GACG,CAAA,GACL,eACC,oBAAC,QAAD;IAAM,IAAI,GAAG,GAAG;IAAe,WAAU;IACtC,UAAA;GACG,CAAA,CAEJ;EACD,CAAA,CAAA;;AAEX;;AAUA,SAAS,kBAAkB,EACzB,OACA,aACA,WACA,UACA,GAAG,SACsB;CACzB,MAAM,KAAK,MAAM,MAAM;CACvB,OACE,qBAAC,YAAD;EACE,aAAU;EACV,oBAAkB,cAAc,GAAG,GAAG,gBAAgB,KAAA;EACtD,WAAW,GAAG,sBAAsB,SAAS;EAC7C,GAAI;EAJN,UAAA;GAME,oBAAC,UAAD;IAAQ,WAAU;IAA8B,UAAA;GAAc,CAAA;GAC7D,eACC,oBAAC,KAAD;IAAG,IAAI,GAAG,GAAG;IAAe,WAAU;IACnC,UAAA;GACA,CAAA;GAEJ;EACO;;AAEd"}
1
+ {"version":3,"file":"checkbox-card.js","names":[],"sources":["../../src/components/checkbox-card.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as CheckboxPrimitive from '../primitives/vendor/radix/react-checkbox';\n\nimport { Checkbox } from './checkbox';\n\nexport interface CheckboxCardProps extends Omit<\n React.ComponentProps<typeof CheckboxPrimitive.Root>,\n 'title' | 'children'\n> {\n /** The option's name. */\n title: React.ReactNode;\n /** A sentence under the name: what choosing it means. */\n description?: React.ReactNode;\n /** Extra classes for the card (the label); className goes to the checkbox. */\n cardClassName?: string;\n}\n\n/**\n * A checkbox with a title and a sentence, where the whole card is the hit\n * area (44px or taller). For choices that need explaining: roles,\n * permissions, notification types. One focus ring, on the card.\n */\nfunction CheckboxCard({\n title,\n description,\n id: idProp,\n disabled,\n className,\n cardClassName,\n ...props\n}: CheckboxCardProps) {\n const auto = React.useId();\n const id = idProp ?? auto;\n return (\n <label\n htmlFor={id}\n data-slot=\"checkbox-card\"\n className={cn(\n 'flex min-h-11 cursor-pointer items-start gap-3 rounded-md border border-border bg-surface px-3 py-2.5 transition-colors hover:border-border-strong',\n 'has-[[data-state=checked]]:border-brand/40 has-[[data-state=checked]]:bg-brand-soft/50',\n 'has-[:focus-visible]:border-ring has-[:focus-visible]:inset-ring-1 has-[:focus-visible]:inset-ring-ring',\n // :disabled also catches a disabled fieldset around the card.\n 'has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60 has-[:disabled]:hover:border-border',\n cardClassName,\n )}\n >\n <Checkbox\n id={id}\n disabled={disabled}\n aria-labelledby={`${id}-title`}\n aria-describedby={description ? `${id}-description` : undefined}\n className={cn(\n 'mt-0.5 outline-hidden! focus-visible:ring-0 focus-visible:outline-none',\n className,\n )}\n {...props}\n />\n <span className=\"grid min-w-0 gap-0.5\">\n <span id={`${id}-title`} className=\"text-sm leading-5 font-medium\">\n {title}\n </span>\n {description && (\n <span id={`${id}-description`} className=\"text-[13px] leading-5 text-muted-foreground\">\n {description}\n </span>\n )}\n </span>\n </label>\n );\n}\n\nexport interface CheckboxCardGroupProps extends React.ComponentProps<'fieldset'> {\n /** The group's name, shown as its legend. */\n label: React.ReactNode;\n /** Help under the legend. */\n description?: React.ReactNode;\n}\n\n/** A fieldset of CheckboxCards with a visible legend. `disabled` disables every card. */\nfunction CheckboxCardGroup({\n label,\n description,\n className,\n children,\n ...props\n}: CheckboxCardGroupProps) {\n const id = React.useId();\n return (\n <fieldset\n data-slot=\"checkbox-card-group\"\n aria-describedby={description ? `${id}-description` : undefined}\n className={cn('grid min-w-0 gap-2', className)}\n {...props}\n >\n <legend className=\"mb-1.5 text-sm font-medium\">{label}</legend>\n {description && (\n <p id={`${id}-description`} className=\"-mt-1.5 text-[13px] text-muted-foreground\">\n {description}\n </p>\n )}\n {children}\n </fieldset>\n );\n}\n\nexport { CheckboxCard, CheckboxCardGroup };\n"],"mappings":";;;;;;;;;;;AAwBA,SAAS,aAAa,EACpB,OACA,aACA,IAAI,QACJ,UACA,WACA,eACA,GAAG,SACiB;CACpB,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,KAAK,UAAU;CACrB,OACE,qBAAC,SAAD;EACE,SAAS;EACT,aAAU;EACV,WAAW,GACT,sJACA,0FACA,2GAEA,qGACA,aACF;EAVF,UAAA,CAYE,oBAAC,UAAD;GACM;GACM;GACV,mBAAiB,GAAG,GAAG;GACvB,oBAAkB,cAAc,GAAG,GAAG,gBAAgB,KAAA;GACtD,WAAW,GACT,0EACA,SACF;GACA,GAAI;EACL,CAAA,GACD,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,QAAD;IAAM,IAAI,GAAG,GAAG;IAAS,WAAU;IAChC,UAAA;GACG,CAAA,GACL,eACC,oBAAC,QAAD;IAAM,IAAI,GAAG,GAAG;IAAe,WAAU;IACtC,UAAA;GACG,CAAA,CAEJ;EACD,CAAA,CAAA;;AAEX;;AAUA,SAAS,kBAAkB,EACzB,OACA,aACA,WACA,UACA,GAAG,SACsB;CACzB,MAAM,KAAK,MAAM,MAAM;CACvB,OACE,qBAAC,YAAD;EACE,aAAU;EACV,oBAAkB,cAAc,GAAG,GAAG,gBAAgB,KAAA;EACtD,WAAW,GAAG,sBAAsB,SAAS;EAC7C,GAAI;EAJN,UAAA;GAME,oBAAC,UAAD;IAAQ,WAAU;IAA8B,UAAA;GAAc,CAAA;GAC7D,eACC,oBAAC,KAAD;IAAG,IAAI,GAAG,GAAG;IAAe,WAAU;IACnC,UAAA;GACA,CAAA;GAEJ;EACO;;AAEd"}
@@ -1,4 +1,4 @@
1
- import { Checkbox as CheckboxPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as CheckboxPrimitive from '../primitives/vendor/radix/react-checkbox';
3
3
  declare function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>): React.JSX.Element;
4
4
  export { Checkbox };
@@ -1,16 +1,17 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Checkbox } from "radix-ui";
3
+ import { Checkbox as Checkbox$1, CheckboxIndicator } from "../primitives/vendor/radix/react-checkbox/checkbox.js";
3
4
  import "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import Check from "@burtson-labs/icons/react/check";
6
7
  import Minus from "@burtson-labs/icons/react/minus";
7
8
  //#region src/components/checkbox.tsx
8
- function Checkbox$1({ className, ...props }) {
9
- return /* @__PURE__ */ jsx(Checkbox.Root, {
9
+ function Checkbox({ className, ...props }) {
10
+ return /* @__PURE__ */ jsx(Checkbox$1, {
10
11
  "data-slot": "checkbox",
11
12
  className: cn("peer size-4 shrink-0 rounded-xs border border-border-strong bg-surface shadow-xs transition-[border-color,box-shadow] outline-none hover:border-brand/50 focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground", className),
12
13
  ...props,
13
- children: /* @__PURE__ */ jsxs(Checkbox.Indicator, {
14
+ children: /* @__PURE__ */ jsxs(CheckboxIndicator, {
14
15
  "data-slot": "checkbox-indicator",
15
16
  className: "group/indicator grid place-content-center text-current",
16
17
  children: [/* @__PURE__ */ jsx(Check, {
@@ -26,6 +27,6 @@ function Checkbox$1({ className, ...props }) {
26
27
  });
27
28
  }
28
29
  //#endregion
29
- export { Checkbox$1 as Checkbox };
30
+ export { Checkbox };
30
31
 
31
32
  //# sourceMappingURL=checkbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","names":["Checkbox","CheckboxPrimitive"],"sources":["../../src/components/checkbox.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport Minus from '@burtson-labs/icons/react/minus';\nimport { Checkbox as CheckboxPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'peer size-4 shrink-0 rounded-xs border border-border-strong bg-surface shadow-xs transition-[border-color,box-shadow] outline-none hover:border-brand/50 focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"group/indicator grid place-content-center text-current\"\n >\n <Check\n className=\"size-3.5 group-data-[state=indeterminate]/indicator:hidden\"\n strokeWidth={2.5}\n aria-hidden\n />\n <Minus\n className=\"hidden size-3.5 group-data-[state=indeterminate]/indicator:block\"\n strokeWidth={2.5}\n aria-hidden\n />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n"],"mappings":";;;;;;;AAOA,SAASA,WAAS,EAAE,WAAW,GAAG,SAA8D;CAC9F,OACE,oBAACC,SAAkB,MAAnB;EACE,aAAU;EACV,WAAW,GACT,iZACA,SACF;EACA,GAAI;EAEJ,UAAA,qBAACA,SAAkB,WAAnB;GACE,aAAU;GACV,WAAU;GAFZ,UAAA,CAIE,oBAAC,OAAD;IACE,WAAU;IACV,aAAa;IACb,eAAA;GACD,CAAA,GACD,oBAAC,OAAD;IACE,WAAU;IACV,aAAa;IACb,eAAA;GACD,CAAA,CAC0B;;CACP,CAAA;AAE5B"}
1
+ {"version":3,"file":"checkbox.js","names":["CheckboxPrimitive.Root","CheckboxPrimitive.Indicator"],"sources":["../../src/components/checkbox.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport Minus from '@burtson-labs/icons/react/minus';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as CheckboxPrimitive from '../primitives/vendor/radix/react-checkbox';\n\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'peer size-4 shrink-0 rounded-xs border border-border-strong bg-surface shadow-xs transition-[border-color,box-shadow] outline-none hover:border-brand/50 focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"group/indicator grid place-content-center text-current\"\n >\n <Check\n className=\"size-3.5 group-data-[state=indeterminate]/indicator:hidden\"\n strokeWidth={2.5}\n aria-hidden\n />\n <Minus\n className=\"hidden size-3.5 group-data-[state=indeterminate]/indicator:block\"\n strokeWidth={2.5}\n aria-hidden\n />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n"],"mappings":";;;;;;;;AAOA,SAAS,SAAS,EAAE,WAAW,GAAG,SAA8D;CAC9F,OACE,oBAACA,YAAD;EACE,aAAU;EACV,WAAW,GACT,iZACA,SACF;EACA,GAAI;EAEJ,UAAA,qBAACC,mBAAD;GACE,aAAU;GACV,WAAU;GAFZ,UAAA,CAIE,oBAAC,OAAD;IACE,WAAU;IACV,aAAa;IACb,eAAA;GACD,CAAA,GACD,oBAAC,OAAD;IACE,WAAU;IACV,aAAa;IACb,eAAA;GACD,CAAA,CAC0B;;CACP,CAAA;AAE5B"}
@@ -1,5 +1,5 @@
1
- import { Collapsible as CollapsiblePrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as CollapsiblePrimitive from '../primitives/vendor/radix/react-collapsible';
3
3
  declare function Collapsible(props: React.ComponentProps<typeof CollapsiblePrimitive.Root>): React.JSX.Element;
4
4
  declare function CollapsibleTrigger(props: React.ComponentProps<typeof CollapsiblePrimitive.Trigger>): React.JSX.Element;
5
5
  declare function CollapsibleContent({ className, ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Content>): React.JSX.Element;
@@ -1,28 +1,29 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Collapsible } from "radix-ui";
3
+ import { Content, Root, Trigger } from "../primitives/vendor/radix/react-collapsible/collapsible.js";
3
4
  import "react";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  //#region src/components/collapsible.tsx
6
- function Collapsible$1(props) {
7
- return /* @__PURE__ */ jsx(Collapsible.Root, {
7
+ function Collapsible(props) {
8
+ return /* @__PURE__ */ jsx(Root, {
8
9
  "data-slot": "collapsible",
9
10
  ...props
10
11
  });
11
12
  }
12
13
  function CollapsibleTrigger(props) {
13
- return /* @__PURE__ */ jsx(Collapsible.Trigger, {
14
+ return /* @__PURE__ */ jsx(Trigger, {
14
15
  "data-slot": "collapsible-trigger",
15
16
  ...props
16
17
  });
17
18
  }
18
19
  function CollapsibleContent({ className, ...props }) {
19
- return /* @__PURE__ */ jsx(Collapsible.Content, {
20
+ return /* @__PURE__ */ jsx(Content, {
20
21
  "data-slot": "collapsible-content",
21
22
  className: cn("overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down", className),
22
23
  ...props
23
24
  });
24
25
  }
25
26
  //#endregion
26
- export { Collapsible$1 as Collapsible, CollapsibleContent, CollapsibleTrigger };
27
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger };
27
28
 
28
29
  //# sourceMappingURL=collapsible.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collapsible.js","names":["Collapsible","CollapsiblePrimitive"],"sources":["../../src/components/collapsible.tsx"],"sourcesContent":["import { Collapsible as CollapsiblePrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction Collapsible(props: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger(props: React.ComponentProps<typeof CollapsiblePrimitive.Trigger>) {\n return <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n className,\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Content>) {\n return (\n <CollapsiblePrimitive.Content\n data-slot=\"collapsible-content\"\n className={cn(\n 'overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Collapsible, CollapsibleContent, CollapsibleTrigger };\n"],"mappings":";;;;;AAKA,SAASA,cAAY,OAA+D;CAClF,OAAO,oBAACC,YAAqB,MAAtB;EAA2B,aAAU;EAAc,GAAI;CAAQ,CAAA;AACxE;AAEA,SAAS,mBAAmB,OAAkE;CAC5F,OAAO,oBAACA,YAAqB,SAAtB;EAA8B,aAAU;EAAsB,GAAI;CAAQ,CAAA;AACnF;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,oBAACA,YAAqB,SAAtB;EACE,aAAU;EACV,WAAW,GACT,yGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"collapsible.js","names":["CollapsiblePrimitive.Root","CollapsiblePrimitive.Trigger","CollapsiblePrimitive.Content"],"sources":["../../src/components/collapsible.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as CollapsiblePrimitive from '../primitives/vendor/radix/react-collapsible';\n\nfunction Collapsible(props: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger(props: React.ComponentProps<typeof CollapsiblePrimitive.Trigger>) {\n return <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n className,\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Content>) {\n return (\n <CollapsiblePrimitive.Content\n data-slot=\"collapsible-content\"\n className={cn(\n 'overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Collapsible, CollapsibleContent, CollapsibleTrigger };\n"],"mappings":";;;;;;AAKA,SAAS,YAAY,OAA+D;CAClF,OAAO,oBAACA,MAAD;EAA2B,aAAU;EAAc,GAAI;CAAQ,CAAA;AACxE;AAEA,SAAS,mBAAmB,OAAkE;CAC5F,OAAO,oBAACC,SAAD;EAA8B,aAAU;EAAsB,GAAI;CAAQ,CAAA;AACnF;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAW,GACT,yGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { Spinner } from "./spinner.js";
3
4
  import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.js","names":["_Fragment"],"sources":["../../src/components/combobox.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronsUpDown from '@burtson-labs/icons/react/chevrons-up-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { fieldClasses } from './input';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { Spinner } from './spinner';\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** Second line, e.g. an email under a name. Also searched. */\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n options: ComboboxOption[];\n value: string | null;\n onValueChange: (value: string | null) => void;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n disabled?: boolean;\n /** Show a spinner in the list, e.g. while `onSearchChange` fetches. */\n loading?: boolean;\n /**\n * Called as the person types. Pass it to search on a server; the options\n * you pass back are shown as-is (no client filtering).\n */\n onSearchChange?: (search: string) => void;\n /** Let the person clear the selection by picking it again. */\n clearable?: boolean;\n id?: string;\n className?: string;\n 'aria-invalid'?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n name?: string;\n required?: boolean;\n}\n\n/** Pick one value from a long or remote list by typing. */\nfunction Combobox({\n options,\n value,\n onValueChange,\n placeholder = 'Select…',\n searchPlaceholder = 'Search…',\n emptyText = 'No matches.',\n disabled,\n loading,\n onSearchChange,\n clearable = true,\n id,\n className,\n name,\n required,\n ...aria\n}: ComboboxProps) {\n const [open, setOpen] = React.useState(false);\n const listId = React.useId();\n const selected = options.find((o) => o.value === value);\n return (\n <>\n {name && <input type=\"hidden\" name={name} value={value ?? ''} disabled={disabled} />}\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-required={required || undefined}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n setOpen(true);\n }\n }}\n id={id}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-controls={open ? listId : undefined}\n aria-label={\n aria['aria-label'] ?? (aria['aria-labelledby'] || id ? undefined : placeholder)\n }\n aria-labelledby={aria['aria-labelledby']}\n aria-describedby={aria['aria-describedby']}\n data-required={required || undefined}\n aria-invalid={aria['aria-invalid']}\n disabled={disabled}\n data-slot=\"combobox-trigger\"\n className={cn(\n fieldClasses,\n 'flex h-9 items-center justify-between gap-2 text-left',\n !selected && 'text-muted-foreground',\n className,\n )}\n >\n <span className=\"truncate\">{selected?.label ?? value ?? placeholder}</span>\n <ChevronsUpDown className=\"size-4 shrink-0 opacity-60\" aria-hidden />\n </button>\n </PopoverTrigger>\n <PopoverContent\n id={listId}\n aria-label={aria['aria-label'] ?? placeholder}\n className=\"w-(--radix-popover-trigger-width) min-w-64 p-0\"\n align=\"start\"\n >\n <Command shouldFilter={!onSearchChange}>\n <CommandInput\n aria-label={searchPlaceholder}\n placeholder={searchPlaceholder}\n onValueChange={onSearchChange}\n />\n <CommandList>\n {loading ? (\n <div className=\"flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground\">\n <Spinner /> Searching…\n </div>\n ) : (\n <CommandEmpty>{emptyText}</CommandEmpty>\n )}\n {!loading && (\n <CommandGroup>\n {options.map((o) => (\n <CommandItem\n key={o.value}\n value={`${o.label} ${o.description ?? ''} ${o.value}`}\n disabled={o.disabled}\n onSelect={() => {\n onValueChange(clearable && o.value === value ? null : o.value);\n setOpen(false);\n }}\n >\n <span className=\"grid min-w-0 flex-1\">\n <span className=\"truncate\">{o.label}</span>\n {o.description && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {o.description}\n </span>\n )}\n </span>\n <Check\n aria-hidden\n className={cn(\n 'ml-auto size-4 text-brand',\n o.value === value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </>\n );\n}\n\nexport { Combobox };\n"],"mappings":";;;;;;;;;;;AAsDA,SAAS,SAAS,EAChB,SACA,OACA,eACA,cAAc,WACd,oBAAoB,WACpB,YAAY,eACZ,UACA,SACA,gBACA,YAAY,MACZ,IACA,WACA,MACA,UACA,GAAG,QACa;CAChB,MAAM,CAAC,MAAM,WAAW,MAAM,SAAS,KAAK;CAC5C,MAAM,SAAS,MAAM,MAAM;CAC3B,MAAM,WAAW,QAAQ,MAAM,MAAM,EAAE,UAAU,KAAK;CACtD,OACE,qBAAAA,UAAA,EAAA,UAAA,CACG,QAAQ,oBAAC,SAAD;EAAO,MAAK;EAAe;EAAM,OAAO,SAAS;EAAc;CAAW,CAAA,GACnF,qBAAC,SAAD;EAAe;EAAM,cAAc;EAAnC,UAAA,CACE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,UAAD;IACE,MAAK;IACL,MAAK;IACL,iBAAe,YAAY,KAAA;IAC3B,YAAY,UAAU;KACpB,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;MACxD,MAAM,eAAe;MACrB,QAAQ,IAAI;KACd;IACF;IACI;IACJ,iBAAe;IACf,iBAAc;IACd,iBAAe,OAAO,SAAS,KAAA;IAC/B,cACE,KAAK,kBAAkB,KAAK,sBAAsB,KAAK,KAAA,IAAY;IAErE,mBAAiB,KAAK;IACtB,oBAAkB,KAAK;IACvB,iBAAe,YAAY,KAAA;IAC3B,gBAAc,KAAK;IACT;IACV,aAAU;IACV,WAAW,GACT,cACA,yDACA,CAAC,YAAY,yBACb,SACF;IA5BF,UAAA,CA8BE,oBAAC,QAAD;KAAM,WAAU;KAAY,UAAA,UAAU,SAAS,SAAS;IAAkB,CAAA,GAC1E,oBAAC,gBAAD;KAAgB,WAAU;KAA6B,eAAA;IAAa,CAAA,CAC9D;;EACM,CAAA,GAChB,oBAAC,gBAAD;GACE,IAAI;GACJ,cAAY,KAAK,iBAAiB;GAClC,WAAU;GACV,OAAM;GAEN,UAAA,qBAAC,SAAD;IAAS,cAAc,CAAC;IAAxB,UAAA,CACE,oBAAC,cAAD;KACE,cAAY;KACZ,aAAa;KACb,eAAe;IAChB,CAAA,GACD,qBAAC,aAAD,EAAA,UAAA,CACG,UACC,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,SAAD,CAAU,CAAA,GAAC,aACR;IAEL,CAAA,IAAA,oBAAC,cAAD,EAAA,UAAe,UAAwB,CAAA,GAExC,CAAC,WACA,oBAAC,cAAD,EAAA,UACG,QAAQ,KAAK,MACZ,qBAAC,aAAD;KAEE,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,eAAe,GAAG,GAAG,EAAE;KAC9C,UAAU,EAAE;KACZ,gBAAgB;MACd,cAAc,aAAa,EAAE,UAAU,QAAQ,OAAO,EAAE,KAAK;MAC7D,QAAQ,KAAK;KACf;KAPF,UAAA,CASE,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACE,oBAAC,QAAD;OAAM,WAAU;OAAY,UAAA,EAAE;MAAY,CAAA,GACzC,EAAE,eACD,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,EAAE;MACC,CAAA,CAEJ;KACN,CAAA,GAAA,oBAAC,OAAD;MACE,eAAA;MACA,WAAW,GACT,6BACA,EAAE,UAAU,QAAQ,gBAAgB,WACtC;KACD,CAAA,CACU;IAvBN,GAAA,EAAE,KAuBI,CACd,EACW,CAAA,CAEL,EAAA,CAAA,CACN;;EACK,CAAA,CACT;CACT,CAAA,CAAA,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"combobox.js","names":["_Fragment"],"sources":["../../src/components/combobox.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronsUpDown from '@burtson-labs/icons/react/chevrons-up-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { fieldClasses } from './input';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { Spinner } from './spinner';\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** Second line, e.g. an email under a name. Also searched. */\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n options: ComboboxOption[];\n value: string | null;\n onValueChange: (value: string | null) => void;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n disabled?: boolean;\n /** Show a spinner in the list, e.g. while `onSearchChange` fetches. */\n loading?: boolean;\n /**\n * Called as the person types. Pass it to search on a server; the options\n * you pass back are shown as-is (no client filtering).\n */\n onSearchChange?: (search: string) => void;\n /** Let the person clear the selection by picking it again. */\n clearable?: boolean;\n id?: string;\n className?: string;\n 'aria-invalid'?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n name?: string;\n required?: boolean;\n}\n\n/** Pick one value from a long or remote list by typing. */\nfunction Combobox({\n options,\n value,\n onValueChange,\n placeholder = 'Select…',\n searchPlaceholder = 'Search…',\n emptyText = 'No matches.',\n disabled,\n loading,\n onSearchChange,\n clearable = true,\n id,\n className,\n name,\n required,\n ...aria\n}: ComboboxProps) {\n const [open, setOpen] = React.useState(false);\n const listId = React.useId();\n const selected = options.find((o) => o.value === value);\n return (\n <>\n {name && <input type=\"hidden\" name={name} value={value ?? ''} disabled={disabled} />}\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-required={required || undefined}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n setOpen(true);\n }\n }}\n id={id}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-controls={open ? listId : undefined}\n aria-label={\n aria['aria-label'] ?? (aria['aria-labelledby'] || id ? undefined : placeholder)\n }\n aria-labelledby={aria['aria-labelledby']}\n aria-describedby={aria['aria-describedby']}\n data-required={required || undefined}\n aria-invalid={aria['aria-invalid']}\n disabled={disabled}\n data-slot=\"combobox-trigger\"\n className={cn(\n fieldClasses,\n 'flex h-9 items-center justify-between gap-2 text-left',\n !selected && 'text-muted-foreground',\n className,\n )}\n >\n <span className=\"truncate\">{selected?.label ?? value ?? placeholder}</span>\n <ChevronsUpDown className=\"size-4 shrink-0 opacity-60\" aria-hidden />\n </button>\n </PopoverTrigger>\n <PopoverContent\n id={listId}\n aria-label={aria['aria-label'] ?? placeholder}\n className=\"w-(--radix-popover-trigger-width) min-w-64 p-0\"\n align=\"start\"\n >\n <Command shouldFilter={!onSearchChange}>\n <CommandInput\n aria-label={searchPlaceholder}\n placeholder={searchPlaceholder}\n onValueChange={onSearchChange}\n />\n <CommandList>\n {loading ? (\n <div className=\"flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground\">\n <Spinner /> Searching…\n </div>\n ) : (\n <CommandEmpty>{emptyText}</CommandEmpty>\n )}\n {!loading && (\n <CommandGroup>\n {options.map((o) => (\n <CommandItem\n key={o.value}\n value={`${o.label} ${o.description ?? ''} ${o.value}`}\n disabled={o.disabled}\n onSelect={() => {\n onValueChange(clearable && o.value === value ? null : o.value);\n setOpen(false);\n }}\n >\n <span className=\"grid min-w-0 flex-1\">\n <span className=\"truncate\">{o.label}</span>\n {o.description && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {o.description}\n </span>\n )}\n </span>\n <Check\n aria-hidden\n className={cn(\n 'ml-auto size-4 text-brand',\n o.value === value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </>\n );\n}\n\nexport { Combobox };\n"],"mappings":";;;;;;;;;;;;AAsDA,SAAS,SAAS,EAChB,SACA,OACA,eACA,cAAc,WACd,oBAAoB,WACpB,YAAY,eACZ,UACA,SACA,gBACA,YAAY,MACZ,IACA,WACA,MACA,UACA,GAAG,QACa;CAChB,MAAM,CAAC,MAAM,WAAW,MAAM,SAAS,KAAK;CAC5C,MAAM,SAAS,MAAM,MAAM;CAC3B,MAAM,WAAW,QAAQ,MAAM,MAAM,EAAE,UAAU,KAAK;CACtD,OACE,qBAAAA,UAAA,EAAA,UAAA,CACG,QAAQ,oBAAC,SAAD;EAAO,MAAK;EAAe;EAAM,OAAO,SAAS;EAAc;CAAW,CAAA,GACnF,qBAAC,SAAD;EAAe;EAAM,cAAc;EAAnC,UAAA,CACE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,UAAD;IACE,MAAK;IACL,MAAK;IACL,iBAAe,YAAY,KAAA;IAC3B,YAAY,UAAU;KACpB,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;MACxD,MAAM,eAAe;MACrB,QAAQ,IAAI;KACd;IACF;IACI;IACJ,iBAAe;IACf,iBAAc;IACd,iBAAe,OAAO,SAAS,KAAA;IAC/B,cACE,KAAK,kBAAkB,KAAK,sBAAsB,KAAK,KAAA,IAAY;IAErE,mBAAiB,KAAK;IACtB,oBAAkB,KAAK;IACvB,iBAAe,YAAY,KAAA;IAC3B,gBAAc,KAAK;IACT;IACV,aAAU;IACV,WAAW,GACT,cACA,yDACA,CAAC,YAAY,yBACb,SACF;IA5BF,UAAA,CA8BE,oBAAC,QAAD;KAAM,WAAU;KAAY,UAAA,UAAU,SAAS,SAAS;IAAkB,CAAA,GAC1E,oBAAC,gBAAD;KAAgB,WAAU;KAA6B,eAAA;IAAa,CAAA,CAC9D;;EACM,CAAA,GAChB,oBAAC,gBAAD;GACE,IAAI;GACJ,cAAY,KAAK,iBAAiB;GAClC,WAAU;GACV,OAAM;GAEN,UAAA,qBAAC,SAAD;IAAS,cAAc,CAAC;IAAxB,UAAA,CACE,oBAAC,cAAD;KACE,cAAY;KACZ,aAAa;KACb,eAAe;IAChB,CAAA,GACD,qBAAC,aAAD,EAAA,UAAA,CACG,UACC,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,SAAD,CAAU,CAAA,GAAC,aACR;IAEL,CAAA,IAAA,oBAAC,cAAD,EAAA,UAAe,UAAwB,CAAA,GAExC,CAAC,WACA,oBAAC,cAAD,EAAA,UACG,QAAQ,KAAK,MACZ,qBAAC,aAAD;KAEE,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,eAAe,GAAG,GAAG,EAAE;KAC9C,UAAU,EAAE;KACZ,gBAAgB;MACd,cAAc,aAAa,EAAE,UAAU,QAAQ,OAAO,EAAE,KAAK;MAC7D,QAAQ,KAAK;KACf;KAPF,UAAA,CASE,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACE,oBAAC,QAAD;OAAM,WAAU;OAAY,UAAA,EAAE;MAAY,CAAA,GACzC,EAAE,eACD,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,EAAE;MACC,CAAA,CAEJ;KACN,CAAA,GAAA,oBAAC,OAAD;MACE,eAAA;MACA,WAAW,GACT,6BACA,EAAE,UAAU,QAAQ,gBAAgB,WACtC;KACD,CAAA,CACU;IAvBN,GAAA,EAAE,KAuBI,CACd,EACW,CAAA,CAEL,EAAA,CAAA,CACN;;EACK,CAAA,CACT;CACT,CAAA,CAAA,EAAA,CAAA;AAEN"}