@burtson-labs/ui 0.13.1 → 0.14.1

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 (460) 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 +20 -12
  7. package/THIRD_PARTY_NOTICES.md +15 -3
  8. package/dist/components/accordion.d.ts +4 -4
  9. package/dist/components/accordion.js +22 -18
  10. package/dist/components/accordion.js.map +1 -1
  11. package/dist/components/alert-dialog.d.ts +13 -11
  12. package/dist/components/alert-dialog.js +41 -31
  13. package/dist/components/alert-dialog.js.map +1 -1
  14. package/dist/components/alert.d.ts +5 -3
  15. package/dist/components/alert.js +12 -7
  16. package/dist/components/alert.js.map +1 -1
  17. package/dist/components/app-shell.d.ts +7 -6
  18. package/dist/components/app-shell.js +22 -14
  19. package/dist/components/app-shell.js.map +1 -1
  20. package/dist/components/attachment.d.ts +3 -3
  21. package/dist/components/attachment.js +11 -7
  22. package/dist/components/attachment.js.map +1 -1
  23. package/dist/components/audio-player.d.ts +2 -2
  24. package/dist/components/audio-player.js +9 -6
  25. package/dist/components/audio-player.js.map +1 -1
  26. package/dist/components/avatar.d.ts +4 -4
  27. package/dist/components/avatar.js +16 -12
  28. package/dist/components/avatar.js.map +1 -1
  29. package/dist/components/badge.d.ts +1 -1
  30. package/dist/components/badge.js +15 -13
  31. package/dist/components/badge.js.map +1 -1
  32. package/dist/components/breadcrumb.d.ts +8 -8
  33. package/dist/components/breadcrumb.js +27 -20
  34. package/dist/components/breadcrumb.js.map +1 -1
  35. package/dist/components/button.d.ts +9 -2
  36. package/dist/components/button.js +15 -6
  37. package/dist/components/button.js.map +1 -1
  38. package/dist/components/card.d.ts +9 -9
  39. package/dist/components/card.js +33 -23
  40. package/dist/components/card.js.map +1 -1
  41. package/dist/components/chat-history.d.ts +1 -1
  42. package/dist/components/chat-history.js +11 -9
  43. package/dist/components/chat-history.js.map +1 -1
  44. package/dist/components/chat-layout.d.ts +1 -1
  45. package/dist/components/chat-layout.js +8 -3
  46. package/dist/components/chat-layout.js.map +1 -1
  47. package/dist/components/checkbox-card.d.ts +3 -3
  48. package/dist/components/checkbox-card.js +12 -10
  49. package/dist/components/checkbox-card.js.map +1 -1
  50. package/dist/components/checkbox.d.ts +24 -3
  51. package/dist/components/checkbox.js +52 -9
  52. package/dist/components/checkbox.js.map +1 -1
  53. package/dist/components/collapsible.d.ts +3 -3
  54. package/dist/components/collapsible.js +14 -11
  55. package/dist/components/collapsible.js.map +1 -1
  56. package/dist/components/combobox.d.ts +14 -4
  57. package/dist/components/combobox.js +19 -8
  58. package/dist/components/combobox.js.map +1 -1
  59. package/dist/components/command.d.ts +68 -12
  60. package/dist/components/command.js +48 -34
  61. package/dist/components/command.js.map +1 -1
  62. package/dist/components/composer.d.ts +2 -2
  63. package/dist/components/composer.js +10 -7
  64. package/dist/components/composer.js.map +1 -1
  65. package/dist/components/connection-status.d.ts +3 -3
  66. package/dist/components/connection-status.js +19 -14
  67. package/dist/components/connection-status.js.map +1 -1
  68. package/dist/components/context-menu.d.ts +15 -14
  69. package/dist/components/context-menu.js +52 -41
  70. package/dist/components/context-menu.js.map +1 -1
  71. package/dist/components/conversation.d.ts +1 -1
  72. package/dist/components/conversation.js +7 -5
  73. package/dist/components/conversation.js.map +1 -1
  74. package/dist/components/copy-button.d.ts +1 -1
  75. package/dist/components/copy-button.js +4 -2
  76. package/dist/components/copy-button.js.map +1 -1
  77. package/dist/components/data-table.d.ts +7 -2
  78. package/dist/components/data-table.js +17 -42
  79. package/dist/components/data-table.js.map +1 -1
  80. package/dist/components/dialog.d.ts +19 -10
  81. package/dist/components/dialog.js +50 -33
  82. package/dist/components/dialog.js.map +1 -1
  83. package/dist/components/dropdown-menu.d.ts +15 -14
  84. package/dist/components/dropdown-menu.js +52 -41
  85. package/dist/components/dropdown-menu.js.map +1 -1
  86. package/dist/components/editor-tabs.d.ts +1 -1
  87. package/dist/components/editor-tabs.js +7 -5
  88. package/dist/components/editor-tabs.js.map +1 -1
  89. package/dist/components/empty-state.d.ts +5 -5
  90. package/dist/components/empty-state.js +17 -11
  91. package/dist/components/empty-state.js.map +1 -1
  92. package/dist/components/error-summary.d.ts +21 -0
  93. package/dist/components/error-summary.js +62 -0
  94. package/dist/components/error-summary.js.map +1 -0
  95. package/dist/components/field.d.ts +66 -7
  96. package/dist/components/field.js +152 -20
  97. package/dist/components/field.js.map +1 -1
  98. package/dist/components/form-actions.d.ts +18 -0
  99. package/dist/components/form-actions.js +30 -0
  100. package/dist/components/form-actions.js.map +1 -0
  101. package/dist/components/icon-button.d.ts +3 -1
  102. package/dist/components/icon-button.js +6 -3
  103. package/dist/components/icon-button.js.map +1 -1
  104. package/dist/components/input.d.ts +42 -7
  105. package/dist/components/input.js +54 -10
  106. package/dist/components/input.js.map +1 -1
  107. package/dist/components/kbd.d.ts +2 -2
  108. package/dist/components/kbd.js +8 -5
  109. package/dist/components/kbd.js.map +1 -1
  110. package/dist/components/label.d.ts +7 -2
  111. package/dist/components/label.js +14 -7
  112. package/dist/components/label.js.map +1 -1
  113. package/dist/components/markdown.d.ts +4 -3
  114. package/dist/components/markdown.js +8 -6
  115. package/dist/components/markdown.js.map +1 -1
  116. package/dist/components/menubar.d.ts +17 -15
  117. package/dist/components/menubar.js +58 -45
  118. package/dist/components/menubar.js.map +1 -1
  119. package/dist/components/message-actions.d.ts +3 -3
  120. package/dist/components/message-actions.js +16 -12
  121. package/dist/components/message-actions.js.map +1 -1
  122. package/dist/components/message.d.ts +1 -1
  123. package/dist/components/message.js +6 -3
  124. package/dist/components/message.js.map +1 -1
  125. package/dist/components/mobile-nav.d.ts +1 -1
  126. package/dist/components/mobile-nav.js +7 -5
  127. package/dist/components/mobile-nav.js.map +1 -1
  128. package/dist/components/native-select.d.ts +16 -0
  129. package/dist/components/native-select.js +33 -0
  130. package/dist/components/native-select.js.map +1 -0
  131. package/dist/components/navigation-menu.d.ts +13 -12
  132. package/dist/components/navigation-menu.js +43 -33
  133. package/dist/components/navigation-menu.js.map +1 -1
  134. package/dist/components/number-input.d.ts +23 -0
  135. package/dist/components/number-input.js +45 -0
  136. package/dist/components/number-input.js.map +1 -0
  137. package/dist/components/onboarding-checklist.d.ts +1 -1
  138. package/dist/components/onboarding-checklist.js +5 -3
  139. package/dist/components/onboarding-checklist.js.map +1 -1
  140. package/dist/components/page-header.d.ts +7 -6
  141. package/dist/components/page-header.js +23 -15
  142. package/dist/components/page-header.js.map +1 -1
  143. package/dist/components/pagination.d.ts +1 -1
  144. package/dist/components/pagination.js +4 -2
  145. package/dist/components/pagination.js.map +1 -1
  146. package/dist/components/popover.d.ts +14 -11
  147. package/dist/components/popover.js +30 -23
  148. package/dist/components/popover.js.map +1 -1
  149. package/dist/components/progress.d.ts +2 -2
  150. package/dist/components/progress.js +11 -9
  151. package/dist/components/progress.js.map +1 -1
  152. package/dist/components/radio-group.d.ts +23 -4
  153. package/dist/components/radio-group.js +56 -14
  154. package/dist/components/radio-group.js.map +1 -1
  155. package/dist/components/reasoning.d.ts +3 -3
  156. package/dist/components/reasoning.js +14 -11
  157. package/dist/components/reasoning.js.map +1 -1
  158. package/dist/components/resizable.js +1 -0
  159. package/dist/components/resizable.js.map +1 -1
  160. package/dist/components/scroll-area.d.ts +4 -3
  161. package/dist/components/scroll-area.js +18 -14
  162. package/dist/components/scroll-area.js.map +1 -1
  163. package/dist/components/secret-input.d.ts +3 -2
  164. package/dist/components/secret-input.js +7 -4
  165. package/dist/components/secret-input.js.map +1 -1
  166. package/dist/components/select.d.ts +12 -7
  167. package/dist/components/select.js +42 -35
  168. package/dist/components/select.js.map +1 -1
  169. package/dist/components/separator.d.ts +2 -2
  170. package/dist/components/separator.js +8 -6
  171. package/dist/components/separator.js.map +1 -1
  172. package/dist/components/sheet.d.ts +11 -9
  173. package/dist/components/sheet.js +41 -29
  174. package/dist/components/sheet.js.map +1 -1
  175. package/dist/components/skeleton.d.ts +2 -1
  176. package/dist/components/skeleton.js +7 -4
  177. package/dist/components/skeleton.js.map +1 -1
  178. package/dist/components/slider.d.ts +10 -6
  179. package/dist/components/slider.js +16 -7
  180. package/dist/components/slider.js.map +1 -1
  181. package/dist/components/source.d.ts +2 -2
  182. package/dist/components/source.js +10 -7
  183. package/dist/components/source.js.map +1 -1
  184. package/dist/components/spinner.d.ts +4 -2
  185. package/dist/components/spinner.js +5 -3
  186. package/dist/components/spinner.js.map +1 -1
  187. package/dist/components/stat-card.d.ts +27 -2
  188. package/dist/components/stat-card.js +70 -9
  189. package/dist/components/stat-card.js.map +1 -1
  190. package/dist/components/status.d.ts +7 -6
  191. package/dist/components/status.js +12 -5
  192. package/dist/components/status.js.map +1 -1
  193. package/dist/components/steps.d.ts +1 -1
  194. package/dist/components/steps.js +5 -3
  195. package/dist/components/steps.js.map +1 -1
  196. package/dist/components/switch.d.ts +47 -3
  197. package/dist/components/switch.js +89 -11
  198. package/dist/components/switch.js.map +1 -1
  199. package/dist/components/table.d.ts +29 -12
  200. package/dist/components/table.js +80 -34
  201. package/dist/components/table.js.map +1 -1
  202. package/dist/components/tabs.d.ts +10 -5
  203. package/dist/components/tabs.js +29 -19
  204. package/dist/components/tabs.js.map +1 -1
  205. package/dist/components/textarea.d.ts +6 -1
  206. package/dist/components/textarea.js +4 -3
  207. package/dist/components/textarea.js.map +1 -1
  208. package/dist/components/toast.d.ts +11 -7
  209. package/dist/components/toast.js +37 -27
  210. package/dist/components/toast.js.map +1 -1
  211. package/dist/components/toaster.d.ts +4 -2
  212. package/dist/components/toaster.js +7 -2
  213. package/dist/components/toaster.js.map +1 -1
  214. package/dist/components/tool-call.d.ts +2 -2
  215. package/dist/components/tool-call.js +15 -12
  216. package/dist/components/tool-call.js.map +1 -1
  217. package/dist/components/toolbar.d.ts +9 -4
  218. package/dist/components/toolbar.js +15 -9
  219. package/dist/components/toolbar.js.map +1 -1
  220. package/dist/components/tooltip.d.ts +4 -3
  221. package/dist/components/tooltip.js +17 -13
  222. package/dist/components/tooltip.js.map +1 -1
  223. package/dist/components/tour.js +10 -8
  224. package/dist/components/tour.js.map +1 -1
  225. package/dist/components/tree-view.d.ts +1 -1
  226. package/dist/components/tree-view.js +10 -5
  227. package/dist/components/tree-view.js.map +1 -1
  228. package/dist/components/voice-recorder.d.ts +1 -1
  229. package/dist/components/voice-recorder.js +5 -2
  230. package/dist/components/voice-recorder.js.map +1 -1
  231. package/dist/index.d.ts +6 -1
  232. package/dist/index.js +17 -12
  233. package/dist/lib/media.d.ts +18 -0
  234. package/dist/lib/media.js +34 -0
  235. package/dist/lib/media.js.map +1 -0
  236. package/dist/lib/utils.d.ts +32 -0
  237. package/dist/lib/utils.js +33 -1
  238. package/dist/lib/utils.js.map +1 -1
  239. package/dist/mui/index.js +20 -8
  240. package/dist/mui/index.js.map +1 -1
  241. package/dist/primitives/vendor/cmdk/command-score.d.ts +1 -0
  242. package/dist/primitives/vendor/cmdk/command-score.js +64 -0
  243. package/dist/primitives/vendor/cmdk/command-score.js.map +1 -0
  244. package/dist/primitives/vendor/cmdk/index.d.ts +384 -0
  245. package/dist/primitives/vendor/cmdk/index.js +687 -0
  246. package/dist/primitives/vendor/cmdk/index.js.map +1 -0
  247. package/dist/primitives/vendor/radix/number/index.d.ts +1 -0
  248. package/dist/primitives/vendor/radix/number/number.d.ts +2 -0
  249. package/dist/primitives/vendor/radix/number/number.js +9 -0
  250. package/dist/primitives/vendor/radix/number/number.js.map +1 -0
  251. package/dist/primitives/vendor/radix/primitive/index.d.ts +2 -0
  252. package/dist/primitives/vendor/radix/primitive/is-development.d.ts +1 -0
  253. package/dist/primitives/vendor/radix/primitive/is-development.js +7 -0
  254. package/dist/primitives/vendor/radix/primitive/is-development.js.map +1 -0
  255. package/dist/primitives/vendor/radix/primitive/primitive.d.ts +14 -0
  256. package/dist/primitives/vendor/radix/primitive/primitive.js +12 -0
  257. package/dist/primitives/vendor/radix/primitive/primitive.js.map +1 -0
  258. package/dist/primitives/vendor/radix/primitive/types.d.ts +5 -0
  259. package/dist/primitives/vendor/radix/react-accordion/accordion.d.ts +112 -0
  260. package/dist/primitives/vendor/radix/react-accordion/accordion.js +266 -0
  261. package/dist/primitives/vendor/radix/react-accordion/accordion.js.map +1 -0
  262. package/dist/primitives/vendor/radix/react-accordion/index.d.ts +2 -0
  263. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.d.ts +49 -0
  264. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js +122 -0
  265. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js.map +1 -0
  266. package/dist/primitives/vendor/radix/react-alert-dialog/index.d.ts +2 -0
  267. package/dist/primitives/vendor/radix/react-arrow/arrow.d.ts +9 -0
  268. package/dist/primitives/vendor/radix/react-arrow/arrow.js +22 -0
  269. package/dist/primitives/vendor/radix/react-arrow/arrow.js.map +1 -0
  270. package/dist/primitives/vendor/radix/react-arrow/index.d.ts +2 -0
  271. package/dist/primitives/vendor/radix/react-avatar/avatar.d.ts +19 -0
  272. package/dist/primitives/vendor/radix/react-avatar/avatar.js +132 -0
  273. package/dist/primitives/vendor/radix/react-avatar/avatar.js.map +1 -0
  274. package/dist/primitives/vendor/radix/react-avatar/index.d.ts +2 -0
  275. package/dist/primitives/vendor/radix/react-checkbox/checkbox.d.ts +47 -0
  276. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js +197 -0
  277. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js.map +1 -0
  278. package/dist/primitives/vendor/radix/react-checkbox/index.d.ts +2 -0
  279. package/dist/primitives/vendor/radix/react-collapsible/collapsible.d.ts +31 -0
  280. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js +133 -0
  281. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js.map +1 -0
  282. package/dist/primitives/vendor/radix/react-collapsible/index.d.ts +2 -0
  283. package/dist/primitives/vendor/radix/react-collection/collection-legacy.d.ts +21 -0
  284. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js +84 -0
  285. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js.map +1 -0
  286. package/dist/primitives/vendor/radix/react-collection/collection.d.ts +32 -0
  287. package/dist/primitives/vendor/radix/react-collection/index.d.ts +4 -0
  288. package/dist/primitives/vendor/radix/react-collection/ordered-dictionary.d.ts +51 -0
  289. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.d.ts +13 -0
  290. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js +43 -0
  291. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js.map +1 -0
  292. package/dist/primitives/vendor/radix/react-compose-refs/index.d.ts +1 -0
  293. package/dist/primitives/vendor/radix/react-context/create-context.d.ts +45 -0
  294. package/dist/primitives/vendor/radix/react-context/create-context.js +74 -0
  295. package/dist/primitives/vendor/radix/react-context/create-context.js.map +1 -0
  296. package/dist/primitives/vendor/radix/react-context/index.d.ts +2 -0
  297. package/dist/primitives/vendor/radix/react-context-menu/context-menu.d.ts +95 -0
  298. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js +279 -0
  299. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js.map +1 -0
  300. package/dist/primitives/vendor/radix/react-context-menu/index.d.ts +2 -0
  301. package/dist/primitives/vendor/radix/react-dialog/dialog.d.ts +97 -0
  302. package/dist/primitives/vendor/radix/react-dialog/dialog.js +262 -0
  303. package/dist/primitives/vendor/radix/react-dialog/dialog.js.map +1 -0
  304. package/dist/primitives/vendor/radix/react-dialog/index.d.ts +4 -0
  305. package/dist/primitives/vendor/radix/react-direction/direction.d.ts +10 -0
  306. package/dist/primitives/vendor/radix/react-direction/direction.js +13 -0
  307. package/dist/primitives/vendor/radix/react-direction/direction.js.map +1 -0
  308. package/dist/primitives/vendor/radix/react-direction/index.d.ts +1 -0
  309. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.d.ts +61 -0
  310. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js +336 -0
  311. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js.map +1 -0
  312. package/dist/primitives/vendor/radix/react-dismissable-layer/index.d.ts +4 -0
  313. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.d.ts +95 -0
  314. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js +257 -0
  315. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js.map +1 -0
  316. package/dist/primitives/vendor/radix/react-dropdown-menu/index.d.ts +2 -0
  317. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.d.ts +11 -0
  318. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js +49 -0
  319. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js.map +1 -0
  320. package/dist/primitives/vendor/radix/react-focus-guards/index.d.ts +1 -0
  321. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.d.ts +31 -0
  322. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js +221 -0
  323. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js.map +1 -0
  324. package/dist/primitives/vendor/radix/react-focus-scope/index.d.ts +1 -0
  325. package/dist/primitives/vendor/radix/react-id/id.d.ts +2 -0
  326. package/dist/primitives/vendor/radix/react-id/id.js +17 -0
  327. package/dist/primitives/vendor/radix/react-id/id.js.map +1 -0
  328. package/dist/primitives/vendor/radix/react-id/index.d.ts +1 -0
  329. package/dist/primitives/vendor/radix/react-label/index.d.ts +2 -0
  330. package/dist/primitives/vendor/radix/react-label/label.d.ts +9 -0
  331. package/dist/primitives/vendor/radix/react-label/label.js +21 -0
  332. package/dist/primitives/vendor/radix/react-label/label.js.map +1 -0
  333. package/dist/primitives/vendor/radix/react-menu/index.d.ts +2 -0
  334. package/dist/primitives/vendor/radix/react-menu/menu.d.ts +173 -0
  335. package/dist/primitives/vendor/radix/react-menu/menu.js +806 -0
  336. package/dist/primitives/vendor/radix/react-menu/menu.js.map +1 -0
  337. package/dist/primitives/vendor/radix/react-menubar/index.d.ts +2 -0
  338. package/dist/primitives/vendor/radix/react-menubar/menubar.d.ts +106 -0
  339. package/dist/primitives/vendor/radix/react-menubar/menubar.js +377 -0
  340. package/dist/primitives/vendor/radix/react-menubar/menubar.js.map +1 -0
  341. package/dist/primitives/vendor/radix/react-navigation-menu/index.d.ts +2 -0
  342. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.d.ts +124 -0
  343. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js +743 -0
  344. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js.map +1 -0
  345. package/dist/primitives/vendor/radix/react-popover/index.d.ts +1 -0
  346. package/dist/primitives/vendor/radix/react-popover/popover.d.ts +83 -0
  347. package/dist/primitives/vendor/radix/react-popover/popover.js +236 -0
  348. package/dist/primitives/vendor/radix/react-popover/popover.js.map +1 -0
  349. package/dist/primitives/vendor/radix/react-popper/index.d.ts +2 -0
  350. package/dist/primitives/vendor/radix/react-popper/popper.d.ts +44 -0
  351. package/dist/primitives/vendor/radix/react-popper/popper.js +276 -0
  352. package/dist/primitives/vendor/radix/react-popper/popper.js.map +1 -0
  353. package/dist/primitives/vendor/radix/react-portal/index.d.ts +2 -0
  354. package/dist/primitives/vendor/radix/react-portal/portal.d.ts +13 -0
  355. package/dist/primitives/vendor/radix/react-portal/portal.js +21 -0
  356. package/dist/primitives/vendor/radix/react-portal/portal.js.map +1 -0
  357. package/dist/primitives/vendor/radix/react-presence/index.d.ts +2 -0
  358. package/dist/primitives/vendor/radix/react-presence/presence.d.ts +11 -0
  359. package/dist/primitives/vendor/radix/react-presence/presence.js +152 -0
  360. package/dist/primitives/vendor/radix/react-presence/presence.js.map +1 -0
  361. package/dist/primitives/vendor/radix/react-presence/use-state-machine.d.ts +10 -0
  362. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js +12 -0
  363. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js.map +1 -0
  364. package/dist/primitives/vendor/radix/react-primitive/index.d.ts +2 -0
  365. package/dist/primitives/vendor/radix/react-primitive/primitive.d.ts +56 -0
  366. package/dist/primitives/vendor/radix/react-primitive/primitive.js +84 -0
  367. package/dist/primitives/vendor/radix/react-primitive/primitive.js.map +1 -0
  368. package/dist/primitives/vendor/radix/react-progress/index.d.ts +2 -0
  369. package/dist/primitives/vendor/radix/react-progress/progress.d.ts +17 -0
  370. package/dist/primitives/vendor/radix/react-progress/progress.js +79 -0
  371. package/dist/primitives/vendor/radix/react-progress/progress.js.map +1 -0
  372. package/dist/primitives/vendor/radix/react-radio-group/index.d.ts +2 -0
  373. package/dist/primitives/vendor/radix/react-radio-group/radio-group.d.ts +55 -0
  374. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js +173 -0
  375. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js.map +1 -0
  376. package/dist/primitives/vendor/radix/react-radio-group/radio.d.ts +62 -0
  377. package/dist/primitives/vendor/radix/react-radio-group/radio.js +150 -0
  378. package/dist/primitives/vendor/radix/react-radio-group/radio.js.map +1 -0
  379. package/dist/primitives/vendor/radix/react-roving-focus/index.d.ts +2 -0
  380. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.d.ts +47 -0
  381. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js +218 -0
  382. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js.map +1 -0
  383. package/dist/primitives/vendor/radix/react-scroll-area/index.d.ts +2 -0
  384. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.d.ts +121 -0
  385. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js +713 -0
  386. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js.map +1 -0
  387. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.d.ts +10 -0
  388. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js +12 -0
  389. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js.map +1 -0
  390. package/dist/primitives/vendor/radix/react-select/index.d.ts +2 -0
  391. package/dist/primitives/vendor/radix/react-select/select.d.ts +163 -0
  392. package/dist/primitives/vendor/radix/react-select/select.js +1040 -0
  393. package/dist/primitives/vendor/radix/react-select/select.js.map +1 -0
  394. package/dist/primitives/vendor/radix/react-separator/index.d.ts +2 -0
  395. package/dist/primitives/vendor/radix/react-separator/separator.d.ts +20 -0
  396. package/dist/primitives/vendor/radix/react-separator/separator.js +29 -0
  397. package/dist/primitives/vendor/radix/react-separator/separator.js.map +1 -0
  398. package/dist/primitives/vendor/radix/react-slot/index.d.ts +1 -0
  399. package/dist/primitives/vendor/radix/react-slot/slot.d.ts +29 -0
  400. package/dist/primitives/vendor/radix/react-slot/slot.js +107 -0
  401. package/dist/primitives/vendor/radix/react-slot/slot.js.map +1 -0
  402. package/dist/primitives/vendor/radix/react-switch/index.d.ts +2 -0
  403. package/dist/primitives/vendor/radix/react-switch/switch.d.ts +41 -0
  404. package/dist/primitives/vendor/radix/react-switch/switch.js +185 -0
  405. package/dist/primitives/vendor/radix/react-switch/switch.js.map +1 -0
  406. package/dist/primitives/vendor/radix/react-tabs/index.d.ts +2 -0
  407. package/dist/primitives/vendor/radix/react-tabs/tabs.d.ts +54 -0
  408. package/dist/primitives/vendor/radix/react-tabs/tabs.js +145 -0
  409. package/dist/primitives/vendor/radix/react-tabs/tabs.js.map +1 -0
  410. package/dist/primitives/vendor/radix/react-toast/index.d.ts +2 -0
  411. package/dist/primitives/vendor/radix/react-toast/toast.d.ts +125 -0
  412. package/dist/primitives/vendor/radix/react-toast/toast.js +557 -0
  413. package/dist/primitives/vendor/radix/react-toast/toast.js.map +1 -0
  414. package/dist/primitives/vendor/radix/react-tooltip/index.d.ts +2 -0
  415. package/dist/primitives/vendor/radix/react-tooltip/tooltip.d.ts +99 -0
  416. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js +503 -0
  417. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js.map +1 -0
  418. package/dist/primitives/vendor/radix/react-use-callback-ref/index.d.ts +1 -0
  419. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.d.ts +6 -0
  420. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js +18 -0
  421. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js.map +1 -0
  422. package/dist/primitives/vendor/radix/react-use-controllable-state/index.d.ts +2 -0
  423. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state-reducer.d.ts +28 -0
  424. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.d.ts +11 -0
  425. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js +59 -0
  426. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js.map +1 -0
  427. package/dist/primitives/vendor/radix/react-use-effect-event/index.d.ts +1 -0
  428. package/dist/primitives/vendor/radix/react-use-effect-event/use-effect-event.d.ts +7 -0
  429. package/dist/primitives/vendor/radix/react-use-is-hydrated/index.d.ts +1 -0
  430. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.d.ts +1 -0
  431. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js +18 -0
  432. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js.map +1 -0
  433. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.d.ts +6 -0
  434. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js +19 -0
  435. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js.map +1 -0
  436. package/dist/primitives/vendor/radix/react-use-layout-effect/index.d.ts +1 -0
  437. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.d.ts +10 -0
  438. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js +15 -0
  439. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js.map +1 -0
  440. package/dist/primitives/vendor/radix/react-use-previous/index.d.ts +1 -0
  441. package/dist/primitives/vendor/radix/react-use-previous/use-previous.d.ts +2 -0
  442. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js +20 -0
  443. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js.map +1 -0
  444. package/dist/primitives/vendor/radix/react-use-size/index.d.ts +1 -0
  445. package/dist/primitives/vendor/radix/react-use-size/use-size.d.ts +5 -0
  446. package/dist/primitives/vendor/radix/react-use-size/use-size.js +42 -0
  447. package/dist/primitives/vendor/radix/react-use-size/use-size.js.map +1 -0
  448. package/dist/primitives/vendor/radix/react-visually-hidden/index.d.ts +2 -0
  449. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.d.ts +21 -0
  450. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js +32 -0
  451. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js.map +1 -0
  452. package/dist/primitives/vendor/radix/rect/index.d.ts +2 -0
  453. package/dist/primitives/vendor/radix/rect/observe-element-rect.d.ts +16 -0
  454. package/dist/styles.css +1 -1
  455. package/dist/theme.css +36 -17
  456. package/dist/tokens.d.ts +78 -36
  457. package/dist/tokens.js +63 -32
  458. package/dist/tokens.js.map +1 -1
  459. package/package.json +25 -13
  460. package/vendor-manifest.json +1101 -0
