@burtson-labs/ui 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/LICENSES/DEPENDENCIES.txt +2745 -0
  2. package/LICENSES/Radix-MIT.txt +21 -0
  3. package/LICENSES/cmdk-MIT.txt +21 -0
  4. package/LICENSES/overrides/react-remove-scroll-bar.txt +26 -0
  5. package/LICENSES/shadcn-MIT.txt +21 -0
  6. package/README.md +5 -1
  7. package/THIRD_PARTY_NOTICES.md +15 -3
  8. package/dist/components/accordion.d.ts +1 -1
  9. package/dist/components/accordion.js +9 -8
  10. package/dist/components/accordion.js.map +1 -1
  11. package/dist/components/alert-dialog.d.ts +1 -1
  12. package/dist/components/alert-dialog.js +12 -11
  13. package/dist/components/alert-dialog.js.map +1 -1
  14. package/dist/components/alert.js +1 -0
  15. package/dist/components/alert.js.map +1 -1
  16. package/dist/components/app-shell.js +1 -0
  17. package/dist/components/app-shell.js.map +1 -1
  18. package/dist/components/attachment.js +1 -0
  19. package/dist/components/attachment.js.map +1 -1
  20. package/dist/components/audio-player.js +1 -0
  21. package/dist/components/audio-player.js.map +1 -1
  22. package/dist/components/avatar.d.ts +1 -1
  23. package/dist/components/avatar.js +7 -6
  24. package/dist/components/avatar.js.map +1 -1
  25. package/dist/components/badge.js +3 -3
  26. package/dist/components/badge.js.map +1 -1
  27. package/dist/components/breadcrumb.js +3 -3
  28. package/dist/components/breadcrumb.js.map +1 -1
  29. package/dist/components/button.d.ts +2 -2
  30. package/dist/components/button.js +3 -3
  31. package/dist/components/button.js.map +1 -1
  32. package/dist/components/card.d.ts +1 -1
  33. package/dist/components/card.js +1 -0
  34. package/dist/components/card.js.map +1 -1
  35. package/dist/components/chat-history.js +1 -0
  36. package/dist/components/chat-history.js.map +1 -1
  37. package/dist/components/chat-layout.js +1 -0
  38. package/dist/components/chat-layout.js.map +1 -1
  39. package/dist/components/checkbox-card.d.ts +1 -1
  40. package/dist/components/checkbox-card.js +3 -3
  41. package/dist/components/checkbox-card.js.map +1 -1
  42. package/dist/components/checkbox.d.ts +1 -1
  43. package/dist/components/checkbox.js +6 -5
  44. package/dist/components/checkbox.js.map +1 -1
  45. package/dist/components/collapsible.d.ts +1 -1
  46. package/dist/components/collapsible.js +7 -6
  47. package/dist/components/collapsible.js.map +1 -1
  48. package/dist/components/combobox.js +1 -0
  49. package/dist/components/combobox.js.map +1 -1
  50. package/dist/components/command.d.ts +1 -1
  51. package/dist/components/command.js +12 -11
  52. package/dist/components/command.js.map +1 -1
  53. package/dist/components/composer.js +1 -0
  54. package/dist/components/composer.js.map +1 -1
  55. package/dist/components/connection-status.js +1 -0
  56. package/dist/components/connection-status.js.map +1 -1
  57. package/dist/components/context-menu.d.ts +1 -1
  58. package/dist/components/context-menu.js +19 -18
  59. package/dist/components/context-menu.js.map +1 -1
  60. package/dist/components/conversation.js +1 -0
  61. package/dist/components/conversation.js.map +1 -1
  62. package/dist/components/copy-button.js +1 -0
  63. package/dist/components/copy-button.js.map +1 -1
  64. package/dist/components/data-table.js +1 -0
  65. package/dist/components/data-table.js.map +1 -1
  66. package/dist/components/dialog.d.ts +1 -1
  67. package/dist/components/dialog.js +13 -12
  68. package/dist/components/dialog.js.map +1 -1
  69. package/dist/components/dropdown-menu.d.ts +1 -1
  70. package/dist/components/dropdown-menu.js +19 -18
  71. package/dist/components/dropdown-menu.js.map +1 -1
  72. package/dist/components/editor-tabs.js +1 -0
  73. package/dist/components/editor-tabs.js.map +1 -1
  74. package/dist/components/empty-state.js +1 -0
  75. package/dist/components/empty-state.js.map +1 -1
  76. package/dist/components/field.js +1 -0
  77. package/dist/components/field.js.map +1 -1
  78. package/dist/components/icon-button.js +1 -0
  79. package/dist/components/icon-button.js.map +1 -1
  80. package/dist/components/input.js +1 -0
  81. package/dist/components/input.js.map +1 -1
  82. package/dist/components/kbd.js +1 -0
  83. package/dist/components/kbd.js.map +1 -1
  84. package/dist/components/label.d.ts +1 -1
  85. package/dist/components/label.js +5 -4
  86. package/dist/components/label.js.map +1 -1
  87. package/dist/components/markdown.js +1 -0
  88. package/dist/components/markdown.js.map +1 -1
  89. package/dist/components/menubar.d.ts +1 -1
  90. package/dist/components/menubar.js +20 -19
  91. package/dist/components/menubar.js.map +1 -1
  92. package/dist/components/message-actions.js +1 -0
  93. package/dist/components/message-actions.js.map +1 -1
  94. package/dist/components/message.js +1 -0
  95. package/dist/components/message.js.map +1 -1
  96. package/dist/components/mobile-nav.js +1 -0
  97. package/dist/components/mobile-nav.js.map +1 -1
  98. package/dist/components/navigation-menu.d.ts +1 -1
  99. package/dist/components/navigation-menu.js +12 -11
  100. package/dist/components/navigation-menu.js.map +1 -1
  101. package/dist/components/onboarding-checklist.js +1 -0
  102. package/dist/components/onboarding-checklist.js.map +1 -1
  103. package/dist/components/page-header.js +1 -0
  104. package/dist/components/page-header.js.map +1 -1
  105. package/dist/components/pagination.js +1 -0
  106. package/dist/components/pagination.js.map +1 -1
  107. package/dist/components/popover.d.ts +1 -1
  108. package/dist/components/popover.js +8 -7
  109. package/dist/components/popover.js.map +1 -1
  110. package/dist/components/progress.d.ts +1 -1
  111. package/dist/components/progress.js +6 -5
  112. package/dist/components/progress.js.map +1 -1
  113. package/dist/components/radio-group.d.ts +1 -1
  114. package/dist/components/radio-group.js +7 -6
  115. package/dist/components/radio-group.js.map +1 -1
  116. package/dist/components/reasoning.js +5 -4
  117. package/dist/components/reasoning.js.map +1 -1
  118. package/dist/components/resizable.js +1 -0
  119. package/dist/components/resizable.js.map +1 -1
  120. package/dist/components/scroll-area.d.ts +1 -1
  121. package/dist/components/scroll-area.js +9 -8
  122. package/dist/components/scroll-area.js.map +1 -1
  123. package/dist/components/secret-input.js +1 -0
  124. package/dist/components/secret-input.js.map +1 -1
  125. package/dist/components/select.d.ts +1 -1
  126. package/dist/components/select.js +18 -17
  127. package/dist/components/select.js.map +1 -1
  128. package/dist/components/separator.d.ts +1 -1
  129. package/dist/components/separator.js +5 -4
  130. package/dist/components/separator.js.map +1 -1
  131. package/dist/components/sheet.d.ts +1 -1
  132. package/dist/components/sheet.js +10 -9
  133. package/dist/components/sheet.js.map +1 -1
  134. package/dist/components/skeleton.js +1 -0
  135. package/dist/components/skeleton.js.map +1 -1
  136. package/dist/components/slider.js +1 -0
  137. package/dist/components/slider.js.map +1 -1
  138. package/dist/components/source.js +1 -0
  139. package/dist/components/source.js.map +1 -1
  140. package/dist/components/spinner.js +1 -0
  141. package/dist/components/spinner.js.map +1 -1
  142. package/dist/components/stat-card.js +1 -0
  143. package/dist/components/stat-card.js.map +1 -1
  144. package/dist/components/status.js +1 -0
  145. package/dist/components/status.js.map +1 -1
  146. package/dist/components/steps.js +1 -0
  147. package/dist/components/steps.js.map +1 -1
  148. package/dist/components/switch.d.ts +1 -1
  149. package/dist/components/switch.js +6 -5
  150. package/dist/components/switch.js.map +1 -1
  151. package/dist/components/table.js +1 -0
  152. package/dist/components/table.js.map +1 -1
  153. package/dist/components/tabs.d.ts +1 -1
  154. package/dist/components/tabs.js +8 -7
  155. package/dist/components/tabs.js.map +1 -1
  156. package/dist/components/textarea.js +1 -0
  157. package/dist/components/textarea.js.map +1 -1
  158. package/dist/components/toast.d.ts +1 -1
  159. package/dist/components/toast.js +11 -10
  160. package/dist/components/toast.js.map +1 -1
  161. package/dist/components/toaster.js +1 -0
  162. package/dist/components/toaster.js.map +1 -1
  163. package/dist/components/tool-call.js +5 -4
  164. package/dist/components/tool-call.js.map +1 -1
  165. package/dist/components/toolbar.js +1 -0
  166. package/dist/components/toolbar.js.map +1 -1
  167. package/dist/components/tooltip.d.ts +1 -1
  168. package/dist/components/tooltip.js +10 -9
  169. package/dist/components/tooltip.js.map +1 -1
  170. package/dist/components/tour.js +8 -6
  171. package/dist/components/tour.js.map +1 -1
  172. package/dist/components/tree-view.js +1 -0
  173. package/dist/components/tree-view.js.map +1 -1
  174. package/dist/components/voice-recorder.js +1 -0
  175. package/dist/components/voice-recorder.js.map +1 -1
  176. package/dist/primitives/vendor/cmdk/command-score.d.ts +1 -0
  177. package/dist/primitives/vendor/cmdk/command-score.js +64 -0
  178. package/dist/primitives/vendor/cmdk/command-score.js.map +1 -0
  179. package/dist/primitives/vendor/cmdk/index.d.ts +384 -0
  180. package/dist/primitives/vendor/cmdk/index.js +687 -0
  181. package/dist/primitives/vendor/cmdk/index.js.map +1 -0
  182. package/dist/primitives/vendor/radix/number/index.d.ts +1 -0
  183. package/dist/primitives/vendor/radix/number/number.d.ts +2 -0
  184. package/dist/primitives/vendor/radix/number/number.js +9 -0
  185. package/dist/primitives/vendor/radix/number/number.js.map +1 -0
  186. package/dist/primitives/vendor/radix/primitive/index.d.ts +2 -0
  187. package/dist/primitives/vendor/radix/primitive/is-development.d.ts +1 -0
  188. package/dist/primitives/vendor/radix/primitive/is-development.js +7 -0
  189. package/dist/primitives/vendor/radix/primitive/is-development.js.map +1 -0
  190. package/dist/primitives/vendor/radix/primitive/primitive.d.ts +14 -0
  191. package/dist/primitives/vendor/radix/primitive/primitive.js +12 -0
  192. package/dist/primitives/vendor/radix/primitive/primitive.js.map +1 -0
  193. package/dist/primitives/vendor/radix/primitive/types.d.ts +5 -0
  194. package/dist/primitives/vendor/radix/react-accordion/accordion.d.ts +112 -0
  195. package/dist/primitives/vendor/radix/react-accordion/accordion.js +266 -0
  196. package/dist/primitives/vendor/radix/react-accordion/accordion.js.map +1 -0
  197. package/dist/primitives/vendor/radix/react-accordion/index.d.ts +2 -0
  198. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.d.ts +49 -0
  199. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js +122 -0
  200. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js.map +1 -0
  201. package/dist/primitives/vendor/radix/react-alert-dialog/index.d.ts +2 -0
  202. package/dist/primitives/vendor/radix/react-arrow/arrow.d.ts +9 -0
  203. package/dist/primitives/vendor/radix/react-arrow/arrow.js +22 -0
  204. package/dist/primitives/vendor/radix/react-arrow/arrow.js.map +1 -0
  205. package/dist/primitives/vendor/radix/react-arrow/index.d.ts +2 -0
  206. package/dist/primitives/vendor/radix/react-avatar/avatar.d.ts +19 -0
  207. package/dist/primitives/vendor/radix/react-avatar/avatar.js +132 -0
  208. package/dist/primitives/vendor/radix/react-avatar/avatar.js.map +1 -0
  209. package/dist/primitives/vendor/radix/react-avatar/index.d.ts +2 -0
  210. package/dist/primitives/vendor/radix/react-checkbox/checkbox.d.ts +47 -0
  211. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js +197 -0
  212. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js.map +1 -0
  213. package/dist/primitives/vendor/radix/react-checkbox/index.d.ts +2 -0
  214. package/dist/primitives/vendor/radix/react-collapsible/collapsible.d.ts +31 -0
  215. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js +133 -0
  216. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js.map +1 -0
  217. package/dist/primitives/vendor/radix/react-collapsible/index.d.ts +2 -0
  218. package/dist/primitives/vendor/radix/react-collection/collection-legacy.d.ts +21 -0
  219. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js +84 -0
  220. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js.map +1 -0
  221. package/dist/primitives/vendor/radix/react-collection/collection.d.ts +32 -0
  222. package/dist/primitives/vendor/radix/react-collection/index.d.ts +4 -0
  223. package/dist/primitives/vendor/radix/react-collection/ordered-dictionary.d.ts +51 -0
  224. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.d.ts +13 -0
  225. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js +43 -0
  226. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js.map +1 -0
  227. package/dist/primitives/vendor/radix/react-compose-refs/index.d.ts +1 -0
  228. package/dist/primitives/vendor/radix/react-context/create-context.d.ts +45 -0
  229. package/dist/primitives/vendor/radix/react-context/create-context.js +74 -0
  230. package/dist/primitives/vendor/radix/react-context/create-context.js.map +1 -0
  231. package/dist/primitives/vendor/radix/react-context/index.d.ts +2 -0
  232. package/dist/primitives/vendor/radix/react-context-menu/context-menu.d.ts +95 -0
  233. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js +279 -0
  234. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js.map +1 -0
  235. package/dist/primitives/vendor/radix/react-context-menu/index.d.ts +2 -0
  236. package/dist/primitives/vendor/radix/react-dialog/dialog.d.ts +97 -0
  237. package/dist/primitives/vendor/radix/react-dialog/dialog.js +262 -0
  238. package/dist/primitives/vendor/radix/react-dialog/dialog.js.map +1 -0
  239. package/dist/primitives/vendor/radix/react-dialog/index.d.ts +4 -0
  240. package/dist/primitives/vendor/radix/react-direction/direction.d.ts +10 -0
  241. package/dist/primitives/vendor/radix/react-direction/direction.js +13 -0
  242. package/dist/primitives/vendor/radix/react-direction/direction.js.map +1 -0
  243. package/dist/primitives/vendor/radix/react-direction/index.d.ts +1 -0
  244. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.d.ts +61 -0
  245. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js +336 -0
  246. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js.map +1 -0
  247. package/dist/primitives/vendor/radix/react-dismissable-layer/index.d.ts +4 -0
  248. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.d.ts +95 -0
  249. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js +257 -0
  250. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js.map +1 -0
  251. package/dist/primitives/vendor/radix/react-dropdown-menu/index.d.ts +2 -0
  252. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.d.ts +11 -0
  253. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js +49 -0
  254. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js.map +1 -0
  255. package/dist/primitives/vendor/radix/react-focus-guards/index.d.ts +1 -0
  256. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.d.ts +31 -0
  257. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js +221 -0
  258. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js.map +1 -0
  259. package/dist/primitives/vendor/radix/react-focus-scope/index.d.ts +1 -0
  260. package/dist/primitives/vendor/radix/react-id/id.d.ts +2 -0
  261. package/dist/primitives/vendor/radix/react-id/id.js +17 -0
  262. package/dist/primitives/vendor/radix/react-id/id.js.map +1 -0
  263. package/dist/primitives/vendor/radix/react-id/index.d.ts +1 -0
  264. package/dist/primitives/vendor/radix/react-label/index.d.ts +2 -0
  265. package/dist/primitives/vendor/radix/react-label/label.d.ts +9 -0
  266. package/dist/primitives/vendor/radix/react-label/label.js +21 -0
  267. package/dist/primitives/vendor/radix/react-label/label.js.map +1 -0
  268. package/dist/primitives/vendor/radix/react-menu/index.d.ts +2 -0
  269. package/dist/primitives/vendor/radix/react-menu/menu.d.ts +173 -0
  270. package/dist/primitives/vendor/radix/react-menu/menu.js +806 -0
  271. package/dist/primitives/vendor/radix/react-menu/menu.js.map +1 -0
  272. package/dist/primitives/vendor/radix/react-menubar/index.d.ts +2 -0
  273. package/dist/primitives/vendor/radix/react-menubar/menubar.d.ts +106 -0
  274. package/dist/primitives/vendor/radix/react-menubar/menubar.js +377 -0
  275. package/dist/primitives/vendor/radix/react-menubar/menubar.js.map +1 -0
  276. package/dist/primitives/vendor/radix/react-navigation-menu/index.d.ts +2 -0
  277. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.d.ts +124 -0
  278. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js +743 -0
  279. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js.map +1 -0
  280. package/dist/primitives/vendor/radix/react-popover/index.d.ts +1 -0
  281. package/dist/primitives/vendor/radix/react-popover/popover.d.ts +83 -0
  282. package/dist/primitives/vendor/radix/react-popover/popover.js +236 -0
  283. package/dist/primitives/vendor/radix/react-popover/popover.js.map +1 -0
  284. package/dist/primitives/vendor/radix/react-popper/index.d.ts +2 -0
  285. package/dist/primitives/vendor/radix/react-popper/popper.d.ts +44 -0
  286. package/dist/primitives/vendor/radix/react-popper/popper.js +276 -0
  287. package/dist/primitives/vendor/radix/react-popper/popper.js.map +1 -0
  288. package/dist/primitives/vendor/radix/react-portal/index.d.ts +2 -0
  289. package/dist/primitives/vendor/radix/react-portal/portal.d.ts +13 -0
  290. package/dist/primitives/vendor/radix/react-portal/portal.js +21 -0
  291. package/dist/primitives/vendor/radix/react-portal/portal.js.map +1 -0
  292. package/dist/primitives/vendor/radix/react-presence/index.d.ts +2 -0
  293. package/dist/primitives/vendor/radix/react-presence/presence.d.ts +11 -0
  294. package/dist/primitives/vendor/radix/react-presence/presence.js +152 -0
  295. package/dist/primitives/vendor/radix/react-presence/presence.js.map +1 -0
  296. package/dist/primitives/vendor/radix/react-presence/use-state-machine.d.ts +10 -0
  297. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js +12 -0
  298. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js.map +1 -0
  299. package/dist/primitives/vendor/radix/react-primitive/index.d.ts +2 -0
  300. package/dist/primitives/vendor/radix/react-primitive/primitive.d.ts +56 -0
  301. package/dist/primitives/vendor/radix/react-primitive/primitive.js +84 -0
  302. package/dist/primitives/vendor/radix/react-primitive/primitive.js.map +1 -0
  303. package/dist/primitives/vendor/radix/react-progress/index.d.ts +2 -0
  304. package/dist/primitives/vendor/radix/react-progress/progress.d.ts +17 -0
  305. package/dist/primitives/vendor/radix/react-progress/progress.js +79 -0
  306. package/dist/primitives/vendor/radix/react-progress/progress.js.map +1 -0
  307. package/dist/primitives/vendor/radix/react-radio-group/index.d.ts +2 -0
  308. package/dist/primitives/vendor/radix/react-radio-group/radio-group.d.ts +55 -0
  309. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js +173 -0
  310. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js.map +1 -0
  311. package/dist/primitives/vendor/radix/react-radio-group/radio.d.ts +62 -0
  312. package/dist/primitives/vendor/radix/react-radio-group/radio.js +150 -0
  313. package/dist/primitives/vendor/radix/react-radio-group/radio.js.map +1 -0
  314. package/dist/primitives/vendor/radix/react-roving-focus/index.d.ts +2 -0
  315. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.d.ts +47 -0
  316. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js +218 -0
  317. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js.map +1 -0
  318. package/dist/primitives/vendor/radix/react-scroll-area/index.d.ts +2 -0
  319. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.d.ts +121 -0
  320. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js +713 -0
  321. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js.map +1 -0
  322. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.d.ts +10 -0
  323. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js +12 -0
  324. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js.map +1 -0
  325. package/dist/primitives/vendor/radix/react-select/index.d.ts +2 -0
  326. package/dist/primitives/vendor/radix/react-select/select.d.ts +163 -0
  327. package/dist/primitives/vendor/radix/react-select/select.js +1040 -0
  328. package/dist/primitives/vendor/radix/react-select/select.js.map +1 -0
  329. package/dist/primitives/vendor/radix/react-separator/index.d.ts +2 -0
  330. package/dist/primitives/vendor/radix/react-separator/separator.d.ts +20 -0
  331. package/dist/primitives/vendor/radix/react-separator/separator.js +29 -0
  332. package/dist/primitives/vendor/radix/react-separator/separator.js.map +1 -0
  333. package/dist/primitives/vendor/radix/react-slot/index.d.ts +1 -0
  334. package/dist/primitives/vendor/radix/react-slot/slot.d.ts +29 -0
  335. package/dist/primitives/vendor/radix/react-slot/slot.js +107 -0
  336. package/dist/primitives/vendor/radix/react-slot/slot.js.map +1 -0
  337. package/dist/primitives/vendor/radix/react-switch/index.d.ts +2 -0
  338. package/dist/primitives/vendor/radix/react-switch/switch.d.ts +41 -0
  339. package/dist/primitives/vendor/radix/react-switch/switch.js +185 -0
  340. package/dist/primitives/vendor/radix/react-switch/switch.js.map +1 -0
  341. package/dist/primitives/vendor/radix/react-tabs/index.d.ts +2 -0
  342. package/dist/primitives/vendor/radix/react-tabs/tabs.d.ts +54 -0
  343. package/dist/primitives/vendor/radix/react-tabs/tabs.js +145 -0
  344. package/dist/primitives/vendor/radix/react-tabs/tabs.js.map +1 -0
  345. package/dist/primitives/vendor/radix/react-toast/index.d.ts +2 -0
  346. package/dist/primitives/vendor/radix/react-toast/toast.d.ts +125 -0
  347. package/dist/primitives/vendor/radix/react-toast/toast.js +557 -0
  348. package/dist/primitives/vendor/radix/react-toast/toast.js.map +1 -0
  349. package/dist/primitives/vendor/radix/react-tooltip/index.d.ts +2 -0
  350. package/dist/primitives/vendor/radix/react-tooltip/tooltip.d.ts +99 -0
  351. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js +503 -0
  352. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js.map +1 -0
  353. package/dist/primitives/vendor/radix/react-use-callback-ref/index.d.ts +1 -0
  354. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.d.ts +6 -0
  355. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js +18 -0
  356. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js.map +1 -0
  357. package/dist/primitives/vendor/radix/react-use-controllable-state/index.d.ts +2 -0
  358. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state-reducer.d.ts +28 -0
  359. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.d.ts +11 -0
  360. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js +59 -0
  361. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js.map +1 -0
  362. package/dist/primitives/vendor/radix/react-use-effect-event/index.d.ts +1 -0
  363. package/dist/primitives/vendor/radix/react-use-effect-event/use-effect-event.d.ts +7 -0
  364. package/dist/primitives/vendor/radix/react-use-is-hydrated/index.d.ts +1 -0
  365. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.d.ts +1 -0
  366. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js +18 -0
  367. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js.map +1 -0
  368. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.d.ts +6 -0
  369. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js +19 -0
  370. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js.map +1 -0
  371. package/dist/primitives/vendor/radix/react-use-layout-effect/index.d.ts +1 -0
  372. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.d.ts +10 -0
  373. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js +15 -0
  374. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js.map +1 -0
  375. package/dist/primitives/vendor/radix/react-use-previous/index.d.ts +1 -0
  376. package/dist/primitives/vendor/radix/react-use-previous/use-previous.d.ts +2 -0
  377. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js +20 -0
  378. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js.map +1 -0
  379. package/dist/primitives/vendor/radix/react-use-size/index.d.ts +1 -0
  380. package/dist/primitives/vendor/radix/react-use-size/use-size.d.ts +5 -0
  381. package/dist/primitives/vendor/radix/react-use-size/use-size.js +42 -0
  382. package/dist/primitives/vendor/radix/react-use-size/use-size.js.map +1 -0
  383. package/dist/primitives/vendor/radix/react-visually-hidden/index.d.ts +2 -0
  384. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.d.ts +21 -0
  385. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js +32 -0
  386. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js.map +1 -0
  387. package/dist/primitives/vendor/radix/rect/index.d.ts +2 -0
  388. package/dist/primitives/vendor/radix/rect/observe-element-rect.d.ts +16 -0
  389. package/dist/styles.css +1 -1
  390. package/package.json +21 -11
  391. package/vendor-manifest.json +1101 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 WorkOS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Paco Coursey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ Source: https://github.com/theKashey/react-remove-scroll-bar/blob/master/LICENSE
