@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,5 @@
1
- import { Command as CommandPrimitive } from 'cmdk';
2
1
  import * as React from 'react';
2
+ import { Command as CommandPrimitive } from '../primitives/vendor/cmdk';
3
3
  import { Dialog } from './dialog';
4
4
  declare function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>): React.JSX.Element;
5
5
  /** A command palette in a dialog, the usual ⌘K surface. */
@@ -1,12 +1,13 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
3
+ import { Command as pkg } from "../primitives/vendor/cmdk/index.js";
2
4
  import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./dialog.js";
3
5
  import "react";
4
6
  import { jsx, jsxs } from "react/jsx-runtime";
5
7
  import Search from "@burtson-labs/icons/react/search";
6
- import { Command } from "cmdk";
7
8
  //#region src/components/command.tsx
8
- function Command$1({ className, ...props }) {
9
- return /* @__PURE__ */ jsx(Command, {
9
+ function Command({ className, ...props }) {
10
+ return /* @__PURE__ */ jsx(pkg, {
10
11
  "data-slot": "command",
11
12
  className: cn("flex h-full w-full flex-col overflow-hidden rounded-lg bg-surface-raised text-popover-foreground has-[[cmdk-input]:focus-visible]:border-ring", className),
12
13
  ...props
@@ -22,7 +23,7 @@ function CommandDialog({ title = "Command palette", description = "Search for a
22
23
  children: [/* @__PURE__ */ jsxs(DialogHeader, {
23
24
  className: "sr-only",
24
25
  children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })]
25
- }), /* @__PURE__ */ jsx(Command$1, {
26
+ }), /* @__PURE__ */ jsx(Command, {
26
27
  className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-2",
27
28
  children
28
29
  })]
@@ -36,7 +37,7 @@ function CommandInput({ className, ...props }) {
36
37
  children: [/* @__PURE__ */ jsx(Search, {
37
38
  className: "size-4 shrink-0 opacity-50",
38
39
  "aria-hidden": true
39
- }), /* @__PURE__ */ jsx(Command.Input, {
40
+ }), /* @__PURE__ */ jsx(pkg.Input, {
40
41
  "data-slot": "command-input",
41
42
  className: cn("flex h-10 w-full rounded-none border-0 bg-transparent py-3 text-sm shadow-none outline-hidden! placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50", className),
42
43
  ...props
@@ -44,35 +45,35 @@ function CommandInput({ className, ...props }) {
44
45
  });
45
46
  }
46
47
  function CommandList({ className, ...props }) {
47
- return /* @__PURE__ */ jsx(Command.List, {
48
+ return /* @__PURE__ */ jsx(pkg.List, {
48
49
  "data-slot": "command-list",
49
50
  className: cn("max-h-80 scroll-py-1 overflow-x-hidden overflow-y-auto p-1", className),
50
51
  ...props
51
52
  });
52
53
  }
53
54
  function CommandEmpty(props) {
54
- return /* @__PURE__ */ jsx(Command.Empty, {
55
+ return /* @__PURE__ */ jsx(pkg.Empty, {
55
56
  "data-slot": "command-empty",
56
57
  className: "py-6 text-center text-sm text-muted-foreground",
57
58
  ...props
58
59
  });
59
60
  }
60
61
  function CommandGroup({ className, ...props }) {
61
- return /* @__PURE__ */ jsx(Command.Group, {
62
+ return /* @__PURE__ */ jsx(pkg.Group, {
62
63
  "data-slot": "command-group",
63
64
  className: cn("overflow-hidden py-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", className),
64
65
  ...props
65
66
  });
66
67
  }
67
68
  function CommandSeparator({ className, ...props }) {
68
- return /* @__PURE__ */ jsx(Command.Separator, {
69
+ return /* @__PURE__ */ jsx(pkg.Separator, {
69
70
  "data-slot": "command-separator",
70
71
  className: cn("-mx-1 h-px bg-border", className),
71
72
  ...props
72
73
  });
73
74
  }
74
75
  function CommandItem({ className, ...props }) {
75
- return /* @__PURE__ */ jsx(Command.Item, {
76
+ return /* @__PURE__ */ jsx(pkg.Item, {
76
77
  "data-slot": "command-item",
77
78
  className: cn("relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 text-[13px] outline-hidden! select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-secondary data-[selected=true]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
78
79
  ...props
@@ -86,6 +87,6 @@ function CommandShortcut({ className, ...props }) {
86
87
  });
87
88
  }
88
89
  //#endregion
89
- export { Command$1 as Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
90
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
90
91
 
91
92
  //# sourceMappingURL=command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","names":["Command","CommandPrimitive"],"sources":["../../src/components/command.tsx"],"sourcesContent":["import Search from '@burtson-labs/icons/react/search';\nimport { Command as CommandPrimitive } from 'cmdk';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog';\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n // Standalone with a border, the box is the field: its border takes the\n // ring colour while the search input has keyboard focus. In a popover or\n // dialog there is no border of its own, so the rule draws nothing.\n 'flex h-full w-full flex-col overflow-hidden rounded-lg bg-surface-raised text-popover-foreground has-[[cmdk-input]:focus-visible]:border-ring',\n className,\n )}\n {...props}\n />\n );\n}\n\n/** A command palette in a dialog, the usual ⌘K surface. */\nfunction CommandDialog({\n title = 'Command palette',\n description = 'Search for a page or an action',\n children,\n className,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string;\n description?: string;\n className?: string;\n}) {\n return (\n <Dialog {...props}>\n <DialogContent\n className={cn(\n 'top-[20%] translate-y-0 gap-0 overflow-hidden p-0 sm:max-w-xl sm:p-0',\n className,\n )}\n showCloseButton={false}\n >\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <Command className=\"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-2\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n // The row is the field (icon + input, ruled off from the list); the input\n // itself draws no border or outline, whatever the host page's CSS says.\n <div data-slot=\"command-input-wrapper\" className=\"flex h-11 items-center gap-2 border-b px-3\">\n <Search className=\"size-4 shrink-0 opacity-50\" aria-hidden />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n 'flex h-10 w-full rounded-none border-0 bg-transparent py-3 text-sm shadow-none outline-hidden! placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn('max-h-80 scroll-py-1 overflow-x-hidden overflow-y-auto p-1', className)}\n {...props}\n />\n );\n}\n\nfunction CommandEmpty(props: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm text-muted-foreground\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n 'overflow-hidden py-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn('-mx-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 text-[13px] outline-hidden! select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-secondary data-[selected=true]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n 'ml-auto rounded-xs border border-border bg-surface-muted px-1.5 font-mono text-[11px] leading-5 text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n};\n"],"mappings":";;;;;;;AAQA,SAASA,UAAQ,EAAE,WAAW,GAAG,SAAwD;CACvF,OACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAW,GAIT,iJACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,cAAc,EACrB,QAAQ,mBACR,cAAc,kCACd,UACA,WACA,GAAG,SAKF;CACD,OACE,oBAAC,QAAD;EAAQ,GAAI;EACV,UAAA,qBAAC,eAAD;GACE,WAAW,GACT,wEACA,SACF;GACA,iBAAiB;GALnB,UAAA,CAOE,qBAAC,cAAD;IAAc,WAAU;IAAxB,UAAA,CACE,oBAAC,aAAD,EAAA,UAAc,MAAmB,CAAA,GACjC,oBAAC,mBAAD,EAAA,UAAoB,YAA+B,CAAA,CACvC;GACd,CAAA,GAAA,oBAACD,WAAD;IAAS,WAAU;IAChB;GACM,CAAA,CACI;;CACT,CAAA;AAEZ;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OAGE,qBAAC,OAAD;EAAK,aAAU;EAAwB,WAAU;EAAjD,UAAA,CACE,oBAAC,QAAD;GAAQ,WAAU;GAA6B,eAAA;EAAa,CAAA,GAC5D,oBAACC,QAAiB,OAAlB;GACE,aAAU;GACV,WAAW,GACT,oLACA,SACF;GACA,GAAI;EACL,CAAA,CACE;;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GAAG,8DAA8D,SAAS;EACrF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,OAA4D;CAChF,OACE,oBAACA,QAAiB,OAAlB;EACE,aAAU;EACV,WAAU;EACV,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAACA,QAAiB,OAAlB;EACE,aAAU;EACV,WAAW,GACT,2NACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAACA,QAAiB,WAAlB;EACE,aAAU;EACV,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,yYACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAuC;CAC9E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,yHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"command.js","names":["CommandPrimitive"],"sources":["../../src/components/command.tsx"],"sourcesContent":["import Search from '@burtson-labs/icons/react/search';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport { Command as CommandPrimitive } from '../primitives/vendor/cmdk';\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog';\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n // Standalone with a border, the box is the field: its border takes the\n // ring colour while the search input has keyboard focus. In a popover or\n // dialog there is no border of its own, so the rule draws nothing.\n 'flex h-full w-full flex-col overflow-hidden rounded-lg bg-surface-raised text-popover-foreground has-[[cmdk-input]:focus-visible]:border-ring',\n className,\n )}\n {...props}\n />\n );\n}\n\n/** A command palette in a dialog, the usual ⌘K surface. */\nfunction CommandDialog({\n title = 'Command palette',\n description = 'Search for a page or an action',\n children,\n className,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string;\n description?: string;\n className?: string;\n}) {\n return (\n <Dialog {...props}>\n <DialogContent\n className={cn(\n 'top-[20%] translate-y-0 gap-0 overflow-hidden p-0 sm:max-w-xl sm:p-0',\n className,\n )}\n showCloseButton={false}\n >\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <Command className=\"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-2\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n // The row is the field (icon + input, ruled off from the list); the input\n // itself draws no border or outline, whatever the host page's CSS says.\n <div data-slot=\"command-input-wrapper\" className=\"flex h-11 items-center gap-2 border-b px-3\">\n <Search className=\"size-4 shrink-0 opacity-50\" aria-hidden />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n 'flex h-10 w-full rounded-none border-0 bg-transparent py-3 text-sm shadow-none outline-hidden! placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn('max-h-80 scroll-py-1 overflow-x-hidden overflow-y-auto p-1', className)}\n {...props}\n />\n );\n}\n\nfunction CommandEmpty(props: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm text-muted-foreground\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n 'overflow-hidden py-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn('-mx-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 text-[13px] outline-hidden! select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-secondary data-[selected=true]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n 'ml-auto rounded-xs border border-border bg-surface-muted px-1.5 font-mono text-[11px] leading-5 text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n};\n"],"mappings":";;;;;;;;AAQA,SAAS,QAAQ,EAAE,WAAW,GAAG,SAAwD;CACvF,OACE,oBAACA,KAAD;EACE,aAAU;EACV,WAAW,GAIT,iJACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,cAAc,EACrB,QAAQ,mBACR,cAAc,kCACd,UACA,WACA,GAAG,SAKF;CACD,OACE,oBAAC,QAAD;EAAQ,GAAI;EACV,UAAA,qBAAC,eAAD;GACE,WAAW,GACT,wEACA,SACF;GACA,iBAAiB;GALnB,UAAA,CAOE,qBAAC,cAAD;IAAc,WAAU;IAAxB,UAAA,CACE,oBAAC,aAAD,EAAA,UAAc,MAAmB,CAAA,GACjC,oBAAC,mBAAD,EAAA,UAAoB,YAA+B,CAAA,CACvC;GACd,CAAA,GAAA,oBAAC,SAAD;IAAS,WAAU;IAChB;GACM,CAAA,CACI;;CACT,CAAA;AAEZ;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OAGE,qBAAC,OAAD;EAAK,aAAU;EAAwB,WAAU;EAAjD,UAAA,CACE,oBAAC,QAAD;GAAQ,WAAU;GAA6B,eAAA;EAAa,CAAA,GAC5D,oBAACA,IAAiB,OAAlB;GACE,aAAU;GACV,WAAW,GACT,oLACA,SACF;GACA,GAAI;EACL,CAAA,CACE;;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,IAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GAAG,8DAA8D,SAAS;EACrF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,OAA4D;CAChF,OACE,oBAACA,IAAiB,OAAlB;EACE,aAAU;EACV,WAAU;EACV,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAACA,IAAiB,OAAlB;EACE,aAAU;EACV,WAAW,GACT,2NACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAACA,IAAiB,WAAlB;EACE,aAAU;EACV,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,IAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,yYACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAuC;CAC9E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,yHACA,SACF;EACA,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 * as React from "react";
@@ -1 +1 @@
1
- {"version":3,"file":"composer.js","names":["_Fragment"],"sources":["../../src/components/composer.tsx"],"sourcesContent":["import ArrowUp from '@burtson-labs/icons/react/arrow-up';\nimport Paperclip from '@burtson-labs/icons/react/paperclip';\nimport Square from '@burtson-labs/icons/react/square';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\n\nexport interface ComposerProps extends Omit<React.ComponentProps<'form'>, 'onSubmit' | 'onChange'> {\n /**\n * Clears after success. Reject a returned promise to retain the draft. The\n * text can be empty when `attachmentCount` allows an attachment-only send.\n */\n onSubmit: (text: string) => void | Promise<void>;\n onSubmitError?: (error: unknown) => void;\n submitErrorText?: string;\n /** Controlled value; leave out to let the composer keep its own. */\n value?: string;\n onValueChange?: (value: string) => void;\n /** While a reply streams, the send button becomes Stop. */\n streaming?: boolean;\n onStop?: () => void;\n disabled?: boolean;\n placeholder?: string;\n /** Attachment chips or a file button, shown under the text. */\n attachments?: React.ReactNode;\n /** Attachments ready to send. Above zero, an empty message can be sent. */\n attachmentCount?: number;\n /**\n * Extra gate on sending, e.g. false while an attachment is still parsing.\n * Unlike `disabled`, the person can keep typing.\n */\n canSubmit?: boolean;\n /** Extra controls left of the send button (model picker, tools). */\n actions?: React.ReactNode;\n label?: string;\n /**\n * Files the person picked, dropped on the composer or pasted. Setting it\n * shows a paperclip button. The composer only hands the files over: the\n * app uploads them and renders their state in `attachments` (an\n * AttachmentTray), with `attachmentCount` and `canSubmit` for sending.\n */\n onAttach?: (files: File[]) => void;\n /** File input `accept`, e.g. \"image/*,.pdf\". Dropped and pasted files are filtered too. */\n accept?: string;\n /** Allow several files at once. Default true. */\n multiple?: boolean;\n /** Accessible name of the attach button. */\n attachLabel?: string;\n}\n\n/** Does `file` match an `accept` list (\"image/*,.pdf,text/plain\")? Empty accepts all. */\nexport function acceptsFile(file: Pick<File, 'name' | 'type'>, accept?: string): boolean {\n if (!accept?.trim()) return true;\n const name = file.name.toLowerCase();\n const type = (file.type || '').toLowerCase();\n return accept\n .split(',')\n .map((a) => a.trim().toLowerCase())\n .filter(Boolean)\n .some((rule) =>\n rule.startsWith('.')\n ? name.endsWith(rule)\n : rule.endsWith('/*')\n ? type.startsWith(rule.slice(0, -1))\n : type === rule,\n );\n}\n\n/**\n * The message box: grows with its text, Enter sends, Shift+Enter adds a\n * line, and it never sends mid-composition (IME input).\n */\nfunction Composer({\n onSubmit,\n onSubmitError,\n submitErrorText = 'Message could not be sent. Your draft is saved here. Try again.',\n value: controlled,\n onValueChange,\n streaming = false,\n onStop,\n disabled = false,\n placeholder = 'Ask anything…',\n attachments,\n attachmentCount = 0,\n canSubmit = true,\n actions,\n label = 'Message',\n onAttach,\n accept,\n multiple = true,\n attachLabel = 'Attach files',\n className,\n ...props\n}: ComposerProps) {\n const fileInput = React.useRef<HTMLInputElement>(null);\n const [dragging, setDragging] = React.useState(false);\n const dragDepth = React.useRef(0);\n const attach = (list: FileList | File[] | null | undefined) => {\n if (!onAttach || !list) return;\n let files = Array.from(list).filter((f) => acceptsFile(f, accept));\n if (!multiple) files = files.slice(0, 1);\n if (files.length) onAttach(files);\n };\n const hasFiles = (e: React.DragEvent) =>\n Array.from(e.dataTransfer?.types ?? []).includes('Files');\n const [own, setOwn] = React.useState('');\n const value = controlled ?? own;\n const [pending, setPending] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n const sending = React.useRef(false);\n const latest = React.useRef(value);\n const mounted = React.useRef(true);\n const errorId = React.useId();\n React.useEffect(() => {\n latest.current = value;\n }, [value]);\n React.useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const setValue = (v: string) => {\n if (controlled === undefined) setOwn(v);\n onValueChange?.(v);\n };\n const canSend =\n canSubmit &&\n !disabled &&\n !streaming &&\n !pending &&\n (value.trim().length > 0 || attachmentCount > 0);\n const send = async () => {\n if (!canSend || sending.current) return;\n const draft = value;\n sending.current = true;\n setFailed(false);\n setPending(true);\n try {\n await onSubmit(draft.trim());\n if (mounted.current && latest.current === draft) setValue('');\n } catch (error) {\n if (mounted.current) setFailed(true);\n onSubmitError?.(error);\n } finally {\n sending.current = false;\n if (mounted.current) setPending(false);\n }\n };\n\n return (\n <form\n data-slot=\"composer\"\n data-dragging={dragging || undefined}\n onSubmit={(e) => {\n e.preventDefault();\n void send();\n }}\n onDragEnter={(e) => {\n if (!onAttach || disabled || !hasFiles(e)) return;\n e.preventDefault();\n dragDepth.current += 1;\n setDragging(true);\n }}\n onDragOver={(e) => {\n if (!onAttach || disabled || !hasFiles(e)) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n }}\n onDragLeave={() => {\n if (!onAttach) return;\n dragDepth.current = Math.max(0, dragDepth.current - 1);\n if (dragDepth.current === 0) setDragging(false);\n }}\n onDrop={(e) => {\n if (!onAttach || disabled) return;\n e.preventDefault();\n dragDepth.current = 0;\n setDragging(false);\n attach(e.dataTransfer?.files);\n }}\n className={cn(\n // The box is the field: same focus as Input (ring border + 1px inset ring).\n 'relative grid gap-2 rounded-lg border border-input bg-surface p-2 shadow-xs transition-[border-color,box-shadow] has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:inset-ring-1 has-[textarea:focus-visible]:inset-ring-ring dark:bg-surface-raised',\n 'data-[dragging]:border-brand data-[dragging]:inset-ring-1 data-[dragging]:inset-ring-brand',\n disabled && 'opacity-60',\n className,\n )}\n {...props}\n >\n {dragging && (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-1 z-10 grid place-items-center rounded-md border border-dashed border-brand/50 bg-brand-soft/80 text-sm font-medium text-brand-soft-foreground\"\n >\n Drop files to attach\n </div>\n )}\n <textarea\n aria-label={label}\n rows={1}\n value={value}\n disabled={disabled || pending}\n aria-describedby={failed ? errorId : undefined}\n aria-invalid={failed || undefined}\n placeholder={placeholder}\n onChange={(e) => setValue(e.target.value)}\n onPaste={(e) => {\n if (!onAttach) return;\n const files = Array.from(e.clipboardData?.files ?? []);\n // Only take over the paste when it carries files; text pastes as text.\n if (files.length) {\n e.preventDefault();\n attach(files);\n }\n }}\n onKeyDown={(e) => {\n if (\n e.key === 'Enter' &&\n !e.shiftKey &&\n !e.nativeEvent.isComposing &&\n e.nativeEvent.keyCode !== 229\n ) {\n e.preventDefault();\n void send();\n }\n }}\n className=\"field-sizing-content max-h-48 min-h-9 w-full resize-none rounded-none border-0 bg-transparent px-2 py-1.5 text-base sm:text-sm leading-6 shadow-none outline-hidden! placeholder:text-muted-foreground disabled:cursor-not-allowed\"\n />\n {failed && (\n <p id={errorId} role=\"alert\" className=\"px-2 text-sm text-destructive\">\n {submitErrorText}\n </p>\n )}\n {attachments && <div className=\"flex flex-wrap gap-1.5 px-1\">{attachments}</div>}\n <div className=\"flex items-center gap-1\">\n {onAttach && (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n hidden\n tabIndex={-1}\n accept={accept}\n multiple={multiple}\n data-slot=\"composer-file-input\"\n onChange={(e) => {\n attach(e.target.files);\n // Let the same file be picked again after a removal.\n e.target.value = '';\n }}\n />\n <Button\n type=\"button\"\n size=\"icon-sm\"\n variant=\"ghost\"\n aria-label={attachLabel}\n title={attachLabel}\n disabled={disabled}\n onClick={() => fileInput.current?.click()}\n className=\"pointer-coarse:size-11\"\n >\n <Paperclip />\n </Button>\n </>\n )}\n {actions}\n <div className=\"ml-auto\">\n {streaming ? (\n <Button\n type=\"button\"\n size=\"icon-sm\"\n variant=\"secondary\"\n aria-label=\"Stop\"\n className=\"pointer-coarse:size-11\"\n onClick={onStop}\n disabled={!onStop || disabled}\n >\n <Square className=\"fill-current\" />\n </Button>\n ) : (\n <Button\n type=\"submit\"\n size=\"icon-sm\"\n aria-label=\"Send\"\n className=\"pointer-coarse:size-11\"\n loading={pending}\n disabled={!canSend}\n >\n <ArrowUp />\n </Button>\n )}\n </div>\n </div>\n </form>\n );\n}\n\nexport interface SuggestionsProps extends Omit<React.ComponentProps<'div'>, 'onSelect'> {\n items: string[];\n onSelect: (item: string) => void;\n}\n\n/** Starter prompts as chips. */\nfunction Suggestions({ items, onSelect, className, ...props }: SuggestionsProps) {\n return (\n <div\n data-slot=\"suggestions\"\n role=\"group\"\n aria-label=\"Suggestions\"\n className={cn('flex flex-wrap gap-2', className)}\n {...props}\n >\n {items.map((item) => (\n <button\n key={item}\n type=\"button\"\n onClick={() => onSelect(item)}\n className=\"animate-in rounded-full border border-border-strong bg-surface px-3 py-1.5 text-[13px] text-foreground outline-none transition-colors hover:border-brand/40 hover:bg-brand-soft hover:text-brand-soft-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n {item}\n </button>\n ))}\n </div>\n );\n}\n\nexport { Composer, Suggestions };\n"],"mappings":"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"}
1
+ {"version":3,"file":"composer.js","names":["_Fragment"],"sources":["../../src/components/composer.tsx"],"sourcesContent":["import ArrowUp from '@burtson-labs/icons/react/arrow-up';\nimport Paperclip from '@burtson-labs/icons/react/paperclip';\nimport Square from '@burtson-labs/icons/react/square';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\n\nexport interface ComposerProps extends Omit<React.ComponentProps<'form'>, 'onSubmit' | 'onChange'> {\n /**\n * Clears after success. Reject a returned promise to retain the draft. The\n * text can be empty when `attachmentCount` allows an attachment-only send.\n */\n onSubmit: (text: string) => void | Promise<void>;\n onSubmitError?: (error: unknown) => void;\n submitErrorText?: string;\n /** Controlled value; leave out to let the composer keep its own. */\n value?: string;\n onValueChange?: (value: string) => void;\n /** While a reply streams, the send button becomes Stop. */\n streaming?: boolean;\n onStop?: () => void;\n disabled?: boolean;\n placeholder?: string;\n /** Attachment chips or a file button, shown under the text. */\n attachments?: React.ReactNode;\n /** Attachments ready to send. Above zero, an empty message can be sent. */\n attachmentCount?: number;\n /**\n * Extra gate on sending, e.g. false while an attachment is still parsing.\n * Unlike `disabled`, the person can keep typing.\n */\n canSubmit?: boolean;\n /** Extra controls left of the send button (model picker, tools). */\n actions?: React.ReactNode;\n label?: string;\n /**\n * Files the person picked, dropped on the composer or pasted. Setting it\n * shows a paperclip button. The composer only hands the files over: the\n * app uploads them and renders their state in `attachments` (an\n * AttachmentTray), with `attachmentCount` and `canSubmit` for sending.\n */\n onAttach?: (files: File[]) => void;\n /** File input `accept`, e.g. \"image/*,.pdf\". Dropped and pasted files are filtered too. */\n accept?: string;\n /** Allow several files at once. Default true. */\n multiple?: boolean;\n /** Accessible name of the attach button. */\n attachLabel?: string;\n}\n\n/** Does `file` match an `accept` list (\"image/*,.pdf,text/plain\")? Empty accepts all. */\nexport function acceptsFile(file: Pick<File, 'name' | 'type'>, accept?: string): boolean {\n if (!accept?.trim()) return true;\n const name = file.name.toLowerCase();\n const type = (file.type || '').toLowerCase();\n return accept\n .split(',')\n .map((a) => a.trim().toLowerCase())\n .filter(Boolean)\n .some((rule) =>\n rule.startsWith('.')\n ? name.endsWith(rule)\n : rule.endsWith('/*')\n ? type.startsWith(rule.slice(0, -1))\n : type === rule,\n );\n}\n\n/**\n * The message box: grows with its text, Enter sends, Shift+Enter adds a\n * line, and it never sends mid-composition (IME input).\n */\nfunction Composer({\n onSubmit,\n onSubmitError,\n submitErrorText = 'Message could not be sent. Your draft is saved here. Try again.',\n value: controlled,\n onValueChange,\n streaming = false,\n onStop,\n disabled = false,\n placeholder = 'Ask anything…',\n attachments,\n attachmentCount = 0,\n canSubmit = true,\n actions,\n label = 'Message',\n onAttach,\n accept,\n multiple = true,\n attachLabel = 'Attach files',\n className,\n ...props\n}: ComposerProps) {\n const fileInput = React.useRef<HTMLInputElement>(null);\n const [dragging, setDragging] = React.useState(false);\n const dragDepth = React.useRef(0);\n const attach = (list: FileList | File[] | null | undefined) => {\n if (!onAttach || !list) return;\n let files = Array.from(list).filter((f) => acceptsFile(f, accept));\n if (!multiple) files = files.slice(0, 1);\n if (files.length) onAttach(files);\n };\n const hasFiles = (e: React.DragEvent) =>\n Array.from(e.dataTransfer?.types ?? []).includes('Files');\n const [own, setOwn] = React.useState('');\n const value = controlled ?? own;\n const [pending, setPending] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n const sending = React.useRef(false);\n const latest = React.useRef(value);\n const mounted = React.useRef(true);\n const errorId = React.useId();\n React.useEffect(() => {\n latest.current = value;\n }, [value]);\n React.useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const setValue = (v: string) => {\n if (controlled === undefined) setOwn(v);\n onValueChange?.(v);\n };\n const canSend =\n canSubmit &&\n !disabled &&\n !streaming &&\n !pending &&\n (value.trim().length > 0 || attachmentCount > 0);\n const send = async () => {\n if (!canSend || sending.current) return;\n const draft = value;\n sending.current = true;\n setFailed(false);\n setPending(true);\n try {\n await onSubmit(draft.trim());\n if (mounted.current && latest.current === draft) setValue('');\n } catch (error) {\n if (mounted.current) setFailed(true);\n onSubmitError?.(error);\n } finally {\n sending.current = false;\n if (mounted.current) setPending(false);\n }\n };\n\n return (\n <form\n data-slot=\"composer\"\n data-dragging={dragging || undefined}\n onSubmit={(e) => {\n e.preventDefault();\n void send();\n }}\n onDragEnter={(e) => {\n if (!onAttach || disabled || !hasFiles(e)) return;\n e.preventDefault();\n dragDepth.current += 1;\n setDragging(true);\n }}\n onDragOver={(e) => {\n if (!onAttach || disabled || !hasFiles(e)) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n }}\n onDragLeave={() => {\n if (!onAttach) return;\n dragDepth.current = Math.max(0, dragDepth.current - 1);\n if (dragDepth.current === 0) setDragging(false);\n }}\n onDrop={(e) => {\n if (!onAttach || disabled) return;\n e.preventDefault();\n dragDepth.current = 0;\n setDragging(false);\n attach(e.dataTransfer?.files);\n }}\n className={cn(\n // The box is the field: same focus as Input (ring border + 1px inset ring).\n 'relative grid gap-2 rounded-lg border border-input bg-surface p-2 shadow-xs transition-[border-color,box-shadow] has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:inset-ring-1 has-[textarea:focus-visible]:inset-ring-ring dark:bg-surface-raised',\n 'data-[dragging]:border-brand data-[dragging]:inset-ring-1 data-[dragging]:inset-ring-brand',\n disabled && 'opacity-60',\n className,\n )}\n {...props}\n >\n {dragging && (\n <div\n aria-hidden\n className=\"pointer-events-none absolute inset-1 z-10 grid place-items-center rounded-md border border-dashed border-brand/50 bg-brand-soft/80 text-sm font-medium text-brand-soft-foreground\"\n >\n Drop files to attach\n </div>\n )}\n <textarea\n aria-label={label}\n rows={1}\n value={value}\n disabled={disabled || pending}\n aria-describedby={failed ? errorId : undefined}\n aria-invalid={failed || undefined}\n placeholder={placeholder}\n onChange={(e) => setValue(e.target.value)}\n onPaste={(e) => {\n if (!onAttach) return;\n const files = Array.from(e.clipboardData?.files ?? []);\n // Only take over the paste when it carries files; text pastes as text.\n if (files.length) {\n e.preventDefault();\n attach(files);\n }\n }}\n onKeyDown={(e) => {\n if (\n e.key === 'Enter' &&\n !e.shiftKey &&\n !e.nativeEvent.isComposing &&\n e.nativeEvent.keyCode !== 229\n ) {\n e.preventDefault();\n void send();\n }\n }}\n className=\"field-sizing-content max-h-48 min-h-9 w-full resize-none rounded-none border-0 bg-transparent px-2 py-1.5 text-base sm:text-sm leading-6 shadow-none outline-hidden! placeholder:text-muted-foreground disabled:cursor-not-allowed\"\n />\n {failed && (\n <p id={errorId} role=\"alert\" className=\"px-2 text-sm text-destructive\">\n {submitErrorText}\n </p>\n )}\n {attachments && <div className=\"flex flex-wrap gap-1.5 px-1\">{attachments}</div>}\n <div className=\"flex items-center gap-1\">\n {onAttach && (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n hidden\n tabIndex={-1}\n accept={accept}\n multiple={multiple}\n data-slot=\"composer-file-input\"\n onChange={(e) => {\n attach(e.target.files);\n // Let the same file be picked again after a removal.\n e.target.value = '';\n }}\n />\n <Button\n type=\"button\"\n size=\"icon-sm\"\n variant=\"ghost\"\n aria-label={attachLabel}\n title={attachLabel}\n disabled={disabled}\n onClick={() => fileInput.current?.click()}\n className=\"pointer-coarse:size-11\"\n >\n <Paperclip />\n </Button>\n </>\n )}\n {actions}\n <div className=\"ml-auto\">\n {streaming ? (\n <Button\n type=\"button\"\n size=\"icon-sm\"\n variant=\"secondary\"\n aria-label=\"Stop\"\n className=\"pointer-coarse:size-11\"\n onClick={onStop}\n disabled={!onStop || disabled}\n >\n <Square className=\"fill-current\" />\n </Button>\n ) : (\n <Button\n type=\"submit\"\n size=\"icon-sm\"\n aria-label=\"Send\"\n className=\"pointer-coarse:size-11\"\n loading={pending}\n disabled={!canSend}\n >\n <ArrowUp />\n </Button>\n )}\n </div>\n </div>\n </form>\n );\n}\n\nexport interface SuggestionsProps extends Omit<React.ComponentProps<'div'>, 'onSelect'> {\n items: string[];\n onSelect: (item: string) => void;\n}\n\n/** Starter prompts as chips. */\nfunction Suggestions({ items, onSelect, className, ...props }: SuggestionsProps) {\n return (\n <div\n data-slot=\"suggestions\"\n role=\"group\"\n aria-label=\"Suggestions\"\n className={cn('flex flex-wrap gap-2', className)}\n {...props}\n >\n {items.map((item) => (\n <button\n key={item}\n type=\"button\"\n onClick={() => onSelect(item)}\n className=\"animate-in rounded-full border border-border-strong bg-surface px-3 py-1.5 text-[13px] text-foreground outline-none transition-colors hover:border-brand/40 hover:bg-brand-soft hover:text-brand-soft-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n {item}\n </button>\n ))}\n </div>\n );\n}\n\nexport { Composer, Suggestions };\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { Alert, AlertDescription, AlertTitle } from "./alert.js";
3
4
  import { Button } from "./button.js";
@@ -1 +1 @@
1
- {"version":3,"file":"connection-status.js","names":[],"sources":["../../src/components/connection-status.tsx"],"sourcesContent":["import CloudOff from '@burtson-labs/icons/react/cloud-off';\nimport WifiOff from '@burtson-labs/icons/react/wifi-off';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Alert, AlertDescription, AlertTitle } from './alert';\nimport { Button } from './button';\nimport { Status } from './status';\nimport { Tooltip, TooltipContent, TooltipTrigger } from './tooltip';\n\ntype Tone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'info';\n\n/**\n * The host reports the state; these components only present it. `unknown`\n * means nobody has checked yet and never reads as connected.\n */\nexport type ConnectionState =\n 'connected' | 'connecting' | 'reconnecting' | 'offline' | 'error' | 'unknown';\n\nconst connection: Record<ConnectionState, { text: string; tone: Tone; pulse?: boolean }> = {\n connected: { text: 'Connected', tone: 'success' },\n connecting: { text: 'Connecting', tone: 'info', pulse: true },\n reconnecting: { text: 'Reconnecting', tone: 'warning', pulse: true },\n offline: { text: 'Offline', tone: 'neutral' },\n error: { text: 'Connection failed', tone: 'danger' },\n unknown: { text: 'Status unknown', tone: 'neutral' },\n};\n\nexport type SyncState = 'synced' | 'syncing' | 'pending' | 'offline' | 'error' | 'unknown';\n\nconst sync: Record<SyncState, { text: string; tone: Tone; pulse?: boolean }> = {\n synced: { text: 'Synced', tone: 'success' },\n syncing: { text: 'Syncing', tone: 'info', pulse: true },\n pending: { text: 'Changes not synced yet', tone: 'warning' },\n offline: { text: 'Offline, saved on this device', tone: 'neutral' },\n error: { text: 'Sync failed', tone: 'danger' },\n unknown: { text: 'Sync status unknown', tone: 'neutral' },\n};\n\nfunction WithDetail({\n detail,\n children,\n}: {\n detail?: React.ReactNode;\n children: React.ReactElement;\n}) {\n if (!detail) return children;\n return (\n <Tooltip>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent>{detail}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction StatusLine({\n slot,\n state,\n text,\n tone,\n pulse,\n detail,\n onRetry,\n className,\n ...props\n}: Omit<React.ComponentProps<'div'>, 'children'> & {\n slot: string;\n state: string;\n text: React.ReactNode;\n tone: Tone;\n pulse?: boolean;\n detail?: React.ReactNode;\n onRetry?: () => void;\n}) {\n return (\n <div\n data-slot={slot}\n data-state={state}\n role=\"status\"\n className={cn('inline-flex items-center gap-2', className)}\n {...props}\n >\n <WithDetail detail={detail}>\n <Status\n status={tone}\n pulse={pulse}\n tabIndex={detail ? 0 : undefined}\n className=\"rounded-sm outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n {text}\n {detail && typeof detail === 'string' && <span className=\"sr-only\">. {detail}</span>}\n </Status>\n </WithDetail>\n {onRetry && (\n <Button type=\"button\" variant=\"link\" size=\"xs\" className=\"h-auto px-0\" onClick={onRetry}>\n Retry\n </Button>\n )}\n </div>\n );\n}\n\nexport interface ConnectionStatusProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n state: ConnectionState;\n /** Overrides the default text, e.g. \"Connected to Ollama\". */\n label?: React.ReactNode;\n /** More detail in a tooltip, e.g. the endpoint or last error. */\n detail?: React.ReactNode;\n /** Offered when offline or failed. */\n onRetry?: () => void;\n}\n\n/** A dot and a word for a live connection: model provider, gateway, socket. */\nfunction ConnectionStatus({ state, label, detail, onRetry, ...props }: ConnectionStatusProps) {\n const c = connection[state];\n return (\n <StatusLine\n slot=\"connection-status\"\n state={state}\n text={label ?? c.text}\n tone={c.tone}\n pulse={c.pulse}\n detail={detail}\n onRetry={state === 'offline' || state === 'error' ? onRetry : undefined}\n {...props}\n />\n );\n}\n\nexport interface SyncStatusProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n state: SyncState;\n /** When the last successful sync finished. */\n lastSynced?: Date;\n /** Changes waiting to go up. */\n pendingCount?: number;\n detail?: React.ReactNode;\n /** Offered when sync failed. */\n onRetry?: () => void;\n /** Formats `lastSynced`; the default is the local time. */\n formatTime?: (date: Date) => string;\n}\n\n/** Whether local changes have reached the server. */\nfunction SyncStatus({\n state,\n lastSynced,\n pendingCount,\n detail,\n onRetry,\n formatTime = (d) => d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }),\n ...props\n}: SyncStatusProps) {\n const s = sync[state];\n let text = s.text;\n if (state === 'synced' && lastSynced) text = `Synced ${formatTime(lastSynced)}`;\n if (state === 'pending' && pendingCount)\n text = `${pendingCount} ${pendingCount === 1 ? 'change' : 'changes'} not synced yet`;\n return (\n <StatusLine\n slot=\"sync-status\"\n state={state}\n text={text}\n tone={s.tone}\n pulse={s.pulse}\n detail={detail}\n onRetry={state === 'error' ? onRetry : undefined}\n {...props}\n />\n );\n}\n\nexport interface ConnectionBannerProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n state: ConnectionState;\n /** What still works, e.g. \"Messages you send will go out when you reconnect.\" */\n description?: React.ReactNode;\n onRetry?: () => void;\n}\n\n/**\n * A full-width notice for connection trouble. It renders nothing while\n * connected, connecting or unknown, so it can stay mounted.\n */\nfunction ConnectionBanner({\n state,\n description,\n onRetry,\n className,\n ...props\n}: ConnectionBannerProps) {\n if (state !== 'offline' && state !== 'error' && state !== 'reconnecting') return null;\n const title =\n state === 'offline'\n ? 'You are offline'\n : state === 'reconnecting'\n ? 'Reconnecting…'\n : 'Could not connect';\n return (\n <Alert\n data-slot=\"connection-banner\"\n data-state={state}\n variant={state === 'error' ? 'destructive' : 'warning'}\n className={cn('items-center', className)}\n {...props}\n >\n {state === 'offline' ? <WifiOff aria-hidden /> : <CloudOff aria-hidden />}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-x-4 gap-y-2\">\n <div className=\"min-w-0\">\n <AlertTitle>{title}</AlertTitle>\n {description && <AlertDescription>{description}</AlertDescription>}\n </div>\n {onRetry && state !== 'reconnecting' && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onRetry}>\n Retry\n </Button>\n )}\n </div>\n </Alert>\n );\n}\n\nexport { ConnectionBanner, ConnectionStatus, SyncStatus };\n"],"mappings":"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"}
1
+ {"version":3,"file":"connection-status.js","names":[],"sources":["../../src/components/connection-status.tsx"],"sourcesContent":["import CloudOff from '@burtson-labs/icons/react/cloud-off';\nimport WifiOff from '@burtson-labs/icons/react/wifi-off';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Alert, AlertDescription, AlertTitle } from './alert';\nimport { Button } from './button';\nimport { Status } from './status';\nimport { Tooltip, TooltipContent, TooltipTrigger } from './tooltip';\n\ntype Tone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'info';\n\n/**\n * The host reports the state; these components only present it. `unknown`\n * means nobody has checked yet and never reads as connected.\n */\nexport type ConnectionState =\n 'connected' | 'connecting' | 'reconnecting' | 'offline' | 'error' | 'unknown';\n\nconst connection: Record<ConnectionState, { text: string; tone: Tone; pulse?: boolean }> = {\n connected: { text: 'Connected', tone: 'success' },\n connecting: { text: 'Connecting', tone: 'info', pulse: true },\n reconnecting: { text: 'Reconnecting', tone: 'warning', pulse: true },\n offline: { text: 'Offline', tone: 'neutral' },\n error: { text: 'Connection failed', tone: 'danger' },\n unknown: { text: 'Status unknown', tone: 'neutral' },\n};\n\nexport type SyncState = 'synced' | 'syncing' | 'pending' | 'offline' | 'error' | 'unknown';\n\nconst sync: Record<SyncState, { text: string; tone: Tone; pulse?: boolean }> = {\n synced: { text: 'Synced', tone: 'success' },\n syncing: { text: 'Syncing', tone: 'info', pulse: true },\n pending: { text: 'Changes not synced yet', tone: 'warning' },\n offline: { text: 'Offline, saved on this device', tone: 'neutral' },\n error: { text: 'Sync failed', tone: 'danger' },\n unknown: { text: 'Sync status unknown', tone: 'neutral' },\n};\n\nfunction WithDetail({\n detail,\n children,\n}: {\n detail?: React.ReactNode;\n children: React.ReactElement;\n}) {\n if (!detail) return children;\n return (\n <Tooltip>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent>{detail}</TooltipContent>\n </Tooltip>\n );\n}\n\nfunction StatusLine({\n slot,\n state,\n text,\n tone,\n pulse,\n detail,\n onRetry,\n className,\n ...props\n}: Omit<React.ComponentProps<'div'>, 'children'> & {\n slot: string;\n state: string;\n text: React.ReactNode;\n tone: Tone;\n pulse?: boolean;\n detail?: React.ReactNode;\n onRetry?: () => void;\n}) {\n return (\n <div\n data-slot={slot}\n data-state={state}\n role=\"status\"\n className={cn('inline-flex items-center gap-2', className)}\n {...props}\n >\n <WithDetail detail={detail}>\n <Status\n status={tone}\n pulse={pulse}\n tabIndex={detail ? 0 : undefined}\n className=\"rounded-sm outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n {text}\n {detail && typeof detail === 'string' && <span className=\"sr-only\">. {detail}</span>}\n </Status>\n </WithDetail>\n {onRetry && (\n <Button type=\"button\" variant=\"link\" size=\"xs\" className=\"h-auto px-0\" onClick={onRetry}>\n Retry\n </Button>\n )}\n </div>\n );\n}\n\nexport interface ConnectionStatusProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n state: ConnectionState;\n /** Overrides the default text, e.g. \"Connected to Ollama\". */\n label?: React.ReactNode;\n /** More detail in a tooltip, e.g. the endpoint or last error. */\n detail?: React.ReactNode;\n /** Offered when offline or failed. */\n onRetry?: () => void;\n}\n\n/** A dot and a word for a live connection: model provider, gateway, socket. */\nfunction ConnectionStatus({ state, label, detail, onRetry, ...props }: ConnectionStatusProps) {\n const c = connection[state];\n return (\n <StatusLine\n slot=\"connection-status\"\n state={state}\n text={label ?? c.text}\n tone={c.tone}\n pulse={c.pulse}\n detail={detail}\n onRetry={state === 'offline' || state === 'error' ? onRetry : undefined}\n {...props}\n />\n );\n}\n\nexport interface SyncStatusProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n state: SyncState;\n /** When the last successful sync finished. */\n lastSynced?: Date;\n /** Changes waiting to go up. */\n pendingCount?: number;\n detail?: React.ReactNode;\n /** Offered when sync failed. */\n onRetry?: () => void;\n /** Formats `lastSynced`; the default is the local time. */\n formatTime?: (date: Date) => string;\n}\n\n/** Whether local changes have reached the server. */\nfunction SyncStatus({\n state,\n lastSynced,\n pendingCount,\n detail,\n onRetry,\n formatTime = (d) => d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }),\n ...props\n}: SyncStatusProps) {\n const s = sync[state];\n let text = s.text;\n if (state === 'synced' && lastSynced) text = `Synced ${formatTime(lastSynced)}`;\n if (state === 'pending' && pendingCount)\n text = `${pendingCount} ${pendingCount === 1 ? 'change' : 'changes'} not synced yet`;\n return (\n <StatusLine\n slot=\"sync-status\"\n state={state}\n text={text}\n tone={s.tone}\n pulse={s.pulse}\n detail={detail}\n onRetry={state === 'error' ? onRetry : undefined}\n {...props}\n />\n );\n}\n\nexport interface ConnectionBannerProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n state: ConnectionState;\n /** What still works, e.g. \"Messages you send will go out when you reconnect.\" */\n description?: React.ReactNode;\n onRetry?: () => void;\n}\n\n/**\n * A full-width notice for connection trouble. It renders nothing while\n * connected, connecting or unknown, so it can stay mounted.\n */\nfunction ConnectionBanner({\n state,\n description,\n onRetry,\n className,\n ...props\n}: ConnectionBannerProps) {\n if (state !== 'offline' && state !== 'error' && state !== 'reconnecting') return null;\n const title =\n state === 'offline'\n ? 'You are offline'\n : state === 'reconnecting'\n ? 'Reconnecting…'\n : 'Could not connect';\n return (\n <Alert\n data-slot=\"connection-banner\"\n data-state={state}\n variant={state === 'error' ? 'destructive' : 'warning'}\n className={cn('items-center', className)}\n {...props}\n >\n {state === 'offline' ? <WifiOff aria-hidden /> : <CloudOff aria-hidden />}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-x-4 gap-y-2\">\n <div className=\"min-w-0\">\n <AlertTitle>{title}</AlertTitle>\n {description && <AlertDescription>{description}</AlertDescription>}\n </div>\n {onRetry && state !== 'reconnecting' && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onRetry}>\n Retry\n </Button>\n )}\n </div>\n </Alert>\n );\n}\n\nexport { ConnectionBanner, ConnectionStatus, SyncStatus };\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { ContextMenu as ContextMenuPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as ContextMenuPrimitive from '../primitives/vendor/radix/react-context-menu';
3
3
  /**
4
4
  * A right-click menu. Wrap the target in ContextMenuTrigger (use asChild to keep
5
5
  * your element); the menu opens at the pointer, and from the keyboard with the
@@ -1,6 +1,7 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { menuItemClasses, surfaceClasses } from "./popover.js";
3
- import { ContextMenu } from "radix-ui";
4
+ import { CheckboxItem, Content, Group, Item, ItemIndicator, Label, Portal, RadioGroup, RadioItem, Root, Separator, Sub, SubContent, SubTrigger, Trigger } from "../primitives/vendor/radix/react-context-menu/context-menu.js";
4
5
  import "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  import ChevronRight from "@burtson-labs/icons/react/chevron-right";
@@ -12,33 +13,33 @@ import Check from "@burtson-labs/icons/react/check";
12
13
  * context-menu key or Shift+F10 on the focused target. Same rows as
13
14
  * DropdownMenu, so a command can appear in both.
14
15
  */
15
- function ContextMenu$1(props) {
16
- return /* @__PURE__ */ jsx(ContextMenu.Root, {
16
+ function ContextMenu(props) {
17
+ return /* @__PURE__ */ jsx(Root, {
17
18
  "data-slot": "context-menu",
18
19
  ...props
19
20
  });
20
21
  }
21
22
  function ContextMenuTrigger(props) {
22
- return /* @__PURE__ */ jsx(ContextMenu.Trigger, {
23
+ return /* @__PURE__ */ jsx(Trigger, {
23
24
  "data-slot": "context-menu-trigger",
24
25
  ...props
25
26
  });
26
27
  }
27
28
  function ContextMenuGroup(props) {
28
- return /* @__PURE__ */ jsx(ContextMenu.Group, {
29
+ return /* @__PURE__ */ jsx(Group, {
29
30
  "data-slot": "context-menu-group",
30
31
  ...props
31
32
  });
32
33
  }
33
34
  function ContextMenuContent({ className, ...props }) {
34
- return /* @__PURE__ */ jsx(ContextMenu.Portal, { children: /* @__PURE__ */ jsx(ContextMenu.Content, {
35
+ return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Content, {
35
36
  "data-slot": "context-menu-content",
36
37
  className: cn(surfaceClasses, "max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1", className),
37
38
  ...props
38
39
  }) });
39
40
  }
40
41
  function ContextMenuItem({ className, inset, variant = "default", ...props }) {
41
- return /* @__PURE__ */ jsx(ContextMenu.Item, {
42
+ return /* @__PURE__ */ jsx(Item, {
42
43
  "data-slot": "context-menu-item",
43
44
  "data-inset": inset || void 0,
44
45
  "data-variant": variant,
@@ -47,14 +48,14 @@ function ContextMenuItem({ className, inset, variant = "default", ...props }) {
47
48
  });
48
49
  }
49
50
  function ContextMenuCheckboxItem({ className, children, checked, ...props }) {
50
- return /* @__PURE__ */ jsxs(ContextMenu.CheckboxItem, {
51
+ return /* @__PURE__ */ jsxs(CheckboxItem, {
51
52
  "data-slot": "context-menu-checkbox-item",
52
53
  className: cn(menuItemClasses, "pl-8", className),
53
54
  checked,
54
55
  ...props,
55
56
  children: [/* @__PURE__ */ jsx("span", {
56
57
  className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
57
- children: /* @__PURE__ */ jsx(ContextMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, {
58
+ children: /* @__PURE__ */ jsx(ItemIndicator, { children: /* @__PURE__ */ jsx(Check, {
58
59
  className: "size-4 text-foreground",
59
60
  "aria-hidden": true
60
61
  }) })
@@ -62,24 +63,24 @@ function ContextMenuCheckboxItem({ className, children, checked, ...props }) {
62
63
  });
63
64
  }
64
65
  function ContextMenuRadioGroup(props) {
65
- return /* @__PURE__ */ jsx(ContextMenu.RadioGroup, {
66
+ return /* @__PURE__ */ jsx(RadioGroup, {
66
67
  "data-slot": "context-menu-radio-group",
67
68
  ...props
68
69
  });
69
70
  }
70
71
  function ContextMenuRadioItem({ className, children, ...props }) {
71
- return /* @__PURE__ */ jsxs(ContextMenu.RadioItem, {
72
+ return /* @__PURE__ */ jsxs(RadioItem, {
72
73
  "data-slot": "context-menu-radio-item",
73
74
  className: cn(menuItemClasses, "pl-8", className),
74
75
  ...props,
75
76
  children: [/* @__PURE__ */ jsx("span", {
76
77
  className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
77
- children: /* @__PURE__ */ jsx(ContextMenu.ItemIndicator, { children: /* @__PURE__ */ jsx("span", { className: "block size-2 rounded-full bg-foreground" }) })
78
+ children: /* @__PURE__ */ jsx(ItemIndicator, { children: /* @__PURE__ */ jsx("span", { className: "block size-2 rounded-full bg-foreground" }) })
78
79
  }), children]
79
80
  });
80
81
  }
81
82
  function ContextMenuLabel({ className, inset, ...props }) {
82
- return /* @__PURE__ */ jsx(ContextMenu.Label, {
83
+ return /* @__PURE__ */ jsx(Label, {
83
84
  "data-slot": "context-menu-label",
84
85
  "data-inset": inset || void 0,
85
86
  className: cn("px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8", className),
@@ -87,7 +88,7 @@ function ContextMenuLabel({ className, inset, ...props }) {
87
88
  });
88
89
  }
89
90
  function ContextMenuSeparator({ className, ...props }) {
90
- return /* @__PURE__ */ jsx(ContextMenu.Separator, {
91
+ return /* @__PURE__ */ jsx(Separator, {
91
92
  "data-slot": "context-menu-separator",
92
93
  className: cn("-mx-1 my-1 h-px bg-border", className),
93
94
  ...props
@@ -101,13 +102,13 @@ function ContextMenuShortcut({ className, ...props }) {
101
102
  });
102
103
  }
103
104
  function ContextMenuSub(props) {
104
- return /* @__PURE__ */ jsx(ContextMenu.Sub, {
105
+ return /* @__PURE__ */ jsx(Sub, {
105
106
  "data-slot": "context-menu-sub",
106
107
  ...props
107
108
  });
108
109
  }
109
110
  function ContextMenuSubTrigger({ className, inset, children, ...props }) {
110
- return /* @__PURE__ */ jsxs(ContextMenu.SubTrigger, {
111
+ return /* @__PURE__ */ jsxs(SubTrigger, {
111
112
  "data-slot": "context-menu-sub-trigger",
112
113
  "data-inset": inset || void 0,
113
114
  className: cn(menuItemClasses, "data-[state=open]:bg-secondary", className),
@@ -119,13 +120,13 @@ function ContextMenuSubTrigger({ className, inset, children, ...props }) {
119
120
  });
120
121
  }
121
122
  function ContextMenuSubContent({ className, ...props }) {
122
- return /* @__PURE__ */ jsx(ContextMenu.Portal, { children: /* @__PURE__ */ jsx(ContextMenu.SubContent, {
123
+ return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(SubContent, {
123
124
  "data-slot": "context-menu-sub-content",
124
125
  className: cn(surfaceClasses, "min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden p-1", className),
125
126
  ...props
126
127
  }) });
127
128
  }
128
129
  //#endregion
129
- export { ContextMenu$1 as ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger };
130
+ export { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger };
130
131
 
131
132
  //# sourceMappingURL=context-menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu.js","names":["ContextMenu","ContextMenuPrimitive","itemClasses"],"sources":["../../src/components/context-menu.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport { ContextMenu as ContextMenuPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { menuItemClasses as itemClasses, surfaceClasses } from './popover';\n\n/**\n * A right-click menu. Wrap the target in ContextMenuTrigger (use asChild to keep\n * your element); the menu opens at the pointer, and from the keyboard with the\n * context-menu key or Shift+F10 on the focused target. Same rows as\n * DropdownMenu, so a command can appear in both.\n */\nfunction ContextMenu(props: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger(props: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {\n return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />;\n}\n\nfunction ContextMenuGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nfunction ContextMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-content\"\n className={cn(\n surfaceClasses,\n 'max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1',\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nfunction ContextMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset || undefined}\n data-variant={variant}\n className={cn(\n itemClasses,\n 'data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(itemClasses, 'pl-8', className)}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <Check className=\"size-4 text-foreground\" aria-hidden />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction ContextMenuRadioGroup(\n props: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>,\n) {\n return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nfunction ContextMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <span className=\"block size-2 rounded-full bg-foreground\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nfunction ContextMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & { inset?: boolean }) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset || undefined}\n className={cn(\n 'px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSub(props: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nfunction ContextMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset || undefined}\n className={cn(itemClasses, 'data-[state=open]:bg-secondary', className)}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto size-4\" aria-hidden />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\nfunction ContextMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-content\"\n className={cn(\n surfaceClasses,\n 'min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden p-1',\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuGroup,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"context-menu.js","names":["ContextMenuPrimitive.Root","ContextMenuPrimitive.Trigger","ContextMenuPrimitive.Group","ContextMenuPrimitive.Portal","ContextMenuPrimitive.Content","ContextMenuPrimitive.Item","itemClasses","ContextMenuPrimitive.CheckboxItem","ContextMenuPrimitive.ItemIndicator","ContextMenuPrimitive.RadioGroup","ContextMenuPrimitive.RadioItem","ContextMenuPrimitive.Label","ContextMenuPrimitive.Separator","ContextMenuPrimitive.Sub","ContextMenuPrimitive.SubTrigger","ContextMenuPrimitive.SubContent"],"sources":["../../src/components/context-menu.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronRight from '@burtson-labs/icons/react/chevron-right';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as ContextMenuPrimitive from '../primitives/vendor/radix/react-context-menu';\n\nimport { menuItemClasses as itemClasses, surfaceClasses } from './popover';\n\n/**\n * A right-click menu. Wrap the target in ContextMenuTrigger (use asChild to keep\n * your element); the menu opens at the pointer, and from the keyboard with the\n * context-menu key or Shift+F10 on the focused target. Same rows as\n * DropdownMenu, so a command can appear in both.\n */\nfunction ContextMenu(props: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {\n return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger(props: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {\n return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" {...props} />;\n}\n\nfunction ContextMenuGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nfunction ContextMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.Content\n data-slot=\"context-menu-content\"\n className={cn(\n surfaceClasses,\n 'max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto p-1',\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nfunction ContextMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) {\n return (\n <ContextMenuPrimitive.Item\n data-slot=\"context-menu-item\"\n data-inset={inset || undefined}\n data-variant={variant}\n className={cn(\n itemClasses,\n 'data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:*:[svg]:!text-destructive',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {\n return (\n <ContextMenuPrimitive.CheckboxItem\n data-slot=\"context-menu-checkbox-item\"\n className={cn(itemClasses, 'pl-8', className)}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <Check className=\"size-4 text-foreground\" aria-hidden />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction ContextMenuRadioGroup(\n props: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>,\n) {\n return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nfunction ContextMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {\n return (\n <ContextMenuPrimitive.RadioItem\n data-slot=\"context-menu-radio-item\"\n className={cn(itemClasses, 'pl-8', className)}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <ContextMenuPrimitive.ItemIndicator>\n <span className=\"block size-2 rounded-full bg-foreground\" />\n </ContextMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </ContextMenuPrimitive.RadioItem>\n );\n}\n\nfunction ContextMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & { inset?: boolean }) {\n return (\n <ContextMenuPrimitive.Label\n data-slot=\"context-menu-label\"\n data-inset={inset || undefined}\n className={cn(\n 'px-2 pt-2 pb-1 text-[11px] font-semibold tracking-[0.08em] text-muted-foreground uppercase data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n return (\n <ContextMenuPrimitive.Separator\n data-slot=\"context-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction ContextMenuSub(props: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {\n return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nfunction ContextMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n return (\n <ContextMenuPrimitive.SubTrigger\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset || undefined}\n className={cn(itemClasses, 'data-[state=open]:bg-secondary', className)}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto size-4\" aria-hidden />\n </ContextMenuPrimitive.SubTrigger>\n );\n}\n\nfunction ContextMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {\n return (\n <ContextMenuPrimitive.Portal>\n <ContextMenuPrimitive.SubContent\n data-slot=\"context-menu-sub-content\"\n className={cn(\n surfaceClasses,\n 'min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden p-1',\n className,\n )}\n {...props}\n />\n </ContextMenuPrimitive.Portal>\n );\n}\n\nexport {\n ContextMenu,\n ContextMenuCheckboxItem,\n ContextMenuContent,\n ContextMenuGroup,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSeparator,\n ContextMenuShortcut,\n ContextMenuSub,\n ContextMenuSubContent,\n ContextMenuSubTrigger,\n ContextMenuTrigger,\n};\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import * as React from "react";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","names":[],"sources":["../../src/components/conversation.tsx"],"sourcesContent":["import ArrowDown from '@burtson-labs/icons/react/arrow-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport interface ConversationProps extends React.ComponentProps<'div'> {\n /** Shown instead of the messages when there are none. */\n empty?: React.ReactNode;\n /** Accessible name for the message log. */\n label?: string;\n}\n\n/**\n * A scrolling message log that stays pinned to the newest message while it\n * streams, unless the reader has scrolled up; then a \"Jump to latest\" button\n * appears instead of yanking them back down.\n */\nfunction Conversation({\n children,\n empty,\n label = 'Conversation',\n className,\n ...props\n}: ConversationProps) {\n const scroller = React.useRef<HTMLDivElement>(null);\n const content = React.useRef<HTMLDivElement>(null);\n const pinned = React.useRef(true);\n const [atBottom, setAtBottom] = React.useState(true);\n const hasMessages = React.Children.toArray(children).length > 0;\n\n const scrollToBottom = React.useCallback((behavior: ScrollBehavior = 'auto') => {\n const el = scroller.current;\n if (!el) return;\n if (typeof el.scrollTo === 'function') el.scrollTo({ top: el.scrollHeight, behavior });\n else el.scrollTop = el.scrollHeight;\n }, []);\n\n React.useEffect(() => {\n const el = content.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n // Content grows while a reply streams; follow it only if pinned.\n const ro = new ResizeObserver(() => {\n if (pinned.current) scrollToBottom();\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [scrollToBottom]);\n\n React.useEffect(() => {\n if (pinned.current) scrollToBottom();\n }, [children, scrollToBottom]);\n\n const onScroll = () => {\n const el = scroller.current;\n if (!el) return;\n const bottom = el.scrollHeight - el.scrollTop - el.clientHeight < 32;\n pinned.current = bottom;\n setAtBottom(bottom);\n };\n\n return (\n <div data-slot=\"conversation\" className={cn('relative min-h-0', className)} {...props}>\n <div\n ref={scroller}\n role=\"log\"\n aria-label={label}\n aria-live=\"polite\"\n aria-relevant=\"additions text\"\n // A scrollable region must be reachable by keyboard (WCAG 2.1.1).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={onScroll}\n className=\"size-full overflow-y-auto outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n <div ref={content} className=\"grid gap-5 p-4\">\n {hasMessages ? children : empty}\n </div>\n </div>\n {!atBottom && (\n <button\n type=\"button\"\n onClick={() => {\n pinned.current = true;\n setAtBottom(true);\n scrollToBottom(\n typeof matchMedia === 'function' &&\n matchMedia('(prefers-reduced-motion: reduce)').matches\n ? 'auto'\n : 'smooth',\n );\n }}\n className=\"absolute bottom-3 left-1/2 inline-flex -translate-x-1/2 animate-in items-center gap-1.5 rounded-full border border-border-strong bg-surface-raised px-3 py-1.5 text-xs font-semibold shadow-md outline-none hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20 [&_svg]:size-3.5\"\n >\n <ArrowDown aria-hidden /> Jump to latest\n </button>\n )}\n </div>\n );\n}\n\nexport { Conversation };\n"],"mappings":";;;;;;;;;;AAiBA,SAAS,aAAa,EACpB,UACA,OACA,QAAQ,gBACR,WACA,GAAG,SACiB;CACpB,MAAM,WAAW,MAAM,OAAuB,IAAI;CAClD,MAAM,UAAU,MAAM,OAAuB,IAAI;CACjD,MAAM,SAAS,MAAM,OAAO,IAAI;CAChC,MAAM,CAAC,UAAU,eAAe,MAAM,SAAS,IAAI;CACnD,MAAM,cAAc,MAAM,SAAS,QAAQ,QAAQ,CAAC,CAAC,SAAS;CAE9D,MAAM,iBAAiB,MAAM,aAAa,WAA2B,WAAW;EAC9E,MAAM,KAAK,SAAS;EACpB,IAAI,CAAC,IAAI;EACT,IAAI,OAAO,GAAG,aAAa,YAAY,GAAG,SAAS;GAAE,KAAK,GAAG;GAAc;EAAS,CAAC;OAChF,GAAG,YAAY,GAAG;CACzB,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB;EACpB,MAAM,KAAK,QAAQ;EACnB,IAAI,CAAC,MAAM,OAAO,mBAAmB,aAAa;EAElD,MAAM,KAAK,IAAI,qBAAqB;GAClC,IAAI,OAAO,SAAS,eAAe;EACrC,CAAC;EACD,GAAG,QAAQ,EAAE;EACb,aAAa,GAAG,WAAW;CAC7B,GAAG,CAAC,cAAc,CAAC;CAEnB,MAAM,gBAAgB;EACpB,IAAI,OAAO,SAAS,eAAe;CACrC,GAAG,CAAC,UAAU,cAAc,CAAC;CAE7B,MAAM,iBAAiB;EACrB,MAAM,KAAK,SAAS;EACpB,IAAI,CAAC,IAAI;EACT,MAAM,SAAS,GAAG,eAAe,GAAG,YAAY,GAAG,eAAe;EAClE,OAAO,UAAU;EACjB,YAAY,MAAM;CACpB;CAEA,OACE,qBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,oBAAoB,SAAS;EAAG,GAAI;EAAhF,UAAA,CACE,oBAAC,OAAD;GACE,KAAK;GACL,MAAK;GACL,cAAY;GACZ,aAAU;GACV,iBAAc;GAGd,UAAU;GACA;GACV,WAAU;GAEV,UAAA,oBAAC,OAAD;IAAK,KAAK;IAAS,WAAU;IAC1B,UAAA,cAAc,WAAW;GACvB,CAAA;EACF,CAAA,GACJ,CAAC,YACA,qBAAC,UAAD;GACE,MAAK;GACL,eAAe;IACb,OAAO,UAAU;IACjB,YAAY,IAAI;IAChB,eACE,OAAO,eAAe,cACpB,WAAW,kCAAkC,CAAC,CAAC,UAC7C,SACA,QACN;GACF;GACA,WAAU;GAZZ,UAAA,CAcE,oBAAC,WAAD,EAAW,eAAA,KAAa,CAAA,GAAC,iBACnB;EAEP,CAAA,CAAA;;AAET"}
1
+ {"version":3,"file":"conversation.js","names":[],"sources":["../../src/components/conversation.tsx"],"sourcesContent":["import ArrowDown from '@burtson-labs/icons/react/arrow-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport interface ConversationProps extends React.ComponentProps<'div'> {\n /** Shown instead of the messages when there are none. */\n empty?: React.ReactNode;\n /** Accessible name for the message log. */\n label?: string;\n}\n\n/**\n * A scrolling message log that stays pinned to the newest message while it\n * streams, unless the reader has scrolled up; then a \"Jump to latest\" button\n * appears instead of yanking them back down.\n */\nfunction Conversation({\n children,\n empty,\n label = 'Conversation',\n className,\n ...props\n}: ConversationProps) {\n const scroller = React.useRef<HTMLDivElement>(null);\n const content = React.useRef<HTMLDivElement>(null);\n const pinned = React.useRef(true);\n const [atBottom, setAtBottom] = React.useState(true);\n const hasMessages = React.Children.toArray(children).length > 0;\n\n const scrollToBottom = React.useCallback((behavior: ScrollBehavior = 'auto') => {\n const el = scroller.current;\n if (!el) return;\n if (typeof el.scrollTo === 'function') el.scrollTo({ top: el.scrollHeight, behavior });\n else el.scrollTop = el.scrollHeight;\n }, []);\n\n React.useEffect(() => {\n const el = content.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n // Content grows while a reply streams; follow it only if pinned.\n const ro = new ResizeObserver(() => {\n if (pinned.current) scrollToBottom();\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [scrollToBottom]);\n\n React.useEffect(() => {\n if (pinned.current) scrollToBottom();\n }, [children, scrollToBottom]);\n\n const onScroll = () => {\n const el = scroller.current;\n if (!el) return;\n const bottom = el.scrollHeight - el.scrollTop - el.clientHeight < 32;\n pinned.current = bottom;\n setAtBottom(bottom);\n };\n\n return (\n <div data-slot=\"conversation\" className={cn('relative min-h-0', className)} {...props}>\n <div\n ref={scroller}\n role=\"log\"\n aria-label={label}\n aria-live=\"polite\"\n aria-relevant=\"additions text\"\n // A scrollable region must be reachable by keyboard (WCAG 2.1.1).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={onScroll}\n className=\"size-full overflow-y-auto outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n <div ref={content} className=\"grid gap-5 p-4\">\n {hasMessages ? children : empty}\n </div>\n </div>\n {!atBottom && (\n <button\n type=\"button\"\n onClick={() => {\n pinned.current = true;\n setAtBottom(true);\n scrollToBottom(\n typeof matchMedia === 'function' &&\n matchMedia('(prefers-reduced-motion: reduce)').matches\n ? 'auto'\n : 'smooth',\n );\n }}\n className=\"absolute bottom-3 left-1/2 inline-flex -translate-x-1/2 animate-in items-center gap-1.5 rounded-full border border-border-strong bg-surface-raised px-3 py-1.5 text-xs font-semibold shadow-md outline-none hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20 [&_svg]:size-3.5\"\n >\n <ArrowDown aria-hidden /> Jump to latest\n </button>\n )}\n </div>\n );\n}\n\nexport { Conversation };\n"],"mappings":";;;;;;;;;;;AAiBA,SAAS,aAAa,EACpB,UACA,OACA,QAAQ,gBACR,WACA,GAAG,SACiB;CACpB,MAAM,WAAW,MAAM,OAAuB,IAAI;CAClD,MAAM,UAAU,MAAM,OAAuB,IAAI;CACjD,MAAM,SAAS,MAAM,OAAO,IAAI;CAChC,MAAM,CAAC,UAAU,eAAe,MAAM,SAAS,IAAI;CACnD,MAAM,cAAc,MAAM,SAAS,QAAQ,QAAQ,CAAC,CAAC,SAAS;CAE9D,MAAM,iBAAiB,MAAM,aAAa,WAA2B,WAAW;EAC9E,MAAM,KAAK,SAAS;EACpB,IAAI,CAAC,IAAI;EACT,IAAI,OAAO,GAAG,aAAa,YAAY,GAAG,SAAS;GAAE,KAAK,GAAG;GAAc;EAAS,CAAC;OAChF,GAAG,YAAY,GAAG;CACzB,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB;EACpB,MAAM,KAAK,QAAQ;EACnB,IAAI,CAAC,MAAM,OAAO,mBAAmB,aAAa;EAElD,MAAM,KAAK,IAAI,qBAAqB;GAClC,IAAI,OAAO,SAAS,eAAe;EACrC,CAAC;EACD,GAAG,QAAQ,EAAE;EACb,aAAa,GAAG,WAAW;CAC7B,GAAG,CAAC,cAAc,CAAC;CAEnB,MAAM,gBAAgB;EACpB,IAAI,OAAO,SAAS,eAAe;CACrC,GAAG,CAAC,UAAU,cAAc,CAAC;CAE7B,MAAM,iBAAiB;EACrB,MAAM,KAAK,SAAS;EACpB,IAAI,CAAC,IAAI;EACT,MAAM,SAAS,GAAG,eAAe,GAAG,YAAY,GAAG,eAAe;EAClE,OAAO,UAAU;EACjB,YAAY,MAAM;CACpB;CAEA,OACE,qBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,oBAAoB,SAAS;EAAG,GAAI;EAAhF,UAAA,CACE,oBAAC,OAAD;GACE,KAAK;GACL,MAAK;GACL,cAAY;GACZ,aAAU;GACV,iBAAc;GAGd,UAAU;GACA;GACV,WAAU;GAEV,UAAA,oBAAC,OAAD;IAAK,KAAK;IAAS,WAAU;IAC1B,UAAA,cAAc,WAAW;GACvB,CAAA;EACF,CAAA,GACJ,CAAC,YACA,qBAAC,UAAD;GACE,MAAK;GACL,eAAe;IACb,OAAO,UAAU;IACjB,YAAY,IAAI;IAChB,eACE,OAAO,eAAe,cACpB,WAAW,kCAAkC,CAAC,CAAC,UAC7C,SACA,QACN;GACF;GACA,WAAU;GAZZ,UAAA,CAcE,oBAAC,WAAD,EAAW,eAAA,KAAa,CAAA,GAAC,iBACnB;EAEP,CAAA,CAAA;;AAET"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { IconButton } from "./icon-button.js";
2
3
  import { toast } from "./toaster.js";
3
4
  import * as React from "react";
@@ -1 +1 @@
1
- {"version":3,"file":"copy-button.js","names":["_Fragment"],"sources":["../../src/components/copy-button.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport Copy from '@burtson-labs/icons/react/copy';\nimport * as React from 'react';\n\nimport { IconButton, type IconButtonProps } from './icon-button';\nimport { toast } from './toaster';\n\nexport interface CopyButtonProps extends Omit<IconButtonProps, 'label' | 'children' | 'onClick'> {\n /** The text to put on the clipboard. */\n value: string;\n /** Accessible name, e.g. \"Copy API key\". */\n label?: string;\n onCopySuccess?: () => void;\n onCopyError?: (error: unknown) => void;\n}\n\n/**\n * Icon button that copies `value` and shows a check for a moment. When the\n * browser blocks the clipboard it raises a toast (needs a mounted Toaster)\n * asking the person to copy by hand.\n */\nfunction CopyButton({\n value,\n label = 'Copy',\n variant = 'ghost',\n size = 'icon-sm',\n onCopySuccess,\n onCopyError,\n ...props\n}: CopyButtonProps) {\n const [message, setMessage] = React.useState('');\n const [copied, setCopied] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n React.useEffect(() => () => clearTimeout(timer.current), []);\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setMessage('Copied to clipboard.');\n onCopySuccess?.();\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setCopied(false), 1600);\n } catch (error) {\n setMessage('Copy blocked. Select the text and copy it manually.');\n onCopyError?.(error);\n toast({\n title: 'Copy blocked by the browser',\n description: 'Select the text and copy it by hand.',\n variant: 'destructive',\n });\n }\n };\n\n return (\n <>\n <IconButton\n data-slot=\"copy-button\"\n label={copied ? 'Copied' : label}\n variant={variant}\n size={size}\n onClick={() => void copy()}\n {...props}\n >\n {copied ? <Check aria-hidden className=\"text-success\" /> : <Copy aria-hidden />}\n </IconButton>\n <span role=\"status\" className=\"sr-only\">\n {message}\n </span>\n </>\n );\n}\n\nexport { CopyButton };\n"],"mappings":";;;;;;;;;;;;AAqBA,SAAS,WAAW,EAClB,OACA,QAAQ,QACR,UAAU,SACV,OAAO,WACP,eACA,aACA,GAAG,SACe;CAClB,MAAM,CAAC,SAAS,cAAc,MAAM,SAAS,EAAE;CAC/C,MAAM,CAAC,QAAQ,aAAa,MAAM,SAAS,KAAK;CAChD,MAAM,QAAQ,MAAM,OAAkD,KAAA,CAAS;CAC/E,MAAM,sBAAsB,aAAa,MAAM,OAAO,GAAG,CAAC,CAAC;CAE3D,MAAM,OAAO,YAAY;EACvB,IAAI;GACF,MAAM,UAAU,UAAU,UAAU,KAAK;GACzC,UAAU,IAAI;GACd,WAAW,sBAAsB;GACjC,gBAAgB;GAChB,aAAa,MAAM,OAAO;GAC1B,MAAM,UAAU,iBAAiB,UAAU,KAAK,GAAG,IAAI;EACzD,SAAS,OAAO;GACd,WAAW,qDAAqD;GAChE,cAAc,KAAK;GACnB,MAAM;IACJ,OAAO;IACP,aAAa;IACb,SAAS;GACX,CAAC;EACH;CACF;CAEA,OACE,qBAAAA,UAAA,EAAA,UAAA,CACE,oBAAC,YAAD;EACE,aAAU;EACV,OAAO,SAAS,WAAW;EAClB;EACH;EACN,eAAe,KAAK,KAAK;EACzB,GAAI;EAEH,UAAA,SAAS,oBAAC,OAAD;GAAO,eAAA;GAAY,WAAU;EAAgB,CAAA,IAAI,oBAAC,MAAD,EAAM,eAAA,KAAa,CAAA;CACpE,CAAA,GACZ,oBAAC,QAAD;EAAM,MAAK;EAAS,WAAU;EAC3B,UAAA;CACG,CAAA,CACN,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"copy-button.js","names":["_Fragment"],"sources":["../../src/components/copy-button.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport Copy from '@burtson-labs/icons/react/copy';\nimport * as React from 'react';\n\nimport { IconButton, type IconButtonProps } from './icon-button';\nimport { toast } from './toaster';\n\nexport interface CopyButtonProps extends Omit<IconButtonProps, 'label' | 'children' | 'onClick'> {\n /** The text to put on the clipboard. */\n value: string;\n /** Accessible name, e.g. \"Copy API key\". */\n label?: string;\n onCopySuccess?: () => void;\n onCopyError?: (error: unknown) => void;\n}\n\n/**\n * Icon button that copies `value` and shows a check for a moment. When the\n * browser blocks the clipboard it raises a toast (needs a mounted Toaster)\n * asking the person to copy by hand.\n */\nfunction CopyButton({\n value,\n label = 'Copy',\n variant = 'ghost',\n size = 'icon-sm',\n onCopySuccess,\n onCopyError,\n ...props\n}: CopyButtonProps) {\n const [message, setMessage] = React.useState('');\n const [copied, setCopied] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n React.useEffect(() => () => clearTimeout(timer.current), []);\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setMessage('Copied to clipboard.');\n onCopySuccess?.();\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setCopied(false), 1600);\n } catch (error) {\n setMessage('Copy blocked. Select the text and copy it manually.');\n onCopyError?.(error);\n toast({\n title: 'Copy blocked by the browser',\n description: 'Select the text and copy it by hand.',\n variant: 'destructive',\n });\n }\n };\n\n return (\n <>\n <IconButton\n data-slot=\"copy-button\"\n label={copied ? 'Copied' : label}\n variant={variant}\n size={size}\n onClick={() => void copy()}\n {...props}\n >\n {copied ? <Check aria-hidden className=\"text-success\" /> : <Copy aria-hidden />}\n </IconButton>\n <span role=\"status\" className=\"sr-only\">\n {message}\n </span>\n </>\n );\n}\n\nexport { CopyButton };\n"],"mappings":";;;;;;;;;;;;;AAqBA,SAAS,WAAW,EAClB,OACA,QAAQ,QACR,UAAU,SACV,OAAO,WACP,eACA,aACA,GAAG,SACe;CAClB,MAAM,CAAC,SAAS,cAAc,MAAM,SAAS,EAAE;CAC/C,MAAM,CAAC,QAAQ,aAAa,MAAM,SAAS,KAAK;CAChD,MAAM,QAAQ,MAAM,OAAkD,KAAA,CAAS;CAC/E,MAAM,sBAAsB,aAAa,MAAM,OAAO,GAAG,CAAC,CAAC;CAE3D,MAAM,OAAO,YAAY;EACvB,IAAI;GACF,MAAM,UAAU,UAAU,UAAU,KAAK;GACzC,UAAU,IAAI;GACd,WAAW,sBAAsB;GACjC,gBAAgB;GAChB,aAAa,MAAM,OAAO;GAC1B,MAAM,UAAU,iBAAiB,UAAU,KAAK,GAAG,IAAI;EACzD,SAAS,OAAO;GACd,WAAW,qDAAqD;GAChE,cAAc,KAAK;GACnB,MAAM;IACJ,OAAO;IACP,aAAa;IACb,SAAS;GACX,CAAC;EACH;CACF;CAEA,OACE,qBAAAA,UAAA,EAAA,UAAA,CACE,oBAAC,YAAD;EACE,aAAU;EACV,OAAO,SAAS,WAAW;EAClB;EACH;EACN,eAAe,KAAK,KAAK;EACzB,GAAI;EAEH,UAAA,SAAS,oBAAC,OAAD;GAAO,eAAA;GAAY,WAAU;EAAgB,CAAA,IAAI,oBAAC,MAAD,EAAM,eAAA,KAAa,CAAA;CACpE,CAAA,GACZ,oBAAC,QAAD;EAAM,MAAK;EAAS,WAAU;EAC3B,UAAA;CACG,CAAA,CACN,EAAA,CAAA;AAEN"}
@@ -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 { Input } from "./input.js";
@@ -375,6 +376,7 @@ function ErrorMessage({ error, onRetry }) {
375
376
  });
376
377
  }
377
378
  var cardLabelClass = "text-[11px] font-semibold tracking-[0.06em] text-muted-foreground uppercase";
379
+ var liftControls = "[&_a]:relative [&_a]:z-10 [&_button]:relative [&_button]:z-10 [&_input]:relative [&_input]:z-10 [&_select]:relative [&_select]:z-10 [&_textarea]:relative [&_textarea]:z-10";
378
380
  /**
379
381
  * The phone layout: a list of articles, one per row, each named by its title.
380
382
  * The title is the row's open button (its hit area covers the card); the
@@ -464,14 +466,14 @@ function DataTableCards({ "aria-label": ariaLabel, columns, rows, getRowId, getR
464
466
  ]
465
467
  }),
466
468
  subtitle.length > 0 && /* @__PURE__ */ jsx("div", {
467
- className: cn("-mt-2 grid min-w-0 gap-0.5", onToggle && "pl-7"),
469
+ className: cn("-mt-2 grid min-w-0 gap-0.5", liftControls, onToggle && "pl-7"),
468
470
  children: subtitle.map((c) => /* @__PURE__ */ jsx("div", {
469
471
  className: "min-w-0 text-sm text-muted-foreground [overflow-wrap:anywhere]",
470
472
  children: show(c, row)
471
473
  }, c.id))
472
474
  }),
473
475
  fields.length > 0 && /* @__PURE__ */ jsx("dl", {
474
- className: "grid grid-cols-2 gap-x-4 gap-y-2.5 text-sm",
476
+ className: cn("grid grid-cols-2 gap-x-4 gap-y-2.5 text-sm", liftControls),
475
477
  children: fields.map((c) => /* @__PURE__ */ jsxs("div", {
476
478
  className: "min-w-0",
477
479
  children: [/* @__PURE__ */ jsx("dt", {