@@ -1,16 +1,26 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { Spinner } from "./spinner.js";
3
4
  import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
4
- import { fieldClasses } from "./input.js";
5
+ import { fieldClasses, fieldWidthClasses } from "./input.js";
5
6
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./command.js";
6
7
  import * as React from "react";
7
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
9
  import Check from "@burtson-labs/icons/react/check";
9
10
  import ChevronsUpDown from "@burtson-labs/icons/react/chevrons-up-down";
10
11
  //#region src/components/combobox.tsx
11
- /** Pick one value from a long or remote list by typing. */
12
- function Combobox({ options, value, onValueChange, placeholder = "Select…", searchPlaceholder = "Search…", emptyText = "No matches.", disabled, loading, onSearchChange, clearable = true, id, className, name, required, ...aria }) {
12
+ /**
13
+ * Pick one value from a long or remote list by typing. The ref reaches the
14
+ * trigger button, so a form library or an ErrorSummary can focus it.
15
+ */
16
+ var Combobox = React.forwardRef(function Combobox({ options, value: valueProp, defaultValue = null, onValueChange, placeholder = "Select…", searchPlaceholder = "Search…", emptyText = "No matches.", disabled, loading, onSearchChange, clearable = true, width, id, className, name, required, ...aria }, ref) {
13
17
  const [open, setOpen] = React.useState(false);
18
+ const [own, setOwn] = React.useState(defaultValue);
19
+ const value = valueProp === void 0 ? own : valueProp;
20
+ const setValue = (next) => {
21
+ if (valueProp === void 0) setOwn(next);
22
+ onValueChange?.(next);
23
+ };
14
24
  const listId = React.useId();
15
25
  const selected = options.find((o) => o.value === value);
16
26
  return /* @__PURE__ */ jsxs(Fragment, { children: [name && /* @__PURE__ */ jsx("input", {
@@ -24,9 +34,10 @@ function Combobox({ options, value, onValueChange, placeholder = "Select…", se
24
34
  children: [/* @__PURE__ */ jsx(PopoverTrigger, {
25
35
  asChild: true,
26
36
  children: /* @__PURE__ */ jsxs("button", {
37
+ ref,
27
38
  type: "button",
28
39
  role: "combobox",
29
- "aria-required": required || void 0,
40
+ "aria-required": aria["aria-required"] ?? (required || void 0),
30
41
  onKeyDown: (event) => {
31
42
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
32
43
  event.preventDefault();
@@ -44,12 +55,12 @@ function Combobox({ options, value, onValueChange, placeholder = "Select…", se
44
55
  "aria-invalid": aria["aria-invalid"],
45
56
  disabled,
46
57
  "data-slot": "combobox-trigger",
47
- className: cn(fieldClasses, "flex h-9 items-center justify-between gap-2 text-left", !selected && "text-muted-foreground", className),
58
+ className: cn(fieldClasses, "flex h-9 items-center justify-between gap-2 text-left", !selected && "text-muted-foreground", width && fieldWidthClasses[width], className),
48
59
  children: [/* @__PURE__ */ jsx("span", {
49
60
  className: "truncate",
50
61
  children: selected?.label ?? value ?? placeholder
51
62
  }), /* @__PURE__ */ jsx(ChevronsUpDown, {
52
- className: "size-4 shrink-0 opacity-60",
63
+ className: "size-4 shrink-0 text-muted-foreground",
53
64
  "aria-hidden": true
54
65
  })]
55
66
  })
@@ -71,7 +82,7 @@ function Combobox({ options, value, onValueChange, placeholder = "Select…", se
71
82
  value: `${o.label} ${o.description ?? ""} ${o.value}`,
72
83
  disabled: o.disabled,
73
84
  onSelect: () => {
74
- onValueChange(clearable && o.value === value ? null : o.value);
85
+ setValue(clearable && o.value === value ? null : o.value);
75
86
  setOpen(false);
76
87
  },
77
88
  children: [/* @__PURE__ */ jsxs("span", {
@@ -91,7 +102,7 @@ function Combobox({ options, value, onValueChange, placeholder = "Select…", se
91
102
  })
92
103
  })]
93
104
  })] });
94
- }
105
+ });
95
106
  //#endregion
96
107
  export { Combobox };
97
108
 
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.js","names":["_Fragment"],"sources":["../../src/components/combobox.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronsUpDown from '@burtson-labs/icons/react/chevrons-up-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { fieldClasses } from './input';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { Spinner } from './spinner';\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** Second line, e.g. an email under a name. Also searched. */\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n options: ComboboxOption[];\n value: string | null;\n onValueChange: (value: string | null) => void;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n disabled?: boolean;\n /** Show a spinner in the list, e.g. while `onSearchChange` fetches. */\n loading?: boolean;\n /**\n * Called as the person types. Pass it to search on a server; the options\n * you pass back are shown as-is (no client filtering).\n */\n onSearchChange?: (search: string) => void;\n /** Let the person clear the selection by picking it again. */\n clearable?: boolean;\n id?: string;\n className?: string;\n 'aria-invalid'?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n name?: string;\n required?: boolean;\n}\n\n/** Pick one value from a long or remote list by typing. */\nfunction Combobox({\n options,\n value,\n onValueChange,\n placeholder = 'Select…',\n searchPlaceholder = 'Search…',\n emptyText = 'No matches.',\n disabled,\n loading,\n onSearchChange,\n clearable = true,\n id,\n className,\n name,\n required,\n ...aria\n}: ComboboxProps) {\n const [open, setOpen] = React.useState(false);\n const listId = React.useId();\n const selected = options.find((o) => o.value === value);\n return (\n <>\n {name && <input type=\"hidden\" name={name} value={value ?? ''} disabled={disabled} />}\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-required={required || undefined}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n setOpen(true);\n }\n }}\n id={id}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-controls={open ? listId : undefined}\n aria-label={\n aria['aria-label'] ?? (aria['aria-labelledby'] || id ? undefined : placeholder)\n }\n aria-labelledby={aria['aria-labelledby']}\n aria-describedby={aria['aria-describedby']}\n data-required={required || undefined}\n aria-invalid={aria['aria-invalid']}\n disabled={disabled}\n data-slot=\"combobox-trigger\"\n className={cn(\n fieldClasses,\n 'flex h-9 items-center justify-between gap-2 text-left',\n !selected && 'text-muted-foreground',\n className,\n )}\n >\n <span className=\"truncate\">{selected?.label ?? value ?? placeholder}</span>\n <ChevronsUpDown className=\"size-4 shrink-0 opacity-60\" aria-hidden />\n </button>\n </PopoverTrigger>\n <PopoverContent\n id={listId}\n aria-label={aria['aria-label'] ?? placeholder}\n className=\"w-(--radix-popover-trigger-width) min-w-64 p-0\"\n align=\"start\"\n >\n <Command shouldFilter={!onSearchChange}>\n <CommandInput\n aria-label={searchPlaceholder}\n placeholder={searchPlaceholder}\n onValueChange={onSearchChange}\n />\n <CommandList>\n {loading ? (\n <div className=\"flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground\">\n <Spinner /> Searching…\n </div>\n ) : (\n <CommandEmpty>{emptyText}</CommandEmpty>\n )}\n {!loading && (\n <CommandGroup>\n {options.map((o) => (\n <CommandItem\n key={o.value}\n value={`${o.label} ${o.description ?? ''} ${o.value}`}\n disabled={o.disabled}\n onSelect={() => {\n onValueChange(clearable && o.value === value ? null : o.value);\n setOpen(false);\n }}\n >\n <span className=\"grid min-w-0 flex-1\">\n <span className=\"truncate\">{o.label}</span>\n {o.description && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {o.description}\n </span>\n )}\n </span>\n <Check\n aria-hidden\n className={cn(\n 'ml-auto size-4 text-brand',\n o.value === value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </>\n );\n}\n\nexport { Combobox };\n"],"mappings":";;;;;;;;;;;AAsDA,SAAS,SAAS,EAChB,SACA,OACA,eACA,cAAc,WACd,oBAAoB,WACpB,YAAY,eACZ,UACA,SACA,gBACA,YAAY,MACZ,IACA,WACA,MACA,UACA,GAAG,QACa;CAChB,MAAM,CAAC,MAAM,WAAW,MAAM,SAAS,KAAK;CAC5C,MAAM,SAAS,MAAM,MAAM;CAC3B,MAAM,WAAW,QAAQ,MAAM,MAAM,EAAE,UAAU,KAAK;CACtD,OACE,qBAAAA,UAAA,EAAA,UAAA,CACG,QAAQ,oBAAC,SAAD;EAAO,MAAK;EAAe;EAAM,OAAO,SAAS;EAAc;CAAW,CAAA,GACnF,qBAAC,SAAD;EAAe;EAAM,cAAc;EAAnC,UAAA,CACE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,UAAD;IACE,MAAK;IACL,MAAK;IACL,iBAAe,YAAY,KAAA;IAC3B,YAAY,UAAU;KACpB,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;MACxD,MAAM,eAAe;MACrB,QAAQ,IAAI;KACd;IACF;IACI;IACJ,iBAAe;IACf,iBAAc;IACd,iBAAe,OAAO,SAAS,KAAA;IAC/B,cACE,KAAK,kBAAkB,KAAK,sBAAsB,KAAK,KAAA,IAAY;IAErE,mBAAiB,KAAK;IACtB,oBAAkB,KAAK;IACvB,iBAAe,YAAY,KAAA;IAC3B,gBAAc,KAAK;IACT;IACV,aAAU;IACV,WAAW,GACT,cACA,yDACA,CAAC,YAAY,yBACb,SACF;IA5BF,UAAA,CA8BE,oBAAC,QAAD;KAAM,WAAU;KAAY,UAAA,UAAU,SAAS,SAAS;IAAkB,CAAA,GAC1E,oBAAC,gBAAD;KAAgB,WAAU;KAA6B,eAAA;IAAa,CAAA,CAC9D;;EACM,CAAA,GAChB,oBAAC,gBAAD;GACE,IAAI;GACJ,cAAY,KAAK,iBAAiB;GAClC,WAAU;GACV,OAAM;GAEN,UAAA,qBAAC,SAAD;IAAS,cAAc,CAAC;IAAxB,UAAA,CACE,oBAAC,cAAD;KACE,cAAY;KACZ,aAAa;KACb,eAAe;IAChB,CAAA,GACD,qBAAC,aAAD,EAAA,UAAA,CACG,UACC,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,SAAD,CAAU,CAAA,GAAC,aACR;IAEL,CAAA,IAAA,oBAAC,cAAD,EAAA,UAAe,UAAwB,CAAA,GAExC,CAAC,WACA,oBAAC,cAAD,EAAA,UACG,QAAQ,KAAK,MACZ,qBAAC,aAAD;KAEE,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,eAAe,GAAG,GAAG,EAAE;KAC9C,UAAU,EAAE;KACZ,gBAAgB;MACd,cAAc,aAAa,EAAE,UAAU,QAAQ,OAAO,EAAE,KAAK;MAC7D,QAAQ,KAAK;KACf;KAPF,UAAA,CASE,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACE,oBAAC,QAAD;OAAM,WAAU;OAAY,UAAA,EAAE;MAAY,CAAA,GACzC,EAAE,eACD,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,EAAE;MACC,CAAA,CAEJ;KACN,CAAA,GAAA,oBAAC,OAAD;MACE,eAAA;MACA,WAAW,GACT,6BACA,EAAE,UAAU,QAAQ,gBAAgB,WACtC;KACD,CAAA,CACU;IAvBN,GAAA,EAAE,KAuBI,CACd,EACW,CAAA,CAEL,EAAA,CAAA,CACN;;EACK,CAAA,CACT;CACT,CAAA,CAAA,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"combobox.js","names":["_Fragment"],"sources":["../../src/components/combobox.tsx"],"sourcesContent":["import Check from '@burtson-labs/icons/react/check';\nimport ChevronsUpDown from '@burtson-labs/icons/react/chevrons-up-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from './command';\nimport { fieldClasses, type FieldWidth, fieldWidthClasses } from './input';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { Spinner } from './spinner';\n\nexport interface ComboboxOption {\n value: string;\n label: string;\n /** Second line, e.g. an email under a name. Also searched. */\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps {\n options: ComboboxOption[];\n /** Controlled: the chosen value, or null. Leave out for an uncontrolled combobox. */\n value?: string | null;\n /** The starting value when uncontrolled. */\n defaultValue?: string | null;\n onValueChange?: (value: string | null) => void;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyText?: string;\n disabled?: boolean;\n /** Show a spinner in the list, e.g. while `onSearchChange` fetches. */\n loading?: boolean;\n /**\n * Called as the person types. Pass it to search on a server; the options\n * you pass back are shown as-is (no client filtering).\n */\n onSearchChange?: (search: string) => void;\n /** Let the person clear the selection by picking it again. */\n clearable?: boolean;\n /** How wide the trigger is from 640px up; full width on phones. */\n width?: FieldWidth;\n id?: string;\n className?: string;\n 'aria-invalid'?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-required'?: boolean;\n name?: string;\n required?: boolean;\n}\n\n/**\n * Pick one value from a long or remote list by typing. The ref reaches the\n * trigger button, so a form library or an ErrorSummary can focus it.\n */\nconst Combobox = React.forwardRef<HTMLButtonElement, ComboboxProps>(function Combobox(\n {\n options,\n value: valueProp,\n defaultValue = null,\n onValueChange,\n placeholder = 'Select…',\n searchPlaceholder = 'Search…',\n emptyText = 'No matches.',\n disabled,\n loading,\n onSearchChange,\n clearable = true,\n width,\n id,\n className,\n name,\n required,\n ...aria\n },\n ref,\n) {\n const [open, setOpen] = React.useState(false);\n const [own, setOwn] = React.useState<string | null>(defaultValue);\n const value = valueProp === undefined ? own : valueProp;\n const setValue = (next: string | null) => {\n if (valueProp === undefined) setOwn(next);\n onValueChange?.(next);\n };\n const listId = React.useId();\n const selected = options.find((o) => o.value === value);\n return (\n <>\n {name && <input type=\"hidden\" name={name} value={value ?? ''} disabled={disabled} />}\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n ref={ref}\n type=\"button\"\n role=\"combobox\"\n aria-required={aria['aria-required'] ?? (required || undefined)}\n onKeyDown={(event) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n setOpen(true);\n }\n }}\n id={id}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-controls={open ? listId : undefined}\n aria-label={\n aria['aria-label'] ?? (aria['aria-labelledby'] || id ? undefined : placeholder)\n }\n aria-labelledby={aria['aria-labelledby']}\n aria-describedby={aria['aria-describedby']}\n data-required={required || undefined}\n aria-invalid={aria['aria-invalid']}\n disabled={disabled}\n data-slot=\"combobox-trigger\"\n className={cn(\n fieldClasses,\n 'flex h-9 items-center justify-between gap-2 text-left',\n !selected && 'text-muted-foreground',\n width && fieldWidthClasses[width],\n className,\n )}\n >\n <span className=\"truncate\">{selected?.label ?? value ?? placeholder}</span>\n <ChevronsUpDown className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden />\n </button>\n </PopoverTrigger>\n <PopoverContent\n id={listId}\n aria-label={aria['aria-label'] ?? placeholder}\n className=\"w-(--radix-popover-trigger-width) min-w-64 p-0\"\n align=\"start\"\n >\n <Command shouldFilter={!onSearchChange}>\n <CommandInput\n aria-label={searchPlaceholder}\n placeholder={searchPlaceholder}\n onValueChange={onSearchChange}\n />\n <CommandList>\n {loading ? (\n <div className=\"flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground\">\n <Spinner /> Searching…\n </div>\n ) : (\n <CommandEmpty>{emptyText}</CommandEmpty>\n )}\n {!loading && (\n <CommandGroup>\n {options.map((o) => (\n <CommandItem\n key={o.value}\n value={`${o.label} ${o.description ?? ''} ${o.value}`}\n disabled={o.disabled}\n onSelect={() => {\n setValue(clearable && o.value === value ? null : o.value);\n setOpen(false);\n }}\n >\n <span className=\"grid min-w-0 flex-1\">\n <span className=\"truncate\">{o.label}</span>\n {o.description && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {o.description}\n </span>\n )}\n </span>\n <Check\n aria-hidden\n className={cn(\n 'ml-auto size-4 text-brand',\n o.value === value ? 'opacity-100' : 'opacity-0',\n )}\n />\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </>\n );\n});\n\nexport { Combobox };\n"],"mappings":"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"}
@@ -1,18 +1,74 @@
1
- import { Command as CommandPrimitive } from 'cmdk';
2
1
  import * as React from 'react';
3
2
  import { Dialog } from './dialog';
4
- declare function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>): React.JSX.Element;
5
- /** A command palette in a dialog, the usual ⌘K surface. */
6
- declare function CommandDialog({ title, description, children, className, ...props }: React.ComponentProps<typeof Dialog> & {
3
+ declare const Command: React.ForwardRefExoticComponent<Omit<{
4
+ children?: React.ReactNode;
5
+ } & Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
6
+ asChild?: boolean;
7
+ }, "ref"> & {
8
+ label?: string;
9
+ shouldFilter?: boolean;
10
+ filter?: (value: string, search: string, keywords?: string[]) => number;
11
+ defaultValue?: string;
12
+ value?: string;
13
+ onValueChange?: (value: string) => void;
14
+ loop?: boolean;
15
+ disablePointerSelection?: boolean;
16
+ vimBindings?: boolean;
17
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
18
+ export interface CommandDialogProps extends React.ComponentProps<typeof Dialog> {
7
19
  title?: string;
8
20
  description?: string;
9
21
  className?: string;
10
- }): React.JSX.Element;
11
- declare function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>): React.JSX.Element;
12
- declare function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>): React.JSX.Element;
13
- declare function CommandEmpty(props: React.ComponentProps<typeof CommandPrimitive.Empty>): React.JSX.Element;
14
- declare function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>): React.JSX.Element;
15
- declare function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>): React.JSX.Element;
16
- declare function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>): React.JSX.Element;
17
- declare function CommandShortcut({ className, ...props }: React.ComponentProps<'span'>): React.JSX.Element;
22
+ }
23
+ /** A command palette in a dialog, the usual ⌘K surface. */
24
+ declare function CommandDialog({ title, description, children, className, ...props }: CommandDialogProps): React.JSX.Element;
25
+ /**
26
+ * The row is the field (icon + input, ruled off from the list); the input
27
+ * itself draws no border or outline, whatever the host page's CSS says.
28
+ */
29
+ declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Omit<React.ClassAttributes<HTMLInputElement> & React.InputHTMLAttributes<HTMLInputElement> & {
30
+ asChild?: boolean;
31
+ }, "ref">, "value" | "type" | "onChange"> & {
32
+ value?: string;
33
+ onValueChange?: (search: string) => void;
34
+ } & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
35
+ declare const CommandList: React.ForwardRefExoticComponent<Omit<{
36
+ children?: React.ReactNode;
37
+ } & Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
38
+ asChild?: boolean;
39
+ }, "ref"> & {
40
+ label?: string;
41
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
42
+ declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
43
+ children?: React.ReactNode;
44
+ } & Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
45
+ asChild?: boolean;
46
+ }, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
47
+ declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
48
+ children?: React.ReactNode;
49
+ } & Omit<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
50
+ asChild?: boolean;
51
+ }, "ref">, "value" | "heading"> & {
52
+ heading?: React.ReactNode;
53
+ value?: string;
54
+ forceMount?: boolean;
55
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
56
+ declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
57
+ asChild?: boolean;
58
+ }, "ref"> & {
59
+ alwaysRender?: boolean;
60
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
61
+ /** A row: 32px (44px on touch screens), 8px radius, a fill when active. */
62
+ declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
63
+ children?: React.ReactNode;
64
+ } & Omit<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
65
+ asChild?: boolean;
66
+ }, "ref">, "value" | "onSelect" | "disabled"> & {
67
+ disabled?: boolean;
68
+ onSelect?: (value: string) => void;
69
+ value?: string;
70
+ keywords?: string[];
71
+ forceMount?: boolean;
72
+ } & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
73
+ declare const CommandShortcut: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
18
74
  export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, };