2
+ Git blob: 7c08c3990396ecefd90f99ff5d9a34f26f5b5616
3
+ Retrieved to supply the license omitted from the 2.3.8 npm archive.
4
+
5
+ MIT License
6
+
7
+ Copyright (c) 2025 Anton Korzunov <thekashey@gmail.com>
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 shadcn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  **React components for Burtson Labs products.**
11
11
 
12
- Used in Bandit Stealth, Sentinel, our cluster tools and client apps. Radix primitives handle focus and keyboard behaviour, Tailwind v4 handles styling, and the icons are [Burtson Icons](https://icons.burtson.ai). No runtime provider. Install the package, or copy a component's source and change it.
12
+ Used in Bandit Stealth, Sentinel, our cluster tools and client apps. Locally maintained MIT-licensed Radix primitives handle focus and keyboard behaviour, Tailwind v4 handles styling, and the icons are [Burtson Icons](https://icons.burtson.ai). No runtime provider. Install the package, or copy a component's source and change it.
13
13
 
14
14
  [![Docs](https://img.shields.io/badge/docs-ui.burtson.ai-a60ee5)](https://ui.burtson.ai)
15
15
  [![npm](https://img.shields.io/npm/v/@burtson-labs/ui?logo=npm)](https://www.npmjs.com/package/@burtson-labs/ui)
@@ -102,6 +102,10 @@ Adding a component: write `src/components/<name>.tsx`, export it from `src/index
102
102
 
103
103
  Linting and formatting follow [Burtson Labs frontend standards](https://github.com/Burtson-Labs/frontend-standards). Every push is audited by [Sentinel](https://github.com/Burtson-Labs/sentinel-audit).
104
104
 
105
+ ## Local primitives and API references
106
+
107
+ The primitive implementations and cmdk live in this repository; no external Radix or cmdk package is required. See [VENDORING.md](VENDORING.md) for provenance, retained dependencies, and maintenance, and [API_REFERENCE.md](API_REFERENCE.md) for the generated component references. Original licenses are retained in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) and `LICENSES/`.
108
+
105
109
  ## License
106
110
 
107
111
  [MIT](LICENSE) © Burtson Labs. Inspired by and partly adapted from [shadcn/ui](https://github.com/shadcn-ui/ui) (MIT); see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
@@ -1,6 +1,6 @@
1
1
  # Third-party notices
2
2
 
3
- Burtson UI is original work by Burtson Labs, released under the MIT license
3
+ Burtson UI includes Burtson Labs components and vendored third-party primitives, released under the MIT license
4
4
  (see [LICENSE](LICENSE)). Its component API, the `data-slot` convention, the
5
5
  colour-token names and the registry format follow
6
6
  [shadcn/ui](https://github.com/shadcn-ui/ui), and several components adapt
@@ -30,5 +30,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
30
  SOFTWARE.
31
31
  ```
32
32
 
33
- Behaviour and accessibility come from [Radix UI](https://www.radix-ui.com)
34
- primitives (MIT, © WorkOS), installed as the `radix-ui` dependency.
33
+ ## Locally maintained primitives
34
+
35
+ Radix Primitives and cmdk are maintained as TypeScript source under
36
+ `src/primitives/vendor`. They are no longer installed as runtime packages.
37
+ Their original MIT licenses are included in `LICENSES/Radix-MIT.txt` and
38
+ `LICENSES/cmdk-MIT.txt`. `vendor-manifest.json` records exact versions,
39
+ source origins, hashes, and local modifications. See `VENDORING.md`.
40
+
41
+ Floating UI, aria-hidden, react-remove-scroll and the other declared
42
+ dependencies remain external dependencies with their own licenses.
43
+ `LICENSES/DEPENDENCIES.txt` preserves the installed runtime dependency and
44
+ peer dependency notices, including class-variance-authority (Apache-2.0).
45
+ The documentation site's `/licenses.txt` includes these notices too.
46
+ Registry source files carry the applicable full MIT notices.
@@ -1,5 +1,5 @@
1
- import { Accordion as AccordionPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as AccordionPrimitive from '../primitives/vendor/radix/react-accordion';
3
3
  declare function Accordion(props: React.ComponentProps<typeof AccordionPrimitive.Root>): React.JSX.Element;
4
4
  declare function AccordionItem({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>): React.JSX.Element;
5
5
  declare function AccordionTrigger({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Trigger>): React.JSX.Element;
@@ -1,26 +1,27 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
3
+ import { Content, Header, Item, Root, Trigger } from "../primitives/vendor/radix/react-accordion/accordion.js";
2
4
  import ChevronDown from "@burtson-labs/icons/react/chevron-down";
3
- import { Accordion } from "radix-ui";
4
5
  import "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/accordion.tsx
7
- function Accordion$1(props) {
8
- return /* @__PURE__ */ jsx(Accordion.Root, {
8
+ function Accordion(props) {
9
+ return /* @__PURE__ */ jsx(Root, {
9
10
  "data-slot": "accordion",
10
11
  ...props
11
12
  });
12
13
  }
13
14
  function AccordionItem({ className, ...props }) {
14
- return /* @__PURE__ */ jsx(Accordion.Item, {
15
+ return /* @__PURE__ */ jsx(Item, {
15
16
  "data-slot": "accordion-item",
16
17
  className: cn("border-b last:border-b-0", className),
17
18
  ...props
18
19
  });
19
20
  }
20
21
  function AccordionTrigger({ className, children, ...props }) {
21
- return /* @__PURE__ */ jsx(Accordion.Header, {
22
+ return /* @__PURE__ */ jsx(Header, {
22
23
  className: "flex",
23
- children: /* @__PURE__ */ jsxs(Accordion.Trigger, {
24
+ children: /* @__PURE__ */ jsxs(Trigger, {
24
25
  "data-slot": "accordion-trigger",
25
26
  className: cn("flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-semibold transition-all outline-none hover:text-brand focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180", className),
26
27
  ...props,
@@ -32,7 +33,7 @@ function AccordionTrigger({ className, children, ...props }) {
32
33
  });
33
34
  }
34
35
  function AccordionContent({ className, children, ...props }) {
35
- return /* @__PURE__ */ jsx(Accordion.Content, {
36
+ return /* @__PURE__ */ jsx(Content, {
36
37
  "data-slot": "accordion-content",
37
38
  className: "overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
38
39
  ...props,
@@ -43,6 +44,6 @@ function AccordionContent({ className, children, ...props }) {
43
44
  });
44
45
  }
45
46
  //#endregion
46
- export { Accordion$1 as Accordion, AccordionContent, AccordionItem, AccordionTrigger };
47
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
47
48
 
48
49
  //# sourceMappingURL=accordion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accordion.js","names":["Accordion","AccordionPrimitive"],"sources":["../../src/components/accordion.tsx"],"sourcesContent":["import ChevronDown from '@burtson-labs/icons/react/chevron-down';\nimport { Accordion as AccordionPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction Accordion(props: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\nfunction AccordionItem({\n className,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn('border-b last:border-b-0', className)}\n {...props}\n />\n );\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n 'flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-semibold transition-all outline-none hover:text-brand focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',\n className,\n )}\n {...props}\n >\n {children}\n <ChevronDown\n className=\"pointer-events-none size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-200\"\n aria-hidden\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n {...props}\n >\n <div className={cn('pt-0 pb-4', className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n\nexport { Accordion, AccordionContent, AccordionItem, AccordionTrigger };\n"],"mappings":";;;;;;AAMA,SAASA,YAAU,OAA6D;CAC9E,OAAO,oBAACC,UAAmB,MAApB;EAAyB,aAAU;EAAY,GAAI;CAAQ,CAAA;AACpE;AAEA,SAAS,cAAc,EACrB,WACA,GAAG,SACoD;CACvD,OACE,oBAACA,UAAmB,MAApB;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACuD;CAC1D,OACE,oBAACA,UAAmB,QAApB;EAA2B,WAAU;EACnC,UAAA,qBAACA,UAAmB,SAApB;GACE,aAAU;GACV,WAAW,GACT,uRACA,SACF;GACA,GAAI;GANN,UAAA,CAQG,UACD,oBAAC,aAAD;IACE,WAAU;IACV,eAAA;GACD,CAAA,CACyB;;CACH,CAAA;AAE/B;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACuD;CAC1D,OACE,oBAACA,UAAmB,SAApB;EACE,aAAU;EACV,WAAU;EACV,GAAI;EAEJ,UAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,aAAa,SAAS;GAAI;EAAc,CAAA;CACjC,CAAA;AAEhC"}
1
+ {"version":3,"file":"accordion.js","names":["AccordionPrimitive.Root","AccordionPrimitive.Item","AccordionPrimitive.Header","AccordionPrimitive.Trigger","AccordionPrimitive.Content"],"sources":["../../src/components/accordion.tsx"],"sourcesContent":["import ChevronDown from '@burtson-labs/icons/react/chevron-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as AccordionPrimitive from '../primitives/vendor/radix/react-accordion';\n\nfunction Accordion(props: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\nfunction AccordionItem({\n className,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn('border-b last:border-b-0', className)}\n {...props}\n />\n );\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n 'flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-semibold transition-all outline-none hover:text-brand focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',\n className,\n )}\n {...props}\n >\n {children}\n <ChevronDown\n className=\"pointer-events-none size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-200\"\n aria-hidden\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n {...props}\n >\n <div className={cn('pt-0 pb-4', className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n\nexport { Accordion, AccordionContent, AccordionItem, AccordionTrigger };\n"],"mappings":";;;;;;;AAMA,SAAS,UAAU,OAA6D;CAC9E,OAAO,oBAACA,MAAD;EAAyB,aAAU;EAAY,GAAI;CAAQ,CAAA;AACpE;AAEA,SAAS,cAAc,EACrB,WACA,GAAG,SACoD;CACvD,OACE,oBAACC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACuD;CAC1D,OACE,oBAACC,QAAD;EAA2B,WAAU;EACnC,UAAA,qBAACC,SAAD;GACE,aAAU;GACV,WAAW,GACT,uRACA,SACF;GACA,GAAI;GANN,UAAA,CAQG,UACD,oBAAC,aAAD;IACE,WAAU;IACV,eAAA;GACD,CAAA,CACyB;;CACH,CAAA;AAE/B;AAEA,SAAS,iBAAiB,EACxB,WACA,UACA,GAAG,SACuD;CAC1D,OACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAU;EACV,GAAI;EAEJ,UAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,aAAa,SAAS;GAAI;EAAc,CAAA;CACjC,CAAA;AAEhC"}
@@ -1,5 +1,5 @@
1
- import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as AlertDialogPrimitive from '../primitives/vendor/radix/react-alert-dialog';
3
3
  /**
4
4
  * A confirmation that interrupts: "Delete 3 keys?", "Revoke access?". Unlike
5
5
  * Dialog it has no close button and ignores outside clicks, so the person
@@ -1,6 +1,7 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
3
+ import { Action, Cancel, Content, Description, Overlay, Portal, Root, Title, Trigger } from "../primitives/vendor/radix/react-alert-dialog/alert-dialog.js";
2
4
  import { buttonVariants } from "./button.js";
3
- import { AlertDialog } from "radix-ui";
4
5
  import "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/alert-dialog.tsx
@@ -9,23 +10,23 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
10
  * Dialog it has no close button and ignores outside clicks, so the person
10
11
  * answers it; Escape still cancels. Focus starts on Cancel.
11
12
  */
12
- function AlertDialog$1(props) {
13
- return /* @__PURE__ */ jsx(AlertDialog.Root, {
13
+ function AlertDialog(props) {
14
+ return /* @__PURE__ */ jsx(Root, {
14
15
  "data-slot": "alert-dialog",
15
16
  ...props
16
17
  });
17
18
  }
18
19
  function AlertDialogTrigger(props) {
19
- return /* @__PURE__ */ jsx(AlertDialog.Trigger, {
20
+ return /* @__PURE__ */ jsx(Trigger, {
20
21
  "data-slot": "alert-dialog-trigger",
21
22
  ...props
22
23
  });
23
24
  }
24
25
  function AlertDialogContent({ className, ...props }) {
25
- return /* @__PURE__ */ jsxs(AlertDialog.Portal, { children: [/* @__PURE__ */ jsx(AlertDialog.Overlay, {
26
+ return /* @__PURE__ */ jsxs(Portal, { children: [/* @__PURE__ */ jsx(Overlay, {
26
27
  "data-slot": "alert-dialog-overlay",
27
28
  className: "fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in"
28
- }), /* @__PURE__ */ jsx(AlertDialog.Content, {
29
+ }), /* @__PURE__ */ jsx(Content, {
29
30
  "data-slot": "alert-dialog-content",
30
31
  className: cn("fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-md max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-[0_24px_80px_rgb(0_0_0_/_0.28)] outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6", className),
31
32
  ...props
@@ -46,14 +47,14 @@ function AlertDialogFooter({ className, ...props }) {
46
47
  });
47
48
  }
48
49
  function AlertDialogTitle({ className, ...props }) {
49
- return /* @__PURE__ */ jsx(AlertDialog.Title, {
50
+ return /* @__PURE__ */ jsx(Title, {
50
51
  "data-slot": "alert-dialog-title",
51
52
  className: cn("text-base font-semibold tracking-[-0.02em]", className),
52
53
  ...props
53
54
  });
54
55
  }
55
56
  function AlertDialogDescription({ className, ...props }) {
56
- return /* @__PURE__ */ jsx(AlertDialog.Description, {
57
+ return /* @__PURE__ */ jsx(Description, {
57
58
  "data-slot": "alert-dialog-description",
58
59
  className: cn("text-sm leading-5 text-muted-foreground", className),
59
60
  ...props
@@ -61,20 +62,20 @@ function AlertDialogDescription({ className, ...props }) {
61
62
  }
62
63
  /** The confirming button. `destructive` paints it as a danger action. */
63
64
  function AlertDialogAction({ className, destructive = false, ...props }) {
64
- return /* @__PURE__ */ jsx(AlertDialog.Action, {
65
+ return /* @__PURE__ */ jsx(Action, {
65
66
  "data-slot": "alert-dialog-action",
66
67
  className: cn(buttonVariants({ variant: destructive ? "destructive" : "default" }), className),
67
68
  ...props
68
69
  });
69
70
  }
70
71
  function AlertDialogCancel({ className, ...props }) {
71
- return /* @__PURE__ */ jsx(AlertDialog.Cancel, {
72
+ return /* @__PURE__ */ jsx(Cancel, {
72
73
  "data-slot": "alert-dialog-cancel",
73
74
  className: cn(buttonVariants({ variant: "outline" }), className),
74
75
  ...props
75
76
  });
76
77
  }
77
78
  //#endregion
78
- export { AlertDialog$1 as AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger };
79
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger };
79
80
 
80
81
  //# sourceMappingURL=alert-dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alert-dialog.js","names":["AlertDialog","AlertDialogPrimitive"],"sources":["../../src/components/alert-dialog.tsx"],"sourcesContent":["import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { buttonVariants } from './button';\n\n/**\n * A confirmation that interrupts: \"Delete 3 keys?\", \"Revoke access?\". Unlike\n * Dialog it has no close button and ignores outside clicks, so the person\n * answers it; Escape still cancels. Focus starts on Cancel.\n */\nfunction AlertDialog(props: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n}\n\nfunction AlertDialogTrigger(props: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n return <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />;\n}\n\nfunction AlertDialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n return (\n <AlertDialogPrimitive.Portal>\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className=\"fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in\"\n />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n 'fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-md max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-[0_24px_80px_rgb(0_0_0_/_0.28)] outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6',\n className,\n )}\n {...props}\n />\n </AlertDialogPrimitive.Portal>\n );\n}\n\nfunction AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"alert-dialog-header\" className={cn('grid gap-1.5', className)} {...props} />\n );\n}\n\nfunction AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn('text-base font-semibold tracking-[-0.02em]', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn('text-sm leading-5 text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\n/** The confirming button. `destructive` paints it as a danger action. */\nfunction AlertDialogAction({\n className,\n destructive = false,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action> & { destructive?: boolean }) {\n return (\n <AlertDialogPrimitive.Action\n data-slot=\"alert-dialog-action\"\n className={cn(\n buttonVariants({ variant: destructive ? 'destructive' : 'default' }),\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogCancel({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n return (\n <AlertDialogPrimitive.Cancel\n data-slot=\"alert-dialog-cancel\"\n className={cn(buttonVariants({ variant: 'outline' }), className)}\n {...props}\n />\n );\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n};\n"],"mappings":";;;;;;;;;;;AAYA,SAASA,cAAY,OAA+D;CAClF,OAAO,oBAACC,YAAqB,MAAtB;EAA2B,aAAU;EAAe,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,mBAAmB,OAAkE;CAC5F,OAAO,oBAACA,YAAqB,SAAtB;EAA8B,aAAU;EAAuB,GAAI;CAAQ,CAAA;AACpF;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,qBAACA,YAAqB,QAAtB,EAAA,UAAA,CACE,oBAACA,YAAqB,SAAtB;EACE,aAAU;EACV,WAAU;CACX,CAAA,GACD,oBAACA,YAAqB,SAAtB;EACE,aAAU;EACV,WAAW,GACT,2YACA,SACF;EACA,GAAI;CACL,CAAA,CAC0B,EAAA,CAAA;AAEjC;AAEA,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAsC;CAC/E,OACE,oBAAC,OAAD;EAAK,aAAU;EAAsB,WAAW,GAAG,gBAAgB,SAAS;EAAG,GAAI;CAAQ,CAAA;AAE/F;AAEA,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAsC;CAC/E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,0DAA0D,SAAS;EACjF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAACA,YAAqB,OAAtB;EACE,aAAU;EACV,WAAW,GAAG,8CAA8C,SAAS;EACrE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACA,YAAqB,aAAtB;EACE,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,kBAAkB,EACzB,WACA,cAAc,OACd,GAAG,SACoF;CACvF,OACE,oBAACA,YAAqB,QAAtB;EACE,aAAU;EACV,WAAW,GACT,eAAe,EAAE,SAAS,cAAc,gBAAgB,UAAU,CAAC,GACnE,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,kBAAkB,EACzB,WACA,GAAG,SACwD;CAC3D,OACE,oBAACA,YAAqB,QAAtB;EACE,aAAU;EACV,WAAW,GAAG,eAAe,EAAE,SAAS,UAAU,CAAC,GAAG,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"alert-dialog.js","names":["AlertDialogPrimitive.Root","AlertDialogPrimitive.Trigger","AlertDialogPrimitive.Portal","AlertDialogPrimitive.Overlay","AlertDialogPrimitive.Content","AlertDialogPrimitive.Title","AlertDialogPrimitive.Description","AlertDialogPrimitive.Action","AlertDialogPrimitive.Cancel"],"sources":["../../src/components/alert-dialog.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as AlertDialogPrimitive from '../primitives/vendor/radix/react-alert-dialog';\n\nimport { buttonVariants } from './button';\n\n/**\n * A confirmation that interrupts: \"Delete 3 keys?\", \"Revoke access?\". Unlike\n * Dialog it has no close button and ignores outside clicks, so the person\n * answers it; Escape still cancels. Focus starts on Cancel.\n */\nfunction AlertDialog(props: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n}\n\nfunction AlertDialogTrigger(props: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n return <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />;\n}\n\nfunction AlertDialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n return (\n <AlertDialogPrimitive.Portal>\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className=\"fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in\"\n />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n 'fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-md max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-[0_24px_80px_rgb(0_0_0_/_0.28)] outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6',\n className,\n )}\n {...props}\n />\n </AlertDialogPrimitive.Portal>\n );\n}\n\nfunction AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"alert-dialog-header\" className={cn('grid gap-1.5', className)} {...props} />\n );\n}\n\nfunction AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn('text-base font-semibold tracking-[-0.02em]', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn('text-sm leading-5 text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\n/** The confirming button. `destructive` paints it as a danger action. */\nfunction AlertDialogAction({\n className,\n destructive = false,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action> & { destructive?: boolean }) {\n return (\n <AlertDialogPrimitive.Action\n data-slot=\"alert-dialog-action\"\n className={cn(\n buttonVariants({ variant: destructive ? 'destructive' : 'default' }),\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AlertDialogCancel({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n return (\n <AlertDialogPrimitive.Cancel\n data-slot=\"alert-dialog-cancel\"\n className={cn(buttonVariants({ variant: 'outline' }), className)}\n {...props}\n />\n );\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n};\n"],"mappings":";;;;;;;;;;;;AAYA,SAAS,YAAY,OAA+D;CAClF,OAAO,oBAACA,MAAD;EAA2B,aAAU;EAAe,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,mBAAmB,OAAkE;CAC5F,OAAO,oBAACC,SAAD;EAA8B,aAAU;EAAuB,GAAI;CAAQ,CAAA;AACpF;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,qBAACC,QAAD,EAAA,UAAA,CACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAU;CACX,CAAA,GACD,oBAACC,SAAD;EACE,aAAU;EACV,WAAW,GACT,2YACA,SACF;EACA,GAAI;CACL,CAAA,CAC0B,EAAA,CAAA;AAEjC;AAEA,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAsC;CAC/E,OACE,oBAAC,OAAD;EAAK,aAAU;EAAsB,WAAW,GAAG,gBAAgB,SAAS;EAAG,GAAI;CAAQ,CAAA;AAE/F;AAEA,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAsC;CAC/E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,0DAA0D,SAAS;EACjF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAACC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,8CAA8C,SAAS;EACrE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACC,aAAD;EACE,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,kBAAkB,EACzB,WACA,cAAc,OACd,GAAG,SACoF;CACvF,OACE,oBAACC,QAAD;EACE,aAAU;EACV,WAAW,GACT,eAAe,EAAE,SAAS,cAAc,gBAAgB,UAAU,CAAC,GACnE,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,kBAAkB,EACzB,WACA,GAAG,SACwD;CAC3D,OACE,oBAACC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,eAAe,EAAE,SAAS,UAAU,CAAC,GAAG,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import "react";
3
4
  import { jsx } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"alert.js","names":[],"sources":["../../src/components/alert.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nconst alertVariants = cva(\n 'group/alert relative grid w-full grid-cols-1 has-[>svg]:grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 rounded-lg border px-4 py-3.5 text-sm shadow-xs [&>svg]:mt-0.5 [&>svg]:size-4',\n {\n variants: {\n variant: {\n default: 'border-border bg-surface text-foreground [&>svg]:text-muted-foreground',\n brand: 'border-brand/25 bg-brand-soft/70 text-foreground [&>svg]:text-brand',\n success: 'border-success/25 bg-success/10 text-foreground [&>svg]:text-success',\n warning: 'border-warning/25 bg-warning/10 text-foreground [&>svg]:text-warning',\n destructive:\n 'border-destructive/25 bg-destructive/10 text-foreground [&>svg]:text-destructive',\n info: 'border-info/25 bg-info/10 text-foreground [&>svg]:text-info',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n);\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn('font-semibold tracking-[-0.01em]', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n 'col-start-1 group-has-[>svg]/alert:col-start-2 text-[13px] leading-5 text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Alert, AlertDescription, AlertTitle, alertVariants };\n"],"mappings":";;;;;AAKA,IAAM,gBAAgB,IACpB,gLACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,aACE;EACF,MAAM;CACR,EACF;CACA,iBAAiB,EAAE,SAAS,UAAU;AACxC,CACF;AAEA,SAAS,MAAM,EACb,WACA,SACA,GAAG,SACgE;CACnE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,oCAAoC,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EAAE,WAAW,GAAG,SAAsC;CAC9E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,8FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"alert.js","names":[],"sources":["../../src/components/alert.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nconst alertVariants = cva(\n 'group/alert relative grid w-full grid-cols-1 has-[>svg]:grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 rounded-lg border px-4 py-3.5 text-sm shadow-xs [&>svg]:mt-0.5 [&>svg]:size-4',\n {\n variants: {\n variant: {\n default: 'border-border bg-surface text-foreground [&>svg]:text-muted-foreground',\n brand: 'border-brand/25 bg-brand-soft/70 text-foreground [&>svg]:text-brand',\n success: 'border-success/25 bg-success/10 text-foreground [&>svg]:text-success',\n warning: 'border-warning/25 bg-warning/10 text-foreground [&>svg]:text-warning',\n destructive:\n 'border-destructive/25 bg-destructive/10 text-foreground [&>svg]:text-destructive',\n info: 'border-info/25 bg-info/10 text-foreground [&>svg]:text-info',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n);\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn('font-semibold tracking-[-0.01em]', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n 'col-start-1 group-has-[>svg]/alert:col-start-2 text-[13px] leading-5 text-muted-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Alert, AlertDescription, AlertTitle, alertVariants };\n"],"mappings":";;;;;;AAKA,IAAM,gBAAgB,IACpB,gLACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,aACE;EACF,MAAM;CACR,EACF;CACA,iBAAiB,EAAE,SAAS,UAAU;AACxC,CACF;AAEA,SAAS,MAAM,EACb,WACA,SACA,GAAG,SACgE;CACnE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,oCAAoC,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EAAE,WAAW,GAAG,SAAsC;CAC9E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,8FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import "react";
3
4
  import { jsx } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"app-shell.js","names":[],"sources":["../../src/components/app-shell.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction AppShell({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"app-shell\"\n className={cn('grid min-h-dvh grid-rows-[auto_1fr] bg-background text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellHeader({ className, ...props }: React.ComponentProps<'header'>) {\n return (\n <header\n data-slot=\"app-shell-header\"\n className={cn(\n 'sticky top-0 z-40 flex h-12 items-center border-b border-border bg-background/90 px-3 backdrop-blur-xl sm:px-4',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AppShellBody({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"app-shell-body\"\n className={cn('grid min-h-0 grid-cols-1', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellSidebar({ className, ...props }: React.ComponentProps<'aside'>) {\n return (\n <aside\n data-slot=\"app-shell-sidebar\"\n className={cn('min-h-0 border-r border-border bg-surface-muted/55', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellMain({ className, ...props }: React.ComponentProps<'main'>) {\n return (\n <main\n data-slot=\"app-shell-main\"\n className={cn('min-w-0 bg-background', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"app-shell-content\"\n className={cn('mx-auto w-full max-w-[1600px] p-4 sm:p-6', className)}\n {...props}\n />\n );\n}\n\nexport { AppShell, AppShellBody, AppShellContent, AppShellHeader, AppShellMain, AppShellSidebar };\n"],"mappings":";;;;AAIA,SAAS,SAAS,EAAE,WAAW,GAAG,SAAsC;CACtE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,qEAAqE,SAAS;EAC5F,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAyC;CAC/E,OACE,oBAAC,UAAD;EACE,aAAU;EACV,WAAW,GACT,kHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAsC;CAC1E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAwC;CAC/E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,sDAAsD,SAAS;EAC7E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAuC;CAC3E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,yBAAyB,SAAS;EAChD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"app-shell.js","names":[],"sources":["../../src/components/app-shell.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction AppShell({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"app-shell\"\n className={cn('grid min-h-dvh grid-rows-[auto_1fr] bg-background text-foreground', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellHeader({ className, ...props }: React.ComponentProps<'header'>) {\n return (\n <header\n data-slot=\"app-shell-header\"\n className={cn(\n 'sticky top-0 z-40 flex h-12 items-center border-b border-border bg-background/90 px-3 backdrop-blur-xl sm:px-4',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AppShellBody({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"app-shell-body\"\n className={cn('grid min-h-0 grid-cols-1', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellSidebar({ className, ...props }: React.ComponentProps<'aside'>) {\n return (\n <aside\n data-slot=\"app-shell-sidebar\"\n className={cn('min-h-0 border-r border-border bg-surface-muted/55', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellMain({ className, ...props }: React.ComponentProps<'main'>) {\n return (\n <main\n data-slot=\"app-shell-main\"\n className={cn('min-w-0 bg-background', className)}\n {...props}\n />\n );\n}\n\nfunction AppShellContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"app-shell-content\"\n className={cn('mx-auto w-full max-w-[1600px] p-4 sm:p-6', className)}\n {...props}\n />\n );\n}\n\nexport { AppShell, AppShellBody, AppShellContent, AppShellHeader, AppShellMain, AppShellSidebar };\n"],"mappings":";;;;;AAIA,SAAS,SAAS,EAAE,WAAW,GAAG,SAAsC;CACtE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,qEAAqE,SAAS;EAC5F,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAyC;CAC/E,OACE,oBAAC,UAAD;EACE,aAAU;EACV,WAAW,GACT,kHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAsC;CAC1E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAwC;CAC/E,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,sDAAsD,SAAS;EAC7E,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAuC;CAC3E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,yBAAyB,SAAS;EAChD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { Button } from "./button.js";
3
4
  import { Progress } from "./progress.js";
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.js","names":[],"sources":["../../src/components/attachment.tsx"],"sourcesContent":["import AlertCircle from '@burtson-labs/icons/react/alert-circle';\nimport FileText from '@burtson-labs/icons/react/file-text';\nimport RotateCw from '@burtson-labs/icons/react/rotate-cw';\nimport X from '@burtson-labs/icons/react/x';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\nimport { Progress } from './progress';\nimport { Spinner } from './spinner';\n\n/**\n * Where a file is on its way into a message. The app owns the upload and the\n * parsing; these components only show the state it reports.\n */\nexport type AttachmentState = 'queued' | 'uploading' | 'parsing' | 'ready' | 'failed';\n\nconst stateText: Record<AttachmentState, string> = {\n queued: 'Waiting',\n uploading: 'Uploading',\n parsing: 'Reading',\n ready: 'Ready',\n failed: 'Failed',\n};\n\n/** 1536 → \"1.5 KB\". */\nexport function formatBytes(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return '';\n if (bytes < 1024) return `${bytes} B`;\n const units = ['KB', 'MB', 'GB', 'TB'];\n let value = bytes / 1024;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) {\n value /= 1024;\n unit++;\n }\n return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;\n}\n\nconst InTray = React.createContext(false);\n\nexport interface AttachmentItemProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n name: string;\n /** Bytes. */\n size?: number;\n state?: AttachmentState;\n /** 0–100 while uploading or reading. Leave out for an indeterminate bar. */\n progress?: number;\n /** Why it failed, in words the person can act on. */\n error?: string;\n /** A thumbnail URL for images. */\n preview?: string;\n /** Replaces the file icon. */\n icon?: React.ReactNode;\n onRemove?: () => void;\n onRetry?: () => void;\n /** `chip` sits in a composer; `row` fills an upload list. */\n layout?: 'chip' | 'row';\n}\n\n/**\n * One attached file: name, size, state, progress, and remove/retry. State\n * changes are announced politely; a failure says why.\n */\nfunction AttachmentItem({\n name,\n size,\n state = 'ready',\n progress,\n error,\n preview,\n icon,\n onRemove,\n onRetry,\n layout = 'chip',\n className,\n ...props\n}: AttachmentItemProps) {\n const inTray = React.useContext(InTray);\n const busy = state === 'uploading' || state === 'parsing';\n const failed = state === 'failed';\n const meta = [size !== undefined ? formatBytes(size) : null, stateText[state]]\n .filter(Boolean)\n .join(' · ');\n return (\n <div\n data-slot=\"attachment-item\"\n data-state={state}\n data-layout={layout}\n role={inTray ? 'listitem' : undefined}\n aria-busy={busy || undefined}\n className={cn(\n 'group/attachment relative flex min-w-0 items-center gap-2.5 rounded-md border bg-surface text-sm',\n layout === 'chip' ? 'w-60 max-w-full shrink-0 p-1.5 pr-1' : 'w-full p-2.5',\n failed && 'border-destructive/40 bg-destructive/5',\n className,\n )}\n {...props}\n >\n <div\n className={cn(\n 'grid shrink-0 place-items-center overflow-hidden rounded-sm bg-muted text-muted-foreground [&_svg]:size-4',\n layout === 'chip' ? 'size-9' : 'size-10',\n )}\n >\n {preview ? (\n <img src={preview} alt=\"\" className=\"size-full object-cover\" />\n ) : failed ? (\n <AlertCircle className=\"text-destructive\" aria-hidden />\n ) : busy ? (\n <Spinner className=\"size-4\" role=\"presentation\" aria-hidden />\n ) : (\n (icon ?? <FileText aria-hidden />)\n )}\n </div>\n <div className=\"grid min-w-0 flex-1 gap-1\">\n <span className=\"truncate font-medium text-foreground\" title={name}>\n {name}\n </span>\n <span\n aria-live=\"polite\"\n className={cn('truncate text-xs', failed ? 'text-destructive' : 'text-muted-foreground')}\n >\n <span className=\"sr-only\">{name}: </span>\n {failed && error ? error : meta}\n </span>\n {busy && (\n <Progress value={progress} aria-label={`${stateText[state]} ${name}`} className=\"h-1\" />\n )}\n </div>\n {failed && onRetry && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`Retry ${name}`}\n title=\"Retry\"\n onClick={onRetry}\n >\n <RotateCw />\n </Button>\n )}\n {onRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`Remove ${name}`}\n title=\"Remove\"\n onClick={onRemove}\n >\n <X />\n </Button>\n )}\n </div>\n );\n}\n\nexport interface AttachmentTrayProps extends React.ComponentProps<'div'> {\n /** Accessible name for the list. */\n label?: string;\n}\n\n/** Attachments waiting to send, in a row that scrolls sideways when full. */\nfunction AttachmentTray({\n label = 'Attachments',\n className,\n children,\n ...props\n}: AttachmentTrayProps) {\n return (\n <InTray.Provider value={true}>\n <div\n data-slot=\"attachment-tray\"\n role=\"list\"\n aria-label={label}\n className={cn('flex max-w-full gap-1.5 overflow-x-auto pb-0.5', className)}\n {...props}\n >\n {children}\n </div>\n </InTray.Provider>\n );\n}\n\nexport interface UploadQueueFile {\n id: string;\n name: string;\n size?: number;\n state: AttachmentState;\n progress?: number;\n error?: string;\n}\n\nexport interface UploadQueueProps extends Omit<React.ComponentProps<'section'>, 'title'> {\n files: UploadQueueFile[];\n title?: React.ReactNode;\n onRemove?: (id: string) => void;\n onRetry?: (id: string) => void;\n /** Shown when there are no files. */\n empty?: React.ReactNode;\n}\n\n/** A list of uploads with a summary: \"2 of 4 ready, 1 failed\". */\nfunction UploadQueue({\n files,\n title = 'Uploads',\n onRemove,\n onRetry,\n empty,\n className,\n ...props\n}: UploadQueueProps) {\n const headingId = React.useId();\n const ready = files.filter((f) => f.state === 'ready').length;\n const failed = files.filter((f) => f.state === 'failed').length;\n const summary = files.length\n ? `${ready} of ${files.length} ready${failed ? `, ${failed} failed` : ''}`\n : '';\n return (\n <section\n data-slot=\"upload-queue\"\n aria-labelledby={headingId}\n className={cn('grid gap-2', className)}\n {...props}\n >\n <div className=\"flex items-baseline justify-between gap-3\">\n <h3 id={headingId} className=\"text-sm font-semibold\">\n {title}\n </h3>\n <span className=\"text-xs text-muted-foreground tabular-nums\">{summary}</span>\n </div>\n {files.length === 0 ? (\n empty ? (\n <div className=\"text-sm text-muted-foreground\">{empty}</div>\n ) : null\n ) : (\n <InTray.Provider value={true}>\n <div role=\"list\" aria-labelledby={headingId} className=\"grid gap-1.5\">\n {files.map((f) => (\n <AttachmentItem\n key={f.id}\n layout=\"row\"\n name={f.name}\n size={f.size}\n state={f.state}\n progress={f.progress}\n error={f.error}\n onRemove={onRemove ? () => onRemove(f.id) : undefined}\n onRetry={onRetry ? () => onRetry(f.id) : undefined}\n />\n ))}\n </div>\n </InTray.Provider>\n )}\n </section>\n );\n}\n\nexport { AttachmentItem, AttachmentTray, UploadQueue };\n"],"mappings":";;;;;;;;;;;AAkBA,IAAM,YAA6C;CACjD,QAAQ;CACR,WAAW;CACX,SAAS;CACT,OAAO;CACP,QAAQ;AACV;;AAGA,SAAgB,YAAY,OAAuB;CACjD,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG,OAAO;CACjD,IAAI,QAAQ,MAAM,OAAO,GAAG,MAAM;CAClC,MAAM,QAAQ;EAAC;EAAM;EAAM;EAAM;CAAI;CACrC,IAAI,QAAQ,QAAQ;CACpB,IAAI,OAAO;CACX,OAAO,SAAS,QAAQ,OAAO,MAAM,SAAS,GAAG;EAC/C,SAAS;EACT;CACF;CACA,OAAO,GAAG,QAAQ,KAAK,MAAM,QAAQ,CAAC,IAAI,KAAK,MAAM,KAAK,EAAE,GAAG,MAAM;AACvE;AAEA,IAAM,SAAS,MAAM,cAAc,KAAK;;;;;AAyBxC,SAAS,eAAe,EACtB,MACA,MACA,QAAQ,SACR,UACA,OACA,SACA,MACA,UACA,SACA,SAAS,QACT,WACA,GAAG,SACmB;CACtB,MAAM,SAAS,MAAM,WAAW,MAAM;CACtC,MAAM,OAAO,UAAU,eAAe,UAAU;CAChD,MAAM,SAAS,UAAU;CACzB,MAAM,OAAO,CAAC,SAAS,KAAA,IAAY,YAAY,IAAI,IAAI,MAAM,UAAU,MAAM,CAAC,CAC3E,OAAO,OAAO,CAAC,CACf,KAAK,KAAK;CACb,OACE,qBAAC,OAAD;EACE,aAAU;EACV,cAAY;EACZ,eAAa;EACb,MAAM,SAAS,aAAa,KAAA;EAC5B,aAAW,QAAQ,KAAA;EACnB,WAAW,GACT,oGACA,WAAW,SAAS,wCAAwC,gBAC5D,UAAU,0CACV,SACF;EACA,GAAI;EAZN,UAAA;GAcE,oBAAC,OAAD;IACE,WAAW,GACT,6GACA,WAAW,SAAS,WAAW,SACjC;IAEC,UAAA,UACC,oBAAC,OAAD;KAAK,KAAK;KAAS,KAAI;KAAG,WAAU;IAA0B,CAAA,IAC5D,SACF,oBAAC,aAAD;KAAa,WAAU;KAAmB,eAAA;IAAa,CAAA,IACrD,OACF,oBAAC,SAAD;KAAS,WAAU;KAAS,MAAK;KAAe,eAAA;IAAa,CAAA,IAE5D,QAAQ,oBAAC,UAAD,EAAU,eAAA,KAAa,CAAA;GAE/B,CAAA;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,QAAD;MAAM,WAAU;MAAuC,OAAO;MAC3D,UAAA;KACG,CAAA;KACN,qBAAC,QAAD;MACE,aAAU;MACV,WAAW,GAAG,oBAAoB,SAAS,qBAAqB,uBAAuB;MAFzF,UAAA,CAIE,qBAAC,QAAD;OAAM,WAAU;OAAhB,UAAA,CAA2B,MAAK,IAAQ;MACvC,CAAA,GAAA,UAAU,QAAQ,QAAQ,IACvB;;KACL,QACC,oBAAC,UAAD;MAAU,OAAO;MAAU,cAAY,GAAG,UAAU,OAAO,GAAG;MAAQ,WAAU;KAAO,CAAA;IAEtF;;GACJ,UAAU,WACT,oBAAC,QAAD;IACE,MAAK;IACL,SAAQ;IACR,MAAK;IACL,cAAY,SAAS;IACrB,OAAM;IACN,SAAS;IAET,UAAA,oBAAC,UAAD,CAAW,CAAA;GACL,CAAA;GAET,YACC,oBAAC,QAAD;IACE,MAAK;IACL,SAAQ;IACR,MAAK;IACL,cAAY,UAAU;IACtB,OAAM;IACN,SAAS;IAET,UAAA,oBAAC,GAAD,CAAI,CAAA;GACE,CAAA;EAEP;;AAET;;AAQA,SAAS,eAAe,EACtB,QAAQ,eACR,WACA,UACA,GAAG,SACmB;CACtB,OACE,oBAAC,OAAO,UAAR;EAAiB,OAAO;EACtB,UAAA,oBAAC,OAAD;GACE,aAAU;GACV,MAAK;GACL,cAAY;GACZ,WAAW,GAAG,kDAAkD,SAAS;GACzE,GAAI;GAEH;EACE,CAAA;CACU,CAAA;AAErB;;AAqBA,SAAS,YAAY,EACnB,OACA,QAAQ,WACR,UACA,SACA,OACA,WACA,GAAG,SACgB;CACnB,MAAM,YAAY,MAAM,MAAM;CAC9B,MAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,UAAU,OAAO,CAAC,CAAC;CACvD,MAAM,SAAS,MAAM,QAAQ,MAAM,EAAE,UAAU,QAAQ,CAAC,CAAC;CACzD,MAAM,UAAU,MAAM,SAClB,GAAG,MAAM,MAAM,MAAM,OAAO,QAAQ,SAAS,KAAK,OAAO,WAAW,OACpE;CACJ,OACE,qBAAC,WAAD;EACE,aAAU;EACV,mBAAiB;EACjB,WAAW,GAAG,cAAc,SAAS;EACrC,GAAI;EAJN,UAAA,CAME,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,MAAD;IAAI,IAAI;IAAW,WAAU;IAC1B,UAAA;GACC,CAAA,GACJ,oBAAC,QAAD;IAAM,WAAU;IAA8C,UAAA;GAAc,CAAA,CACzE;EACJ,CAAA,GAAA,MAAM,WAAW,IAChB,QACE,oBAAC,OAAD;GAAK,WAAU;GAAiC,UAAA;EAAW,CAAA,IACzD,OAEJ,oBAAC,OAAO,UAAR;GAAiB,OAAO;GACtB,UAAA,oBAAC,OAAD;IAAK,MAAK;IAAO,mBAAiB;IAAW,WAAU;IACpD,UAAA,MAAM,KAAK,MACV,oBAAC,gBAAD;KAEE,QAAO;KACP,MAAM,EAAE;KACR,MAAM,EAAE;KACR,OAAO,EAAE;KACT,UAAU,EAAE;KACZ,OAAO,EAAE;KACT,UAAU,iBAAiB,SAAS,EAAE,EAAE,IAAI,KAAA;KAC5C,SAAS,gBAAgB,QAAQ,EAAE,EAAE,IAAI,KAAA;IAC1C,GATM,EAAE,EASR,CACF;GACE,CAAA;EACU,CAAA,CAEZ;;AAEb"}
1
+ {"version":3,"file":"attachment.js","names":[],"sources":["../../src/components/attachment.tsx"],"sourcesContent":["import AlertCircle from '@burtson-labs/icons/react/alert-circle';\nimport FileText from '@burtson-labs/icons/react/file-text';\nimport RotateCw from '@burtson-labs/icons/react/rotate-cw';\nimport X from '@burtson-labs/icons/react/x';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\nimport { Progress } from './progress';\nimport { Spinner } from './spinner';\n\n/**\n * Where a file is on its way into a message. The app owns the upload and the\n * parsing; these components only show the state it reports.\n */\nexport type AttachmentState = 'queued' | 'uploading' | 'parsing' | 'ready' | 'failed';\n\nconst stateText: Record<AttachmentState, string> = {\n queued: 'Waiting',\n uploading: 'Uploading',\n parsing: 'Reading',\n ready: 'Ready',\n failed: 'Failed',\n};\n\n/** 1536 → \"1.5 KB\". */\nexport function formatBytes(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return '';\n if (bytes < 1024) return `${bytes} B`;\n const units = ['KB', 'MB', 'GB', 'TB'];\n let value = bytes / 1024;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) {\n value /= 1024;\n unit++;\n }\n return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit]}`;\n}\n\nconst InTray = React.createContext(false);\n\nexport interface AttachmentItemProps extends Omit<React.ComponentProps<'div'>, 'children'> {\n name: string;\n /** Bytes. */\n size?: number;\n state?: AttachmentState;\n /** 0–100 while uploading or reading. Leave out for an indeterminate bar. */\n progress?: number;\n /** Why it failed, in words the person can act on. */\n error?: string;\n /** A thumbnail URL for images. */\n preview?: string;\n /** Replaces the file icon. */\n icon?: React.ReactNode;\n onRemove?: () => void;\n onRetry?: () => void;\n /** `chip` sits in a composer; `row` fills an upload list. */\n layout?: 'chip' | 'row';\n}\n\n/**\n * One attached file: name, size, state, progress, and remove/retry. State\n * changes are announced politely; a failure says why.\n */\nfunction AttachmentItem({\n name,\n size,\n state = 'ready',\n progress,\n error,\n preview,\n icon,\n onRemove,\n onRetry,\n layout = 'chip',\n className,\n ...props\n}: AttachmentItemProps) {\n const inTray = React.useContext(InTray);\n const busy = state === 'uploading' || state === 'parsing';\n const failed = state === 'failed';\n const meta = [size !== undefined ? formatBytes(size) : null, stateText[state]]\n .filter(Boolean)\n .join(' · ');\n return (\n <div\n data-slot=\"attachment-item\"\n data-state={state}\n data-layout={layout}\n role={inTray ? 'listitem' : undefined}\n aria-busy={busy || undefined}\n className={cn(\n 'group/attachment relative flex min-w-0 items-center gap-2.5 rounded-md border bg-surface text-sm',\n layout === 'chip' ? 'w-60 max-w-full shrink-0 p-1.5 pr-1' : 'w-full p-2.5',\n failed && 'border-destructive/40 bg-destructive/5',\n className,\n )}\n {...props}\n >\n <div\n className={cn(\n 'grid shrink-0 place-items-center overflow-hidden rounded-sm bg-muted text-muted-foreground [&_svg]:size-4',\n layout === 'chip' ? 'size-9' : 'size-10',\n )}\n >\n {preview ? (\n <img src={preview} alt=\"\" className=\"size-full object-cover\" />\n ) : failed ? (\n <AlertCircle className=\"text-destructive\" aria-hidden />\n ) : busy ? (\n <Spinner className=\"size-4\" role=\"presentation\" aria-hidden />\n ) : (\n (icon ?? <FileText aria-hidden />)\n )}\n </div>\n <div className=\"grid min-w-0 flex-1 gap-1\">\n <span className=\"truncate font-medium text-foreground\" title={name}>\n {name}\n </span>\n <span\n aria-live=\"polite\"\n className={cn('truncate text-xs', failed ? 'text-destructive' : 'text-muted-foreground')}\n >\n <span className=\"sr-only\">{name}: </span>\n {failed && error ? error : meta}\n </span>\n {busy && (\n <Progress value={progress} aria-label={`${stateText[state]} ${name}`} className=\"h-1\" />\n )}\n </div>\n {failed && onRetry && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`Retry ${name}`}\n title=\"Retry\"\n onClick={onRetry}\n >\n <RotateCw />\n </Button>\n )}\n {onRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`Remove ${name}`}\n title=\"Remove\"\n onClick={onRemove}\n >\n <X />\n </Button>\n )}\n </div>\n );\n}\n\nexport interface AttachmentTrayProps extends React.ComponentProps<'div'> {\n /** Accessible name for the list. */\n label?: string;\n}\n\n/** Attachments waiting to send, in a row that scrolls sideways when full. */\nfunction AttachmentTray({\n label = 'Attachments',\n className,\n children,\n ...props\n}: AttachmentTrayProps) {\n return (\n <InTray.Provider value={true}>\n <div\n data-slot=\"attachment-tray\"\n role=\"list\"\n aria-label={label}\n className={cn('flex max-w-full gap-1.5 overflow-x-auto pb-0.5', className)}\n {...props}\n >\n {children}\n </div>\n </InTray.Provider>\n );\n}\n\nexport interface UploadQueueFile {\n id: string;\n name: string;\n size?: number;\n state: AttachmentState;\n progress?: number;\n error?: string;\n}\n\nexport interface UploadQueueProps extends Omit<React.ComponentProps<'section'>, 'title'> {\n files: UploadQueueFile[];\n title?: React.ReactNode;\n onRemove?: (id: string) => void;\n onRetry?: (id: string) => void;\n /** Shown when there are no files. */\n empty?: React.ReactNode;\n}\n\n/** A list of uploads with a summary: \"2 of 4 ready, 1 failed\". */\nfunction UploadQueue({\n files,\n title = 'Uploads',\n onRemove,\n onRetry,\n empty,\n className,\n ...props\n}: UploadQueueProps) {\n const headingId = React.useId();\n const ready = files.filter((f) => f.state === 'ready').length;\n const failed = files.filter((f) => f.state === 'failed').length;\n const summary = files.length\n ? `${ready} of ${files.length} ready${failed ? `, ${failed} failed` : ''}`\n : '';\n return (\n <section\n data-slot=\"upload-queue\"\n aria-labelledby={headingId}\n className={cn('grid gap-2', className)}\n {...props}\n >\n <div className=\"flex items-baseline justify-between gap-3\">\n <h3 id={headingId} className=\"text-sm font-semibold\">\n {title}\n </h3>\n <span className=\"text-xs text-muted-foreground tabular-nums\">{summary}</span>\n </div>\n {files.length === 0 ? (\n empty ? (\n <div className=\"text-sm text-muted-foreground\">{empty}</div>\n ) : null\n ) : (\n <InTray.Provider value={true}>\n <div role=\"list\" aria-labelledby={headingId} className=\"grid gap-1.5\">\n {files.map((f) => (\n <AttachmentItem\n key={f.id}\n layout=\"row\"\n name={f.name}\n size={f.size}\n state={f.state}\n progress={f.progress}\n error={f.error}\n onRemove={onRemove ? () => onRemove(f.id) : undefined}\n onRetry={onRetry ? () => onRetry(f.id) : undefined}\n />\n ))}\n </div>\n </InTray.Provider>\n )}\n </section>\n );\n}\n\nexport { AttachmentItem, AttachmentTray, UploadQueue };\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
3
  import { Button } from "./button.js";
3
4
  import * as React from "react";
@@ -1 +1 @@
1
- {"version":3,"file":"audio-player.js","names":[],"sources":["../../src/components/audio-player.tsx"],"sourcesContent":["import Download from '@burtson-labs/icons/react/download';\nimport FileText from '@burtson-labs/icons/react/file-text';\nimport Pause from '@burtson-labs/icons/react/pause';\nimport Play from '@burtson-labs/icons/react/play';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\n\n/** 83.4 → \"1:23\"; 3723 → \"1:02:03\". */\nexport function formatDuration(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return '0:00';\n const s = Math.floor(seconds);\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const sec = String(s % 60).padStart(2, '0');\n return h ? `${h}:${String(m).padStart(2, '0')}:${sec}` : `${m}:${sec}`;\n}\n\n/**\n * Reduce decoded audio to `bars` peak heights between 0 and 1 (the loudest\n * sample in each slice, normalised to the loudest slice).\n */\nexport function peaksFromChannelData(data: Float32Array, bars = 48): number[] {\n if (!data.length || bars < 1) return [];\n const size = Math.max(1, Math.floor(data.length / bars));\n const peaks: number[] = [];\n for (let b = 0; b < bars; b++) {\n let max = 0;\n const end = Math.min(data.length, (b + 1) * size);\n for (let i = b * size; i < end; i++) {\n const v = Math.abs(data[i] ?? 0);\n if (v > max) max = v;\n }\n peaks.push(max);\n }\n const top = Math.max(...peaks) || 1;\n return peaks.map((p) => p / top);\n}\n\n/**\n * Decode an audio file or URL with Web Audio and return its peaks for\n * AudioPlayer. Browser only; for long files compute peaks on the server.\n */\nexport async function computePeaks(source: Blob | string, bars = 48): Promise<number[]> {\n const Ctx =\n globalThis.AudioContext ??\n (globalThis as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Ctx) throw new Error('Web Audio is not available in this browser.');\n const buf =\n typeof source === 'string'\n ? await (await fetch(source)).arrayBuffer()\n : await source.arrayBuffer();\n const ctx = new Ctx();\n try {\n const audio = await ctx.decodeAudioData(buf);\n return peaksFromChannelData(audio.getChannelData(0), bars);\n } finally {\n void ctx.close();\n }\n}\n\nconst SPEEDS = [1, 1.5, 2] as const;\n\nexport interface AudioPlayerProps extends Omit<React.ComponentProps<'div'>, 'title'> {\n src: string;\n /** Waveform heights 0–1 (see computePeaks). Leave out for a plain progress bar. */\n peaks?: number[];\n /** Name read out with the controls, e.g. \"Voice note from Dana\". */\n title?: string;\n /** Known length in seconds, shown before the file has loaded. */\n duration?: number;\n /** Text of the recording; adds a Transcript toggle. */\n transcript?: React.ReactNode;\n /** Adds a download link with this file name. */\n downloadName?: string;\n /** `compact` fits inside a message bubble. */\n variant?: 'default' | 'compact';\n onPlayChange?: (playing: boolean) => void;\n}\n\n/**\n * Plays one recording: play and pause, a waveform you can click or drive\n * with the arrow keys (5 seconds a step, Home and End), elapsed and total\n * time, speed (1×, 1.5×, 2×), download and a transcript. The waveform is a\n * slider for screen readers.\n */\nfunction AudioPlayer({\n src,\n peaks,\n title = 'Audio',\n duration: knownDuration,\n transcript,\n downloadName,\n variant = 'default',\n onPlayChange,\n className,\n ...props\n}: AudioPlayerProps) {\n const audio = React.useRef<HTMLAudioElement>(null);\n const [playing, setPlaying] = React.useState(false);\n const [current, setCurrent] = React.useState(0);\n const [duration, setDuration] = React.useState(knownDuration ?? 0);\n const [speed, setSpeed] = React.useState<(typeof SPEEDS)[number]>(1);\n const [showTranscript, setShowTranscript] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n const transcriptId = React.useId();\n const compact = variant === 'compact';\n const total = duration || knownDuration || 0;\n const ratio = total ? Math.min(1, current / total) : 0;\n\n React.useEffect(() => {\n if (audio.current) audio.current.playbackRate = speed;\n }, [speed]);\n\n const seek = (t: number) => {\n const el = audio.current;\n const clamped = Math.max(0, Math.min(total || t, t));\n if (el) el.currentTime = clamped;\n setCurrent(clamped);\n };\n\n const togglePlay = async () => {\n const el = audio.current;\n if (!el) return;\n if (el.paused) {\n try {\n await el.play();\n } catch {\n setFailed(true);\n }\n } else el.pause();\n };\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n const step = { ArrowRight: 5, ArrowUp: 5, ArrowLeft: -5, ArrowDown: -5 }[e.key];\n if (step !== undefined) {\n e.preventDefault();\n seek(current + step);\n } else if (e.key === 'Home') {\n e.preventDefault();\n seek(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n seek(total);\n } else if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n void togglePlay();\n }\n };\n\n const bars = peaks && peaks.length ? peaks : null;\n\n return (\n <div\n data-slot=\"audio-player\"\n data-variant={variant}\n className={cn(\n 'grid min-w-0 gap-2 rounded-lg border bg-surface text-foreground',\n compact ? 'w-full max-w-sm p-2' : 'p-3',\n className,\n )}\n {...props}\n >\n {/* eslint-disable-next-line jsx-a11y/media-has-caption -- the transcript prop is the text alternative */}\n <audio\n ref={audio}\n src={src}\n preload=\"metadata\"\n onLoadedMetadata={(e) => {\n const d = e.currentTarget.duration;\n if (Number.isFinite(d)) setDuration(d);\n }}\n onTimeUpdate={(e) => setCurrent(e.currentTarget.currentTime)}\n onPlay={() => {\n setPlaying(true);\n onPlayChange?.(true);\n }}\n onPause={() => {\n setPlaying(false);\n onPlayChange?.(false);\n }}\n onEnded={() => setCurrent(0)}\n onError={() => setFailed(true)}\n />\n <div className=\"flex min-w-0 items-center gap-2\">\n <Button\n type=\"button\"\n size={compact ? 'icon-sm' : 'icon'}\n variant={playing ? 'secondary' : 'default'}\n aria-label={playing ? `Pause ${title}` : `Play ${title}`}\n onClick={() => void togglePlay()}\n disabled={failed}\n className=\"shrink-0 rounded-full pointer-coarse:size-11\"\n >\n {playing ? <Pause className=\"fill-current\" /> : <Play className=\"fill-current\" />}\n </Button>\n <div\n role=\"slider\"\n tabIndex={failed ? -1 : 0}\n aria-label={`Seek ${title}`}\n aria-valuemin={0}\n aria-valuemax={Math.round(total)}\n aria-valuenow={Math.round(current)}\n aria-valuetext={`${formatDuration(current)} of ${formatDuration(total)}`}\n onKeyDown={onKeyDown}\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n if (!rect.width || !total) return;\n seek(((e.clientX - rect.left) / rect.width) * total);\n }}\n className={cn(\n 'relative flex min-w-0 flex-1 cursor-pointer items-center rounded-sm outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20',\n compact ? 'h-7' : 'h-9',\n )}\n >\n {bars ? (\n <div aria-hidden className=\"flex h-full w-full items-center gap-[2px]\">\n {bars.map((p, i) => (\n <span\n key={i}\n className={cn(\n 'min-w-[2px] flex-1 rounded-full transition-colors duration-[var(--duration-fast)] ease-[var(--ease-standard)]',\n (i + 0.5) / bars.length <= ratio ? 'bg-brand' : 'bg-border-strong',\n )}\n style={{ height: `${Math.max(12, Math.round(p * 100))}%` }}\n />\n ))}\n </div>\n ) : (\n <div aria-hidden className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\">\n <div className=\"h-full rounded-full bg-brand\" style={{ width: `${ratio * 100}%` }} />\n </div>\n )}\n </div>\n <span className=\"shrink-0 font-mono text-[11px] text-muted-foreground tabular-nums\">\n {playing || current ? formatDuration(current) : formatDuration(total)}\n </span>\n </div>\n {failed ? (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n This recording could not be played.\n </p>\n ) : (\n <div className=\"flex flex-wrap items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n aria-label={`Playback speed ${speed}×`}\n onClick={() => setSpeed(SPEEDS[(SPEEDS.indexOf(speed) + 1) % SPEEDS.length] ?? 1)}\n className=\"font-mono tabular-nums\"\n >\n {speed}×\n </Button>\n {transcript && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n aria-expanded={showTranscript}\n aria-controls={transcriptId}\n onClick={() => setShowTranscript((v) => !v)}\n >\n <FileText /> Transcript\n </Button>\n )}\n {downloadName && (\n <Button variant=\"ghost\" size=\"xs\" asChild>\n <a href={src} download={downloadName}>\n <Download /> Download\n </a>\n </Button>\n )}\n </div>\n )}\n {transcript && showTranscript && (\n <div\n id={transcriptId}\n className=\"animate-in rounded-md bg-muted/60 p-2.5 text-sm leading-6 text-muted-foreground\"\n >\n {transcript}\n </div>\n )}\n </div>\n );\n}\n\n/** A voice note inside a message: the compact AudioPlayer. */\nfunction VoiceMessage(props: Omit<AudioPlayerProps, 'variant'>) {\n return <AudioPlayer title=\"Voice message\" {...props} variant=\"compact\" />;\n}\n\nexport { AudioPlayer, VoiceMessage };\n"],"mappings":"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"}
1
+ {"version":3,"file":"audio-player.js","names":[],"sources":["../../src/components/audio-player.tsx"],"sourcesContent":["import Download from '@burtson-labs/icons/react/download';\nimport FileText from '@burtson-labs/icons/react/file-text';\nimport Pause from '@burtson-labs/icons/react/pause';\nimport Play from '@burtson-labs/icons/react/play';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\n\n/** 83.4 → \"1:23\"; 3723 → \"1:02:03\". */\nexport function formatDuration(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return '0:00';\n const s = Math.floor(seconds);\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const sec = String(s % 60).padStart(2, '0');\n return h ? `${h}:${String(m).padStart(2, '0')}:${sec}` : `${m}:${sec}`;\n}\n\n/**\n * Reduce decoded audio to `bars` peak heights between 0 and 1 (the loudest\n * sample in each slice, normalised to the loudest slice).\n */\nexport function peaksFromChannelData(data: Float32Array, bars = 48): number[] {\n if (!data.length || bars < 1) return [];\n const size = Math.max(1, Math.floor(data.length / bars));\n const peaks: number[] = [];\n for (let b = 0; b < bars; b++) {\n let max = 0;\n const end = Math.min(data.length, (b + 1) * size);\n for (let i = b * size; i < end; i++) {\n const v = Math.abs(data[i] ?? 0);\n if (v > max) max = v;\n }\n peaks.push(max);\n }\n const top = Math.max(...peaks) || 1;\n return peaks.map((p) => p / top);\n}\n\n/**\n * Decode an audio file or URL with Web Audio and return its peaks for\n * AudioPlayer. Browser only; for long files compute peaks on the server.\n */\nexport async function computePeaks(source: Blob | string, bars = 48): Promise<number[]> {\n const Ctx =\n globalThis.AudioContext ??\n (globalThis as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Ctx) throw new Error('Web Audio is not available in this browser.');\n const buf =\n typeof source === 'string'\n ? await (await fetch(source)).arrayBuffer()\n : await source.arrayBuffer();\n const ctx = new Ctx();\n try {\n const audio = await ctx.decodeAudioData(buf);\n return peaksFromChannelData(audio.getChannelData(0), bars);\n } finally {\n void ctx.close();\n }\n}\n\nconst SPEEDS = [1, 1.5, 2] as const;\n\nexport interface AudioPlayerProps extends Omit<React.ComponentProps<'div'>, 'title'> {\n src: string;\n /** Waveform heights 0–1 (see computePeaks). Leave out for a plain progress bar. */\n peaks?: number[];\n /** Name read out with the controls, e.g. \"Voice note from Dana\". */\n title?: string;\n /** Known length in seconds, shown before the file has loaded. */\n duration?: number;\n /** Text of the recording; adds a Transcript toggle. */\n transcript?: React.ReactNode;\n /** Adds a download link with this file name. */\n downloadName?: string;\n /** `compact` fits inside a message bubble. */\n variant?: 'default' | 'compact';\n onPlayChange?: (playing: boolean) => void;\n}\n\n/**\n * Plays one recording: play and pause, a waveform you can click or drive\n * with the arrow keys (5 seconds a step, Home and End), elapsed and total\n * time, speed (1×, 1.5×, 2×), download and a transcript. The waveform is a\n * slider for screen readers.\n */\nfunction AudioPlayer({\n src,\n peaks,\n title = 'Audio',\n duration: knownDuration,\n transcript,\n downloadName,\n variant = 'default',\n onPlayChange,\n className,\n ...props\n}: AudioPlayerProps) {\n const audio = React.useRef<HTMLAudioElement>(null);\n const [playing, setPlaying] = React.useState(false);\n const [current, setCurrent] = React.useState(0);\n const [duration, setDuration] = React.useState(knownDuration ?? 0);\n const [speed, setSpeed] = React.useState<(typeof SPEEDS)[number]>(1);\n const [showTranscript, setShowTranscript] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n const transcriptId = React.useId();\n const compact = variant === 'compact';\n const total = duration || knownDuration || 0;\n const ratio = total ? Math.min(1, current / total) : 0;\n\n React.useEffect(() => {\n if (audio.current) audio.current.playbackRate = speed;\n }, [speed]);\n\n const seek = (t: number) => {\n const el = audio.current;\n const clamped = Math.max(0, Math.min(total || t, t));\n if (el) el.currentTime = clamped;\n setCurrent(clamped);\n };\n\n const togglePlay = async () => {\n const el = audio.current;\n if (!el) return;\n if (el.paused) {\n try {\n await el.play();\n } catch {\n setFailed(true);\n }\n } else el.pause();\n };\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n const step = { ArrowRight: 5, ArrowUp: 5, ArrowLeft: -5, ArrowDown: -5 }[e.key];\n if (step !== undefined) {\n e.preventDefault();\n seek(current + step);\n } else if (e.key === 'Home') {\n e.preventDefault();\n seek(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n seek(total);\n } else if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n void togglePlay();\n }\n };\n\n const bars = peaks && peaks.length ? peaks : null;\n\n return (\n <div\n data-slot=\"audio-player\"\n data-variant={variant}\n className={cn(\n 'grid min-w-0 gap-2 rounded-lg border bg-surface text-foreground',\n compact ? 'w-full max-w-sm p-2' : 'p-3',\n className,\n )}\n {...props}\n >\n {/* eslint-disable-next-line jsx-a11y/media-has-caption -- the transcript prop is the text alternative */}\n <audio\n ref={audio}\n src={src}\n preload=\"metadata\"\n onLoadedMetadata={(e) => {\n const d = e.currentTarget.duration;\n if (Number.isFinite(d)) setDuration(d);\n }}\n onTimeUpdate={(e) => setCurrent(e.currentTarget.currentTime)}\n onPlay={() => {\n setPlaying(true);\n onPlayChange?.(true);\n }}\n onPause={() => {\n setPlaying(false);\n onPlayChange?.(false);\n }}\n onEnded={() => setCurrent(0)}\n onError={() => setFailed(true)}\n />\n <div className=\"flex min-w-0 items-center gap-2\">\n <Button\n type=\"button\"\n size={compact ? 'icon-sm' : 'icon'}\n variant={playing ? 'secondary' : 'default'}\n aria-label={playing ? `Pause ${title}` : `Play ${title}`}\n onClick={() => void togglePlay()}\n disabled={failed}\n className=\"shrink-0 rounded-full pointer-coarse:size-11\"\n >\n {playing ? <Pause className=\"fill-current\" /> : <Play className=\"fill-current\" />}\n </Button>\n <div\n role=\"slider\"\n tabIndex={failed ? -1 : 0}\n aria-label={`Seek ${title}`}\n aria-valuemin={0}\n aria-valuemax={Math.round(total)}\n aria-valuenow={Math.round(current)}\n aria-valuetext={`${formatDuration(current)} of ${formatDuration(total)}`}\n onKeyDown={onKeyDown}\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n if (!rect.width || !total) return;\n seek(((e.clientX - rect.left) / rect.width) * total);\n }}\n className={cn(\n 'relative flex min-w-0 flex-1 cursor-pointer items-center rounded-sm outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20',\n compact ? 'h-7' : 'h-9',\n )}\n >\n {bars ? (\n <div aria-hidden className=\"flex h-full w-full items-center gap-[2px]\">\n {bars.map((p, i) => (\n <span\n key={i}\n className={cn(\n 'min-w-[2px] flex-1 rounded-full transition-colors duration-[var(--duration-fast)] ease-[var(--ease-standard)]',\n (i + 0.5) / bars.length <= ratio ? 'bg-brand' : 'bg-border-strong',\n )}\n style={{ height: `${Math.max(12, Math.round(p * 100))}%` }}\n />\n ))}\n </div>\n ) : (\n <div aria-hidden className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\">\n <div className=\"h-full rounded-full bg-brand\" style={{ width: `${ratio * 100}%` }} />\n </div>\n )}\n </div>\n <span className=\"shrink-0 font-mono text-[11px] text-muted-foreground tabular-nums\">\n {playing || current ? formatDuration(current) : formatDuration(total)}\n </span>\n </div>\n {failed ? (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n This recording could not be played.\n </p>\n ) : (\n <div className=\"flex flex-wrap items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n aria-label={`Playback speed ${speed}×`}\n onClick={() => setSpeed(SPEEDS[(SPEEDS.indexOf(speed) + 1) % SPEEDS.length] ?? 1)}\n className=\"font-mono tabular-nums\"\n >\n {speed}×\n </Button>\n {transcript && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n aria-expanded={showTranscript}\n aria-controls={transcriptId}\n onClick={() => setShowTranscript((v) => !v)}\n >\n <FileText /> Transcript\n </Button>\n )}\n {downloadName && (\n <Button variant=\"ghost\" size=\"xs\" asChild>\n <a href={src} download={downloadName}>\n <Download /> Download\n </a>\n </Button>\n )}\n </div>\n )}\n {transcript && showTranscript && (\n <div\n id={transcriptId}\n className=\"animate-in rounded-md bg-muted/60 p-2.5 text-sm leading-6 text-muted-foreground\"\n >\n {transcript}\n </div>\n )}\n </div>\n );\n}\n\n/** A voice note inside a message: the compact AudioPlayer. */\nfunction VoiceMessage(props: Omit<AudioPlayerProps, 'variant'>) {\n return <AudioPlayer title=\"Voice message\" {...props} variant=\"compact\" />;\n}\n\nexport { AudioPlayer, VoiceMessage };\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Avatar as AvatarPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as AvatarPrimitive from '../primitives/vendor/radix/react-avatar';
3
3
  declare function Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>): React.JSX.Element;
4
4
  declare function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>): React.JSX.Element;
5
5
  declare function AvatarFallback({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Fallback>): React.JSX.Element;
@@ -1,30 +1,31 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import { Avatar } from "radix-ui";
3
+ import { Avatar as Avatar$1, AvatarFallback as AvatarFallback$1, AvatarImage as AvatarImage$1 } from "../primitives/vendor/radix/react-avatar/avatar.js";
3
4
  import "react";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  //#region src/components/avatar.tsx
6
- function Avatar$1({ className, ...props }) {
7
- return /* @__PURE__ */ jsx(Avatar.Root, {
7
+ function Avatar({ className, ...props }) {
8
+ return /* @__PURE__ */ jsx(Avatar$1, {
8
9
  "data-slot": "avatar",
9
10
  className: cn("relative flex size-8 shrink-0 overflow-hidden rounded-full", className),
10
11
  ...props
11
12
  });
12
13
  }
13
14
  function AvatarImage({ className, ...props }) {
14
- return /* @__PURE__ */ jsx(Avatar.Image, {
15
+ return /* @__PURE__ */ jsx(AvatarImage$1, {
15
16
  "data-slot": "avatar-image",
16
17
  className: cn("aspect-square size-full object-cover", className),
17
18
  ...props
18
19
  });
19
20
  }
20
21
  function AvatarFallback({ className, ...props }) {
21
- return /* @__PURE__ */ jsx(Avatar.Fallback, {
22
+ return /* @__PURE__ */ jsx(AvatarFallback$1, {
22
23
  "data-slot": "avatar-fallback",
23
24
  className: cn("flex size-full items-center justify-center rounded-full border border-brand/15 bg-brand-soft text-xs font-semibold text-brand-soft-foreground", className),
24
25
  ...props
25
26
  });
26
27
  }
27
28
  //#endregion
28
- export { Avatar$1 as Avatar, AvatarFallback, AvatarImage };
29
+ export { Avatar, AvatarFallback, AvatarImage };
29
30
 
30
31
  //# sourceMappingURL=avatar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.js","names":["Avatar","AvatarPrimitive"],"sources":["../../src/components/avatar.tsx"],"sourcesContent":["import { Avatar as AvatarPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn('aspect-square size-full object-cover', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n 'flex size-full items-center justify-center rounded-full border border-brand/15 bg-brand-soft text-xs font-semibold text-brand-soft-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarFallback, AvatarImage };\n"],"mappings":";;;;;AAKA,SAASA,SAAO,EAAE,WAAW,GAAG,SAA4D;CAC1F,OACE,oBAACC,OAAgB,MAAjB;EACE,aAAU;EACV,WAAW,GAAG,8DAA8D,SAAS;EACrF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,OAAgB,OAAjB;EACE,aAAU;EACV,WAAW,GAAG,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,WACA,GAAG,SACqD;CACxD,OACE,oBAACA,OAAgB,UAAjB;EACE,aAAU;EACV,WAAW,GACT,iJACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"avatar.js","names":["AvatarPrimitive.Root","AvatarPrimitive.Image","AvatarPrimitive.Fallback"],"sources":["../../src/components/avatar.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\nimport * as AvatarPrimitive from '../primitives/vendor/radix/react-avatar';\n\nfunction Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn('aspect-square size-full object-cover', className)}\n {...props}\n />\n );\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n 'flex size-full items-center justify-center rounded-full border border-brand/15 bg-brand-soft text-xs font-semibold text-brand-soft-foreground',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarFallback, AvatarImage };\n"],"mappings":";;;;;;AAKA,SAAS,OAAO,EAAE,WAAW,GAAG,SAA4D;CAC1F,OACE,oBAACA,UAAD;EACE,aAAU;EACV,WAAW,GAAG,8DAA8D,SAAS;EACrF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACC,eAAD;EACE,aAAU;EACV,WAAW,GAAG,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EACtB,WACA,GAAG,SACqD;CACxD,OACE,oBAACC,kBAAD;EACE,aAAU;EACV,WAAW,GACT,iJACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}