@@ -1,17 +1,19 @@
1
- import { cn } from "../lib/utils.js";
1
+ "use client";
2
+ import { cn, noOutlineClasses } from "../lib/utils.js";
2
3
  import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./dialog.js";
3
- import "react";
4
+ import { Command as pkg } from "../primitives/vendor/cmdk/index.js";
5
+ import * as React from "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
+ var Command = React.forwardRef(function Command({ className, ...props }, ref) {
10
+ return /* @__PURE__ */ jsx(pkg, {
11
+ ref,
10
12
  "data-slot": "command",
11
13
  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
14
  ...props
13
15
  });
14
- }
16
+ });
15
17
  /** A command palette in a dialog, the usual ⌘K surface. */
16
18
  function CommandDialog({ title = "Command palette", description = "Search for a page or an action", children, className, ...props }) {
17
19
  return /* @__PURE__ */ jsx(Dialog, {
@@ -22,70 +24,82 @@ function CommandDialog({ title = "Command palette", description = "Search for a
22
24
  children: [/* @__PURE__ */ jsxs(DialogHeader, {
23
25
  className: "sr-only",
24
26
  children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })]
25
- }), /* @__PURE__ */ jsx(Command$1, {
27
+ }), /* @__PURE__ */ jsx(Command, {
26
28
  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
29
  children
28
30
  })]
29
31
  })
30
32
  });
31
33
  }
32
- function CommandInput({ className, ...props }) {
34
+ /**
35
+ * The row is the field (icon + input, ruled off from the list); the input
36
+ * itself draws no border or outline, whatever the host page's CSS says.
37
+ */
38
+ var CommandInput = React.forwardRef(function CommandInput({ className, ...props }, ref) {
33
39
  return /* @__PURE__ */ jsxs("div", {
34
40
  "data-slot": "command-input-wrapper",
35
- className: "flex h-11 items-center gap-2 border-b px-3",
41
+ className: "flex items-center gap-2 border-b px-3",
36
42
  children: [/* @__PURE__ */ jsx(Search, {
37
- className: "size-4 shrink-0 opacity-50",
43
+ className: "size-4 shrink-0 text-muted-foreground",
38
44
  "aria-hidden": true
39
- }), /* @__PURE__ */ jsx(Command.Input, {
45
+ }), /* @__PURE__ */ jsx(pkg.Input, {
46
+ ref,
40
47
  "data-slot": "command-input",
41
- 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),
48
+ className: cn("flex h-11 w-full rounded-none border-0 bg-transparent py-3 text-base shadow-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm", noOutlineClasses, className),
42
49
  ...props
43
50
  })]
44
51
  });
45
- }
46
- function CommandList({ className, ...props }) {
47
- return /* @__PURE__ */ jsx(Command.List, {
52
+ });
53
+ var CommandList = React.forwardRef(function CommandList({ className, ...props }, ref) {
54
+ return /* @__PURE__ */ jsx(pkg.List, {
55
+ ref,
48
56
  "data-slot": "command-list",
49
57
  className: cn("max-h-80 scroll-py-1 overflow-x-hidden overflow-y-auto p-1", className),
50
58
  ...props
51
59
  });
52
- }
53
- function CommandEmpty(props) {
54
- return /* @__PURE__ */ jsx(Command.Empty, {
60
+ });
61
+ var CommandEmpty = React.forwardRef(function CommandEmpty({ className, ...props }, ref) {
62
+ return /* @__PURE__ */ jsx(pkg.Empty, {
63
+ ref,
55
64
  "data-slot": "command-empty",
56
- className: "py-6 text-center text-sm text-muted-foreground",
65
+ className: cn("py-6 text-center text-sm text-muted-foreground", className),
57
66
  ...props
58
67
  });
59
- }
60
- function CommandGroup({ className, ...props }) {
61
- return /* @__PURE__ */ jsx(Command.Group, {
68
+ });
69
+ var CommandGroup = React.forwardRef(function CommandGroup({ className, ...props }, ref) {
70
+ return /* @__PURE__ */ jsx(pkg.Group, {
71
+ ref,
62
72
  "data-slot": "command-group",
63
- 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),
73
+ className: cn("overflow-hidden py-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-[11px] [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:tracking-[0.06em] [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:uppercase", className),
64
74
  ...props
65
75
  });
66
- }
67
- function CommandSeparator({ className, ...props }) {
68
- return /* @__PURE__ */ jsx(Command.Separator, {
76
+ });
77
+ var CommandSeparator = React.forwardRef(function CommandSeparator({ className, ...props }, ref) {
78
+ return /* @__PURE__ */ jsx(pkg.Separator, {
79
+ ref,
69
80
  "data-slot": "command-separator",
70
81
  className: cn("-mx-1 h-px bg-border", className),
71
82
  ...props
72
83
  });
73
- }
74
- function CommandItem({ className, ...props }) {
75
- return /* @__PURE__ */ jsx(Command.Item, {
84
+ });
85
+ /** A row: 32px (44px on touch screens), 8px radius, a fill when active. */
86
+ var CommandItem = React.forwardRef(function CommandItem({ className, ...props }, ref) {
87
+ return /* @__PURE__ */ jsx(pkg.Item, {
88
+ ref,
76
89
  "data-slot": "command-item",
77
- 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),
90
+ className: cn("relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 text-[13px] select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-secondary data-[selected=true]:text-foreground pointer-coarse:min-h-11 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", noOutlineClasses, className),
78
91
  ...props
79
92
  });
80
- }
81
- function CommandShortcut({ className, ...props }) {
93
+ });
94
+ var CommandShortcut = React.forwardRef(function CommandShortcut({ className, ...props }, ref) {
82
95
  return /* @__PURE__ */ jsx("span", {
96
+ ref,
83
97
  "data-slot": "command-shortcut",
84
98
  className: cn("ml-auto rounded-xs border border-border bg-surface-muted px-1.5 font-mono text-[11px] leading-5 text-muted-foreground", className),
85
99
  ...props
86
100
  });
87
- }
101
+ });
88
102
  //#endregion
89
- export { Command$1 as Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
103
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
90
104
 
91
105
  //# 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, noOutlineClasses } from '../lib/utils';\nimport { Command as CommandPrimitive } from '../primitives/vendor/cmdk';\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog';\n\nconst Command = React.forwardRef<HTMLDivElement, React.ComponentProps<typeof CommandPrimitive>>(\n function Command({ className, ...props }, ref) {\n return (\n <CommandPrimitive\n ref={ref}\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\nexport interface CommandDialogProps extends React.ComponentProps<typeof Dialog> {\n title?: string;\n description?: string;\n className?: string;\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}: CommandDialogProps) {\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\n/**\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 */\nconst CommandInput = React.forwardRef<\n HTMLInputElement,\n React.ComponentProps<typeof CommandPrimitive.Input>\n>(function CommandInput({ className, ...props }, ref) {\n return (\n <div data-slot=\"command-input-wrapper\" className=\"flex items-center gap-2 border-b px-3\">\n <Search className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden />\n <CommandPrimitive.Input\n ref={ref}\n data-slot=\"command-input\"\n className={cn(\n 'flex h-11 w-full rounded-none border-0 bg-transparent py-3 text-base shadow-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm',\n noOutlineClasses,\n className,\n )}\n {...props}\n />\n </div>\n );\n});\n\nconst CommandList = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof CommandPrimitive.List>\n>(function CommandList({ className, ...props }, ref) {\n return (\n <CommandPrimitive.List\n ref={ref}\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\nconst CommandEmpty = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof CommandPrimitive.Empty>\n>(function CommandEmpty({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Empty\n ref={ref}\n data-slot=\"command-empty\"\n className={cn('py-6 text-center text-sm text-muted-foreground', className)}\n {...props}\n />\n );\n});\n\nconst CommandGroup = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof CommandPrimitive.Group>\n>(function CommandGroup({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Group\n ref={ref}\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-[11px] [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:tracking-[0.06em] [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:uppercase',\n className,\n )}\n {...props}\n />\n );\n});\n\nconst CommandSeparator = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof CommandPrimitive.Separator>\n>(function CommandSeparator({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Separator\n ref={ref}\n data-slot=\"command-separator\"\n className={cn('-mx-1 h-px bg-border', className)}\n {...props}\n />\n );\n});\n\n/** A row: 32px (44px on touch screens), 8px radius, a fill when active. */\nconst CommandItem = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof CommandPrimitive.Item>\n>(function CommandItem({ className, ...props }, ref) {\n return (\n <CommandPrimitive.Item\n ref={ref}\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] select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-secondary data-[selected=true]:text-foreground pointer-coarse:min-h-11 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n noOutlineClasses,\n className,\n )}\n {...props}\n />\n );\n});\n\nconst CommandShortcut = React.forwardRef<HTMLSpanElement, React.ComponentProps<'span'>>(\n function CommandShortcut({ className, ...props }, ref) {\n return (\n <span\n ref={ref}\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);\n\nexport {\n Command,\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n};\n"],"mappings":";;;;;;;;AAQA,IAAM,UAAU,MAAM,WACpB,SAAS,QAAQ,EAAE,WAAW,GAAG,SAAS,KAAK;CAC7C,OACE,oBAACA,KAAD;EACO;EACL,aAAU;EACV,WAAW,GAIT,iJACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CACF;;AASA,SAAS,cAAc,EACrB,QAAQ,mBACR,cAAc,kCACd,UACA,WACA,GAAG,SACkB;CACrB,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;;;;;AAMA,IAAM,eAAe,MAAM,WAGzB,SAAS,aAAa,EAAE,WAAW,GAAG,SAAS,KAAK;CACpD,OACE,qBAAC,OAAD;EAAK,aAAU;EAAwB,WAAU;EAAjD,UAAA,CACE,oBAAC,QAAD;GAAQ,WAAU;GAAwC,eAAA;EAAa,CAAA,GACvE,oBAACA,IAAiB,OAAlB;GACO;GACL,aAAU;GACV,WAAW,GACT,iLACA,kBACA,SACF;GACA,GAAI;EACL,CAAA,CACE;;AAET,CAAC;AAED,IAAM,cAAc,MAAM,WAGxB,SAAS,YAAY,EAAE,WAAW,GAAG,SAAS,KAAK;CACnD,OACE,oBAACA,IAAiB,MAAlB;EACO;EACL,aAAU;EACV,WAAW,GAAG,8DAA8D,SAAS;EACrF,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,eAAe,MAAM,WAGzB,SAAS,aAAa,EAAE,WAAW,GAAG,SAAS,KAAK;CACpD,OACE,oBAACA,IAAiB,OAAlB;EACO;EACL,aAAU;EACV,WAAW,GAAG,kDAAkD,SAAS;EACzE,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,eAAe,MAAM,WAGzB,SAAS,aAAa,EAAE,WAAW,GAAG,SAAS,KAAK;CACpD,OACE,oBAACA,IAAiB,OAAlB;EACO;EACL,aAAU;EACV,WAAW,GACT,+SACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,mBAAmB,MAAM,WAG7B,SAAS,iBAAiB,EAAE,WAAW,GAAG,SAAS,KAAK;CACxD,OACE,oBAACA,IAAiB,WAAlB;EACO;EACL,aAAU;EACV,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;CACL,CAAA;AAEL,CAAC;;AAGD,IAAM,cAAc,MAAM,WAGxB,SAAS,YAAY,EAAE,WAAW,GAAG,SAAS,KAAK;CACnD,OACE,oBAACA,IAAiB,MAAlB;EACO;EACL,aAAU;EACV,WAAW,GACT,iZACA,kBACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,kBAAkB,MAAM,WAC5B,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAS,KAAK;CACrD,OACE,oBAAC,QAAD;EACO;EACL,aAAU;EACV,WAAW,GACT,yHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CACF"}
@@ -47,11 +47,11 @@ export declare function acceptsFile(file: Pick<File, 'name' | 'type'>, accept?:
47
47
  * The message box: grows with its text, Enter sends, Shift+Enter adds a
48
48
  * line, and it never sends mid-composition (IME input).
49
49
  */
50
- declare function Composer({ onSubmit, onSubmitError, submitErrorText, value: controlled, onValueChange, streaming, onStop, disabled, placeholder, attachments, attachmentCount, canSubmit, actions, label, onAttach, accept, multiple, attachLabel, className, ...props }: ComposerProps): React.JSX.Element;
50
+ declare const Composer: React.ForwardRefExoticComponent<Omit<ComposerProps, "ref"> & React.RefAttributes<HTMLFormElement>>;
51
51
  export interface SuggestionsProps extends Omit<React.ComponentProps<'div'>, 'onSelect'> {
52
52
  items: string[];
53
53
  onSelect: (item: string) => void;
54
54
  }
55
55
  /** Starter prompts as chips. */
56
- declare function Suggestions({ items, onSelect, className, ...props }: SuggestionsProps): React.JSX.Element;
56
+ declare const Suggestions: React.ForwardRefExoticComponent<Omit<SuggestionsProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
57
57
  export { Composer, Suggestions };
@@ -1,4 +1,5 @@
1
- import { cn } from "../lib/utils.js";
1
+ "use client";
2
+ import { cn, focusRingClasses, noOutlineClasses } from "../lib/utils.js";
2
3
  import { Button } from "./button.js";
3
4
  import * as React from "react";
4
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -17,7 +18,7 @@ function acceptsFile(file, accept) {
17
18
  * The message box: grows with its text, Enter sends, Shift+Enter adds a
18
19
  * line, and it never sends mid-composition (IME input).
19
20
  */
20
- function Composer({ onSubmit, onSubmitError, submitErrorText = "Message could not be sent. Your draft is saved here. Try again.", value: controlled, onValueChange, streaming = false, onStop, disabled = false, placeholder = "Ask anything…", attachments, attachmentCount = 0, canSubmit = true, actions, label = "Message", onAttach, accept, multiple = true, attachLabel = "Attach files", className, ...props }) {
21
+ var Composer = React.forwardRef(function Composer({ onSubmit, onSubmitError, submitErrorText = "Message could not be sent. Your draft is saved here. Try again.", value: controlled, onValueChange, streaming = false, onStop, disabled = false, placeholder = "Ask anything…", attachments, attachmentCount = 0, canSubmit = true, actions, label = "Message", onAttach, accept, multiple = true, attachLabel = "Attach files", className, ...props }, ref) {
21
22
  const fileInput = React.useRef(null);
22
23
  const [dragging, setDragging] = React.useState(false);
23
24
  const dragDepth = React.useRef(0);
@@ -68,6 +69,7 @@ function Composer({ onSubmit, onSubmitError, submitErrorText = "Message could no
68
69
  }
69
70
  };
70
71
  return /* @__PURE__ */ jsxs("form", {
72
+ ref,
71
73
  "data-slot": "composer",
72
74
  "data-dragging": dragging || void 0,
73
75
  onSubmit: (e) => {
@@ -128,7 +130,7 @@ function Composer({ onSubmit, onSubmitError, submitErrorText = "Message could no
128
130
  send();
129
131
  }
130
132
  },
131
- 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"
133
+ className: cn("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 placeholder:text-muted-foreground disabled:cursor-not-allowed pointer-coarse:min-h-11 pointer-coarse:py-2.5", noOutlineClasses)
132
134
  }),
133
135
  failed && /* @__PURE__ */ jsx("p", {
134
136
  id: errorId,
@@ -192,10 +194,11 @@ function Composer({ onSubmit, onSubmitError, submitErrorText = "Message could no
192
194
  })
193
195
  ]
194
196
  });
195
- }
197
+ });
196
198
  /** Starter prompts as chips. */
197
- function Suggestions({ items, onSelect, className, ...props }) {
199
+ var Suggestions = React.forwardRef(function Suggestions({ items, onSelect, className, ...props }, ref) {
198
200
  return /* @__PURE__ */ jsx("div", {
201
+ ref,
199
202
  "data-slot": "suggestions",
200
203
  role: "group",
201
204
  "aria-label": "Suggestions",
@@ -204,11 +207,11 @@ function Suggestions({ items, onSelect, className, ...props }) {
204
207
  children: items.map((item) => /* @__PURE__ */ jsx("button", {
205
208
  type: "button",
206
209
  onClick: () => onSelect(item),
207
- 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",
210
+ className: cn("animate-in rounded-full border border-border-strong bg-surface px-3 py-1.5 text-[13px] text-foreground transition-colors hover:border-brand/40 hover:bg-brand-soft hover:text-brand-soft-foreground pointer-coarse:min-h-11", focusRingClasses),
208
211
  children: item
209
212
  }, item))
210
213
  });
211
- }
214
+ });
212
215
  //#endregion
213
216
  export { Composer, Suggestions, acceptsFile };
214
217
 
@@ -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, focusRingClasses, noOutlineClasses } 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 */\nconst Composer = React.forwardRef<HTMLFormElement, ComposerProps>(function Composer(\n {\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 },\n ref,\n) {\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 ref={ref}\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={cn(\n '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 placeholder:text-muted-foreground disabled:cursor-not-allowed pointer-coarse:min-h-11 pointer-coarse:py-2.5',\n noOutlineClasses,\n )}\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. */\nconst Suggestions = React.forwardRef<HTMLDivElement, SuggestionsProps>(function Suggestions(\n { items, onSelect, className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\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={cn(\n 'animate-in rounded-full border border-border-strong bg-surface px-3 py-1.5 text-[13px] text-foreground transition-colors hover:border-brand/40 hover:bg-brand-soft hover:text-brand-soft-foreground pointer-coarse:min-h-11',\n focusRingClasses,\n )}\n >\n {item}\n </button>\n ))}\n </div>\n );\n});\n\nexport { Composer, Suggestions };\n"],"mappings":";;;;;;;;;;AAqDA,SAAgB,YAAY,MAAmC,QAA0B;CACvF,IAAI,CAAC,QAAQ,KAAK,GAAG,OAAO;CAC5B,MAAM,OAAO,KAAK,KAAK,YAAY;CACnC,MAAM,QAAQ,KAAK,QAAQ,GAAA,CAAI,YAAY;CAC3C,OAAO,OACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAClC,OAAO,OAAO,CAAC,CACf,MAAM,SACL,KAAK,WAAW,GAAG,IACf,KAAK,SAAS,IAAI,IAClB,KAAK,SAAS,IAAI,IAChB,KAAK,WAAW,KAAK,MAAM,GAAG,EAAE,CAAC,IACjC,SAAS,IACjB;AACJ;;;;;AAMA,IAAM,WAAW,MAAM,WAA2C,SAAS,SACzE,EACE,UACA,eACA,kBAAkB,mEAClB,OAAO,YACP,eACA,YAAY,OACZ,QACA,WAAW,OACX,cAAc,iBACd,aACA,kBAAkB,GAClB,YAAY,MACZ,SACA,QAAQ,WACR,UACA,QACA,WAAW,MACX,cAAc,gBACd,WACA,GAAG,SAEL,KACA;CACA,MAAM,YAAY,MAAM,OAAyB,IAAI;CACrD,MAAM,CAAC,UAAU,eAAe,MAAM,SAAS,KAAK;CACpD,MAAM,YAAY,MAAM,OAAO,CAAC;CAChC,MAAM,UAAU,SAA+C;EAC7D,IAAI,CAAC,YAAY,CAAC,MAAM;EACxB,IAAI,QAAQ,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,MAAM,YAAY,GAAG,MAAM,CAAC;EACjE,IAAI,CAAC,UAAU,QAAQ,MAAM,MAAM,GAAG,CAAC;EACvC,IAAI,MAAM,QAAQ,SAAS,KAAK;CAClC;CACA,MAAM,YAAY,MAChB,MAAM,KAAK,EAAE,cAAc,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,OAAO;CAC1D,MAAM,CAAC,KAAK,UAAU,MAAM,SAAS,EAAE;CACvC,MAAM,QAAQ,cAAc;CAC5B,MAAM,CAAC,SAAS,cAAc,MAAM,SAAS,KAAK;CAClD,MAAM,CAAC,QAAQ,aAAa,MAAM,SAAS,KAAK;CAChD,MAAM,UAAU,MAAM,OAAO,KAAK;CAClC,MAAM,SAAS,MAAM,OAAO,KAAK;CACjC,MAAM,UAAU,MAAM,OAAO,IAAI;CACjC,MAAM,UAAU,MAAM,MAAM;CAC5B,MAAM,gBAAgB;EACpB,OAAO,UAAU;CACnB,GAAG,CAAC,KAAK,CAAC;CACV,MAAM,gBAAgB;EACpB,QAAQ,UAAU;EAClB,aAAa;GACX,QAAQ,UAAU;EACpB;CACF,GAAG,CAAC,CAAC;CACL,MAAM,YAAY,MAAc;EAC9B,IAAI,eAAe,KAAA,GAAW,OAAO,CAAC;EACtC,gBAAgB,CAAC;CACnB;CACA,MAAM,UACJ,aACA,CAAC,YACD,CAAC,aACD,CAAC,YACA,MAAM,KAAK,CAAC,CAAC,SAAS,KAAK,kBAAkB;CAChD,MAAM,OAAO,YAAY;EACvB,IAAI,CAAC,WAAW,QAAQ,SAAS;EACjC,MAAM,QAAQ;EACd,QAAQ,UAAU;EAClB,UAAU,KAAK;EACf,WAAW,IAAI;EACf,IAAI;GACF,MAAM,SAAS,MAAM,KAAK,CAAC;GAC3B,IAAI,QAAQ,WAAW,OAAO,YAAY,OAAO,SAAS,EAAE;EAC9D,SAAS,OAAO;GACd,IAAI,QAAQ,SAAS,UAAU,IAAI;GACnC,gBAAgB,KAAK;EACvB,UAAU;GACR,QAAQ,UAAU;GAClB,IAAI,QAAQ,SAAS,WAAW,KAAK;EACvC;CACF;CAEA,OACE,qBAAC,QAAD;EACO;EACL,aAAU;EACV,iBAAe,YAAY,KAAA;EAC3B,WAAW,MAAM;GACf,EAAE,eAAe;GACjB,KAAU;EACZ;EACA,cAAc,MAAM;GAClB,IAAI,CAAC,YAAY,YAAY,CAAC,SAAS,CAAC,GAAG;GAC3C,EAAE,eAAe;GACjB,UAAU,WAAW;GACrB,YAAY,IAAI;EAClB;EACA,aAAa,MAAM;GACjB,IAAI,CAAC,YAAY,YAAY,CAAC,SAAS,CAAC,GAAG;GAC3C,EAAE,eAAe;GACjB,EAAE,aAAa,aAAa;EAC9B;EACA,mBAAmB;GACjB,IAAI,CAAC,UAAU;GACf,UAAU,UAAU,KAAK,IAAI,GAAG,UAAU,UAAU,CAAC;GACrD,IAAI,UAAU,YAAY,GAAG,YAAY,KAAK;EAChD;EACA,SAAS,MAAM;GACb,IAAI,CAAC,YAAY,UAAU;GAC3B,EAAE,eAAe;GACjB,UAAU,UAAU;GACpB,YAAY,KAAK;GACjB,OAAO,EAAE,cAAc,KAAK;EAC9B;EACA,WAAW,GAET,2QACA,8FACA,YAAY,cACZ,SACF;EACA,GAAI;EAtCN,UAAA;GAwCG,YACC,oBAAC,OAAD;IACE,eAAA;IACA,WAAU;IACX,UAAA;GAEI,CAAA;GAEP,oBAAC,YAAD;IACE,cAAY;IACZ,MAAM;IACC;IACP,UAAU,YAAY;IACtB,oBAAkB,SAAS,UAAU,KAAA;IACrC,gBAAc,UAAU,KAAA;IACX;IACb,WAAW,MAAM,SAAS,EAAE,OAAO,KAAK;IACxC,UAAU,MAAM;KACd,IAAI,CAAC,UAAU;KACf,MAAM,QAAQ,MAAM,KAAK,EAAE,eAAe,SAAS,CAAC,CAAC;KAErD,IAAI,MAAM,QAAQ;MAChB,EAAE,eAAe;MACjB,OAAO,KAAK;KACd;IACF;IACA,YAAY,MAAM;KAChB,IACE,EAAE,QAAQ,WACV,CAAC,EAAE,YACH,CAAC,EAAE,YAAY,eACf,EAAE,YAAY,YAAY,KAC1B;MACA,EAAE,eAAe;MACjB,KAAU;KACZ;IACF;IACA,WAAW,GACT,oQACA,gBACF;GACD,CAAA;GACA,UACC,oBAAC,KAAD;IAAG,IAAI;IAAS,MAAK;IAAQ,WAAU;IACpC,UAAA;GACA,CAAA;GAEJ,eAAe,oBAAC,OAAD;IAAK,WAAU;IAA+B,UAAA;GAAiB,CAAA;GAC/E,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACG,YACC,qBAAAA,UAAA,EAAA,UAAA,CACE,oBAAC,SAAD;MACE,KAAK;MACL,MAAK;MACL,QAAA;MACA,UAAU;MACF;MACE;MACV,aAAU;MACV,WAAW,MAAM;OACf,OAAO,EAAE,OAAO,KAAK;OAErB,EAAE,OAAO,QAAQ;MACnB;KACD,CAAA,GACD,oBAAC,QAAD;MACE,MAAK;MACL,MAAK;MACL,SAAQ;MACR,cAAY;MACZ,OAAO;MACG;MACV,eAAe,UAAU,SAAS,MAAM;MACxC,WAAU;MAEV,UAAA,oBAAC,WAAD,CAAY,CAAA;KACN,CAAA,CACR,EAAA,CAAA;KAEH;KACD,oBAAC,OAAD;MAAK,WAAU;MACZ,UAAA,YACC,oBAAC,QAAD;OACE,MAAK;OACL,MAAK;OACL,SAAQ;OACR,cAAW;OACX,WAAU;OACV,SAAS;OACT,UAAU,CAAC,UAAU;OAErB,UAAA,oBAAC,QAAD,EAAQ,WAAU,eAAgB,CAAA;MAC5B,CAAA,IAER,oBAAC,QAAD;OACE,MAAK;OACL,MAAK;OACL,cAAW;OACX,WAAU;OACV,SAAS;OACT,UAAU,CAAC;OAEX,UAAA,oBAAC,SAAD,CAAU,CAAA;MACJ,CAAA;KAEP,CAAA;IACF;;EACD;;AAEV,CAAC;;AAQD,IAAM,cAAc,MAAM,WAA6C,SAAS,YAC9E,EAAE,OAAO,UAAU,WAAW,GAAG,SACjC,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,aAAU;EACV,MAAK;EACL,cAAW;EACX,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;EAEH,UAAA,MAAM,KAAK,SACV,oBAAC,UAAD;GAEE,MAAK;GACL,eAAe,SAAS,IAAI;GAC5B,WAAW,GACT,+NACA,gBACF;GAEC,UAAA;EACK,GATD,IASC,CACT;CACE,CAAA;AAET,CAAC"}
@@ -15,7 +15,7 @@ export interface ConnectionStatusProps extends Omit<React.ComponentProps<'div'>,
15
15
  onRetry?: () => void;
16
16
  }
17
17
  /** A dot and a word for a live connection: model provider, gateway, socket. */
18
- declare function ConnectionStatus({ state, label, detail, onRetry, ...props }: ConnectionStatusProps): React.JSX.Element;
18
+ declare const ConnectionStatus: React.ForwardRefExoticComponent<Omit<ConnectionStatusProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
19
19
  export interface SyncStatusProps extends Omit<React.ComponentProps<'div'>, 'children'> {
20
20
  state: SyncState;
21
21
  /** When the last successful sync finished. */
@@ -29,7 +29,7 @@ export interface SyncStatusProps extends Omit<React.ComponentProps<'div'>, 'chil
29
29
  formatTime?: (date: Date) => string;
30
30
  }
31
31
  /** Whether local changes have reached the server. */
32
- declare function SyncStatus({ state, lastSynced, pendingCount, detail, onRetry, formatTime, ...props }: SyncStatusProps): React.JSX.Element;
32
+ declare const SyncStatus: React.ForwardRefExoticComponent<Omit<SyncStatusProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
33
33
  export interface ConnectionBannerProps extends Omit<React.ComponentProps<'div'>, 'children'> {
34
34
  state: ConnectionState;
35
35
  /** What still works, e.g. "Messages you send will go out when you reconnect." */
@@ -40,5 +40,5 @@ export interface ConnectionBannerProps extends Omit<React.ComponentProps<'div'>,
40
40
  * A full-width notice for connection trouble. It renders nothing while
41
41
  * connected, connecting or unknown, so it can stay mounted.
42
42
  */
43
- declare function ConnectionBanner({ state, description, onRetry, className, ...props }: ConnectionBannerProps): React.JSX.Element | null;
43
+ declare const ConnectionBanner: React.ForwardRefExoticComponent<Omit<ConnectionBannerProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
44
44
  export { ConnectionBanner, ConnectionStatus, SyncStatus };