@burtson-labs/ui 0.13.1 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. package/LICENSES/DEPENDENCIES.txt +2745 -0
  2. package/LICENSES/Radix-MIT.txt +21 -0
  3. package/LICENSES/cmdk-MIT.txt +21 -0
  4. package/LICENSES/overrides/react-remove-scroll-bar.txt +26 -0
  5. package/LICENSES/shadcn-MIT.txt +21 -0
  6. package/README.md +20 -12
  7. package/THIRD_PARTY_NOTICES.md +15 -3
  8. package/dist/components/accordion.d.ts +4 -4
  9. package/dist/components/accordion.js +22 -18
  10. package/dist/components/accordion.js.map +1 -1
  11. package/dist/components/alert-dialog.d.ts +13 -11
  12. package/dist/components/alert-dialog.js +41 -31
  13. package/dist/components/alert-dialog.js.map +1 -1
  14. package/dist/components/alert.d.ts +5 -3
  15. package/dist/components/alert.js +12 -7
  16. package/dist/components/alert.js.map +1 -1
  17. package/dist/components/app-shell.d.ts +7 -6
  18. package/dist/components/app-shell.js +22 -14
  19. package/dist/components/app-shell.js.map +1 -1
  20. package/dist/components/attachment.d.ts +3 -3
  21. package/dist/components/attachment.js +11 -7
  22. package/dist/components/attachment.js.map +1 -1
  23. package/dist/components/audio-player.d.ts +2 -2
  24. package/dist/components/audio-player.js +9 -6
  25. package/dist/components/audio-player.js.map +1 -1
  26. package/dist/components/avatar.d.ts +4 -4
  27. package/dist/components/avatar.js +16 -12
  28. package/dist/components/avatar.js.map +1 -1
  29. package/dist/components/badge.d.ts +1 -1
  30. package/dist/components/badge.js +15 -13
  31. package/dist/components/badge.js.map +1 -1
  32. package/dist/components/breadcrumb.d.ts +8 -8
  33. package/dist/components/breadcrumb.js +27 -20
  34. package/dist/components/breadcrumb.js.map +1 -1
  35. package/dist/components/button.d.ts +9 -2
  36. package/dist/components/button.js +15 -6
  37. package/dist/components/button.js.map +1 -1
  38. package/dist/components/card.d.ts +9 -9
  39. package/dist/components/card.js +33 -23
  40. package/dist/components/card.js.map +1 -1
  41. package/dist/components/chat-history.d.ts +1 -1
  42. package/dist/components/chat-history.js +11 -9
  43. package/dist/components/chat-history.js.map +1 -1
  44. package/dist/components/chat-layout.d.ts +1 -1
  45. package/dist/components/chat-layout.js +8 -3
  46. package/dist/components/chat-layout.js.map +1 -1
  47. package/dist/components/checkbox-card.d.ts +3 -3
  48. package/dist/components/checkbox-card.js +12 -10
  49. package/dist/components/checkbox-card.js.map +1 -1
  50. package/dist/components/checkbox.d.ts +24 -3
  51. package/dist/components/checkbox.js +52 -9
  52. package/dist/components/checkbox.js.map +1 -1
  53. package/dist/components/collapsible.d.ts +3 -3
  54. package/dist/components/collapsible.js +14 -11
  55. package/dist/components/collapsible.js.map +1 -1
  56. package/dist/components/combobox.d.ts +14 -4
  57. package/dist/components/combobox.js +19 -8
  58. package/dist/components/combobox.js.map +1 -1
  59. package/dist/components/command.d.ts +68 -12
  60. package/dist/components/command.js +48 -34
  61. package/dist/components/command.js.map +1 -1
  62. package/dist/components/composer.d.ts +2 -2
  63. package/dist/components/composer.js +10 -7
  64. package/dist/components/composer.js.map +1 -1
  65. package/dist/components/connection-status.d.ts +3 -3
  66. package/dist/components/connection-status.js +19 -14
  67. package/dist/components/connection-status.js.map +1 -1
  68. package/dist/components/context-menu.d.ts +15 -14
  69. package/dist/components/context-menu.js +52 -41
  70. package/dist/components/context-menu.js.map +1 -1
  71. package/dist/components/conversation.d.ts +1 -1
  72. package/dist/components/conversation.js +7 -5
  73. package/dist/components/conversation.js.map +1 -1
  74. package/dist/components/copy-button.d.ts +1 -1
  75. package/dist/components/copy-button.js +4 -2
  76. package/dist/components/copy-button.js.map +1 -1
  77. package/dist/components/data-table.d.ts +7 -2
  78. package/dist/components/data-table.js +17 -42
  79. package/dist/components/data-table.js.map +1 -1
  80. package/dist/components/dialog.d.ts +19 -10
  81. package/dist/components/dialog.js +50 -33
  82. package/dist/components/dialog.js.map +1 -1
  83. package/dist/components/dropdown-menu.d.ts +15 -14
  84. package/dist/components/dropdown-menu.js +52 -41
  85. package/dist/components/dropdown-menu.js.map +1 -1
  86. package/dist/components/editor-tabs.d.ts +1 -1
  87. package/dist/components/editor-tabs.js +7 -5
  88. package/dist/components/editor-tabs.js.map +1 -1
  89. package/dist/components/empty-state.d.ts +5 -5
  90. package/dist/components/empty-state.js +17 -11
  91. package/dist/components/empty-state.js.map +1 -1
  92. package/dist/components/error-summary.d.ts +21 -0
  93. package/dist/components/error-summary.js +62 -0
  94. package/dist/components/error-summary.js.map +1 -0
  95. package/dist/components/field.d.ts +66 -7
  96. package/dist/components/field.js +152 -20
  97. package/dist/components/field.js.map +1 -1
  98. package/dist/components/form-actions.d.ts +18 -0
  99. package/dist/components/form-actions.js +30 -0
  100. package/dist/components/form-actions.js.map +1 -0
  101. package/dist/components/icon-button.d.ts +3 -1
  102. package/dist/components/icon-button.js +6 -3
  103. package/dist/components/icon-button.js.map +1 -1
  104. package/dist/components/input.d.ts +42 -7
  105. package/dist/components/input.js +54 -10
  106. package/dist/components/input.js.map +1 -1
  107. package/dist/components/kbd.d.ts +2 -2
  108. package/dist/components/kbd.js +8 -5
  109. package/dist/components/kbd.js.map +1 -1
  110. package/dist/components/label.d.ts +7 -2
  111. package/dist/components/label.js +14 -7
  112. package/dist/components/label.js.map +1 -1
  113. package/dist/components/markdown.d.ts +4 -3
  114. package/dist/components/markdown.js +8 -6
  115. package/dist/components/markdown.js.map +1 -1
  116. package/dist/components/menubar.d.ts +17 -15
  117. package/dist/components/menubar.js +58 -45
  118. package/dist/components/menubar.js.map +1 -1
  119. package/dist/components/message-actions.d.ts +3 -3
  120. package/dist/components/message-actions.js +16 -12
  121. package/dist/components/message-actions.js.map +1 -1
  122. package/dist/components/message.d.ts +1 -1
  123. package/dist/components/message.js +6 -3
  124. package/dist/components/message.js.map +1 -1
  125. package/dist/components/mobile-nav.d.ts +1 -1
  126. package/dist/components/mobile-nav.js +7 -5
  127. package/dist/components/mobile-nav.js.map +1 -1
  128. package/dist/components/native-select.d.ts +16 -0
  129. package/dist/components/native-select.js +33 -0
  130. package/dist/components/native-select.js.map +1 -0
  131. package/dist/components/navigation-menu.d.ts +13 -12
  132. package/dist/components/navigation-menu.js +43 -33
  133. package/dist/components/navigation-menu.js.map +1 -1
  134. package/dist/components/number-input.d.ts +23 -0
  135. package/dist/components/number-input.js +45 -0
  136. package/dist/components/number-input.js.map +1 -0
  137. package/dist/components/onboarding-checklist.d.ts +1 -1
  138. package/dist/components/onboarding-checklist.js +5 -3
  139. package/dist/components/onboarding-checklist.js.map +1 -1
  140. package/dist/components/page-header.d.ts +7 -6
  141. package/dist/components/page-header.js +23 -15
  142. package/dist/components/page-header.js.map +1 -1
  143. package/dist/components/pagination.d.ts +1 -1
  144. package/dist/components/pagination.js +4 -2
  145. package/dist/components/pagination.js.map +1 -1
  146. package/dist/components/popover.d.ts +14 -11
  147. package/dist/components/popover.js +30 -23
  148. package/dist/components/popover.js.map +1 -1
  149. package/dist/components/progress.d.ts +2 -2
  150. package/dist/components/progress.js +11 -9
  151. package/dist/components/progress.js.map +1 -1
  152. package/dist/components/radio-group.d.ts +23 -4
  153. package/dist/components/radio-group.js +56 -14
  154. package/dist/components/radio-group.js.map +1 -1
  155. package/dist/components/reasoning.d.ts +3 -3
  156. package/dist/components/reasoning.js +14 -11
  157. package/dist/components/reasoning.js.map +1 -1
  158. package/dist/components/resizable.js +1 -0
  159. package/dist/components/resizable.js.map +1 -1
  160. package/dist/components/scroll-area.d.ts +4 -3
  161. package/dist/components/scroll-area.js +18 -14
  162. package/dist/components/scroll-area.js.map +1 -1
  163. package/dist/components/secret-input.d.ts +3 -2
  164. package/dist/components/secret-input.js +7 -4
  165. package/dist/components/secret-input.js.map +1 -1
  166. package/dist/components/select.d.ts +12 -7
  167. package/dist/components/select.js +42 -35
  168. package/dist/components/select.js.map +1 -1
  169. package/dist/components/separator.d.ts +2 -2
  170. package/dist/components/separator.js +8 -6
  171. package/dist/components/separator.js.map +1 -1
  172. package/dist/components/sheet.d.ts +11 -9
  173. package/dist/components/sheet.js +41 -29
  174. package/dist/components/sheet.js.map +1 -1
  175. package/dist/components/skeleton.d.ts +2 -1
  176. package/dist/components/skeleton.js +7 -4
  177. package/dist/components/skeleton.js.map +1 -1
  178. package/dist/components/slider.d.ts +10 -6
  179. package/dist/components/slider.js +16 -7
  180. package/dist/components/slider.js.map +1 -1
  181. package/dist/components/source.d.ts +2 -2
  182. package/dist/components/source.js +10 -7
  183. package/dist/components/source.js.map +1 -1
  184. package/dist/components/spinner.d.ts +4 -2
  185. package/dist/components/spinner.js +5 -3
  186. package/dist/components/spinner.js.map +1 -1
  187. package/dist/components/stat-card.d.ts +27 -2
  188. package/dist/components/stat-card.js +70 -9
  189. package/dist/components/stat-card.js.map +1 -1
  190. package/dist/components/status.d.ts +7 -6
  191. package/dist/components/status.js +12 -5
  192. package/dist/components/status.js.map +1 -1
  193. package/dist/components/steps.d.ts +1 -1
  194. package/dist/components/steps.js +5 -3
  195. package/dist/components/steps.js.map +1 -1
  196. package/dist/components/switch.d.ts +47 -3
  197. package/dist/components/switch.js +89 -11
  198. package/dist/components/switch.js.map +1 -1
  199. package/dist/components/table.d.ts +29 -12
  200. package/dist/components/table.js +80 -34
  201. package/dist/components/table.js.map +1 -1
  202. package/dist/components/tabs.d.ts +10 -5
  203. package/dist/components/tabs.js +29 -19
  204. package/dist/components/tabs.js.map +1 -1
  205. package/dist/components/textarea.d.ts +6 -1
  206. package/dist/components/textarea.js +4 -3
  207. package/dist/components/textarea.js.map +1 -1
  208. package/dist/components/toast.d.ts +11 -7
  209. package/dist/components/toast.js +37 -27
  210. package/dist/components/toast.js.map +1 -1
  211. package/dist/components/toaster.d.ts +4 -2
  212. package/dist/components/toaster.js +7 -2
  213. package/dist/components/toaster.js.map +1 -1
  214. package/dist/components/tool-call.d.ts +2 -2
  215. package/dist/components/tool-call.js +15 -12
  216. package/dist/components/tool-call.js.map +1 -1
  217. package/dist/components/toolbar.d.ts +9 -4
  218. package/dist/components/toolbar.js +15 -9
  219. package/dist/components/toolbar.js.map +1 -1
  220. package/dist/components/tooltip.d.ts +4 -3
  221. package/dist/components/tooltip.js +17 -13
  222. package/dist/components/tooltip.js.map +1 -1
  223. package/dist/components/tour.js +10 -8
  224. package/dist/components/tour.js.map +1 -1
  225. package/dist/components/tree-view.d.ts +1 -1
  226. package/dist/components/tree-view.js +10 -5
  227. package/dist/components/tree-view.js.map +1 -1
  228. package/dist/components/voice-recorder.d.ts +1 -1
  229. package/dist/components/voice-recorder.js +5 -2
  230. package/dist/components/voice-recorder.js.map +1 -1
  231. package/dist/index.d.ts +6 -1
  232. package/dist/index.js +17 -12
  233. package/dist/lib/media.d.ts +18 -0
  234. package/dist/lib/media.js +34 -0
  235. package/dist/lib/media.js.map +1 -0
  236. package/dist/lib/utils.d.ts +32 -0
  237. package/dist/lib/utils.js +33 -1
  238. package/dist/lib/utils.js.map +1 -1
  239. package/dist/mui/index.js +20 -8
  240. package/dist/mui/index.js.map +1 -1
  241. package/dist/primitives/vendor/cmdk/command-score.d.ts +1 -0
  242. package/dist/primitives/vendor/cmdk/command-score.js +64 -0
  243. package/dist/primitives/vendor/cmdk/command-score.js.map +1 -0
  244. package/dist/primitives/vendor/cmdk/index.d.ts +384 -0
  245. package/dist/primitives/vendor/cmdk/index.js +687 -0
  246. package/dist/primitives/vendor/cmdk/index.js.map +1 -0
  247. package/dist/primitives/vendor/radix/number/index.d.ts +1 -0
  248. package/dist/primitives/vendor/radix/number/number.d.ts +2 -0
  249. package/dist/primitives/vendor/radix/number/number.js +9 -0
  250. package/dist/primitives/vendor/radix/number/number.js.map +1 -0
  251. package/dist/primitives/vendor/radix/primitive/index.d.ts +2 -0
  252. package/dist/primitives/vendor/radix/primitive/is-development.d.ts +1 -0
  253. package/dist/primitives/vendor/radix/primitive/is-development.js +7 -0
  254. package/dist/primitives/vendor/radix/primitive/is-development.js.map +1 -0
  255. package/dist/primitives/vendor/radix/primitive/primitive.d.ts +14 -0
  256. package/dist/primitives/vendor/radix/primitive/primitive.js +12 -0
  257. package/dist/primitives/vendor/radix/primitive/primitive.js.map +1 -0
  258. package/dist/primitives/vendor/radix/primitive/types.d.ts +5 -0
  259. package/dist/primitives/vendor/radix/react-accordion/accordion.d.ts +112 -0
  260. package/dist/primitives/vendor/radix/react-accordion/accordion.js +266 -0
  261. package/dist/primitives/vendor/radix/react-accordion/accordion.js.map +1 -0
  262. package/dist/primitives/vendor/radix/react-accordion/index.d.ts +2 -0
  263. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.d.ts +49 -0
  264. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js +122 -0
  265. package/dist/primitives/vendor/radix/react-alert-dialog/alert-dialog.js.map +1 -0
  266. package/dist/primitives/vendor/radix/react-alert-dialog/index.d.ts +2 -0
  267. package/dist/primitives/vendor/radix/react-arrow/arrow.d.ts +9 -0
  268. package/dist/primitives/vendor/radix/react-arrow/arrow.js +22 -0
  269. package/dist/primitives/vendor/radix/react-arrow/arrow.js.map +1 -0
  270. package/dist/primitives/vendor/radix/react-arrow/index.d.ts +2 -0
  271. package/dist/primitives/vendor/radix/react-avatar/avatar.d.ts +19 -0
  272. package/dist/primitives/vendor/radix/react-avatar/avatar.js +132 -0
  273. package/dist/primitives/vendor/radix/react-avatar/avatar.js.map +1 -0
  274. package/dist/primitives/vendor/radix/react-avatar/index.d.ts +2 -0
  275. package/dist/primitives/vendor/radix/react-checkbox/checkbox.d.ts +47 -0
  276. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js +197 -0
  277. package/dist/primitives/vendor/radix/react-checkbox/checkbox.js.map +1 -0
  278. package/dist/primitives/vendor/radix/react-checkbox/index.d.ts +2 -0
  279. package/dist/primitives/vendor/radix/react-collapsible/collapsible.d.ts +31 -0
  280. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js +133 -0
  281. package/dist/primitives/vendor/radix/react-collapsible/collapsible.js.map +1 -0
  282. package/dist/primitives/vendor/radix/react-collapsible/index.d.ts +2 -0
  283. package/dist/primitives/vendor/radix/react-collection/collection-legacy.d.ts +21 -0
  284. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js +84 -0
  285. package/dist/primitives/vendor/radix/react-collection/collection-legacy.js.map +1 -0
  286. package/dist/primitives/vendor/radix/react-collection/collection.d.ts +32 -0
  287. package/dist/primitives/vendor/radix/react-collection/index.d.ts +4 -0
  288. package/dist/primitives/vendor/radix/react-collection/ordered-dictionary.d.ts +51 -0
  289. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.d.ts +13 -0
  290. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js +43 -0
  291. package/dist/primitives/vendor/radix/react-compose-refs/compose-refs.js.map +1 -0
  292. package/dist/primitives/vendor/radix/react-compose-refs/index.d.ts +1 -0
  293. package/dist/primitives/vendor/radix/react-context/create-context.d.ts +45 -0
  294. package/dist/primitives/vendor/radix/react-context/create-context.js +74 -0
  295. package/dist/primitives/vendor/radix/react-context/create-context.js.map +1 -0
  296. package/dist/primitives/vendor/radix/react-context/index.d.ts +2 -0
  297. package/dist/primitives/vendor/radix/react-context-menu/context-menu.d.ts +95 -0
  298. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js +279 -0
  299. package/dist/primitives/vendor/radix/react-context-menu/context-menu.js.map +1 -0
  300. package/dist/primitives/vendor/radix/react-context-menu/index.d.ts +2 -0
  301. package/dist/primitives/vendor/radix/react-dialog/dialog.d.ts +97 -0
  302. package/dist/primitives/vendor/radix/react-dialog/dialog.js +262 -0
  303. package/dist/primitives/vendor/radix/react-dialog/dialog.js.map +1 -0
  304. package/dist/primitives/vendor/radix/react-dialog/index.d.ts +4 -0
  305. package/dist/primitives/vendor/radix/react-direction/direction.d.ts +10 -0
  306. package/dist/primitives/vendor/radix/react-direction/direction.js +13 -0
  307. package/dist/primitives/vendor/radix/react-direction/direction.js.map +1 -0
  308. package/dist/primitives/vendor/radix/react-direction/index.d.ts +1 -0
  309. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.d.ts +61 -0
  310. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js +336 -0
  311. package/dist/primitives/vendor/radix/react-dismissable-layer/dismissable-layer.js.map +1 -0
  312. package/dist/primitives/vendor/radix/react-dismissable-layer/index.d.ts +4 -0
  313. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.d.ts +95 -0
  314. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js +257 -0
  315. package/dist/primitives/vendor/radix/react-dropdown-menu/dropdown-menu.js.map +1 -0
  316. package/dist/primitives/vendor/radix/react-dropdown-menu/index.d.ts +2 -0
  317. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.d.ts +11 -0
  318. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js +49 -0
  319. package/dist/primitives/vendor/radix/react-focus-guards/focus-guards.js.map +1 -0
  320. package/dist/primitives/vendor/radix/react-focus-guards/index.d.ts +1 -0
  321. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.d.ts +31 -0
  322. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js +221 -0
  323. package/dist/primitives/vendor/radix/react-focus-scope/focus-scope.js.map +1 -0
  324. package/dist/primitives/vendor/radix/react-focus-scope/index.d.ts +1 -0
  325. package/dist/primitives/vendor/radix/react-id/id.d.ts +2 -0
  326. package/dist/primitives/vendor/radix/react-id/id.js +17 -0
  327. package/dist/primitives/vendor/radix/react-id/id.js.map +1 -0
  328. package/dist/primitives/vendor/radix/react-id/index.d.ts +1 -0
  329. package/dist/primitives/vendor/radix/react-label/index.d.ts +2 -0
  330. package/dist/primitives/vendor/radix/react-label/label.d.ts +9 -0
  331. package/dist/primitives/vendor/radix/react-label/label.js +21 -0
  332. package/dist/primitives/vendor/radix/react-label/label.js.map +1 -0
  333. package/dist/primitives/vendor/radix/react-menu/index.d.ts +2 -0
  334. package/dist/primitives/vendor/radix/react-menu/menu.d.ts +173 -0
  335. package/dist/primitives/vendor/radix/react-menu/menu.js +806 -0
  336. package/dist/primitives/vendor/radix/react-menu/menu.js.map +1 -0
  337. package/dist/primitives/vendor/radix/react-menubar/index.d.ts +2 -0
  338. package/dist/primitives/vendor/radix/react-menubar/menubar.d.ts +106 -0
  339. package/dist/primitives/vendor/radix/react-menubar/menubar.js +377 -0
  340. package/dist/primitives/vendor/radix/react-menubar/menubar.js.map +1 -0
  341. package/dist/primitives/vendor/radix/react-navigation-menu/index.d.ts +2 -0
  342. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.d.ts +124 -0
  343. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js +743 -0
  344. package/dist/primitives/vendor/radix/react-navigation-menu/navigation-menu.js.map +1 -0
  345. package/dist/primitives/vendor/radix/react-popover/index.d.ts +1 -0
  346. package/dist/primitives/vendor/radix/react-popover/popover.d.ts +83 -0
  347. package/dist/primitives/vendor/radix/react-popover/popover.js +236 -0
  348. package/dist/primitives/vendor/radix/react-popover/popover.js.map +1 -0
  349. package/dist/primitives/vendor/radix/react-popper/index.d.ts +2 -0
  350. package/dist/primitives/vendor/radix/react-popper/popper.d.ts +44 -0
  351. package/dist/primitives/vendor/radix/react-popper/popper.js +276 -0
  352. package/dist/primitives/vendor/radix/react-popper/popper.js.map +1 -0
  353. package/dist/primitives/vendor/radix/react-portal/index.d.ts +2 -0
  354. package/dist/primitives/vendor/radix/react-portal/portal.d.ts +13 -0
  355. package/dist/primitives/vendor/radix/react-portal/portal.js +21 -0
  356. package/dist/primitives/vendor/radix/react-portal/portal.js.map +1 -0
  357. package/dist/primitives/vendor/radix/react-presence/index.d.ts +2 -0
  358. package/dist/primitives/vendor/radix/react-presence/presence.d.ts +11 -0
  359. package/dist/primitives/vendor/radix/react-presence/presence.js +152 -0
  360. package/dist/primitives/vendor/radix/react-presence/presence.js.map +1 -0
  361. package/dist/primitives/vendor/radix/react-presence/use-state-machine.d.ts +10 -0
  362. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js +12 -0
  363. package/dist/primitives/vendor/radix/react-presence/use-state-machine.js.map +1 -0
  364. package/dist/primitives/vendor/radix/react-primitive/index.d.ts +2 -0
  365. package/dist/primitives/vendor/radix/react-primitive/primitive.d.ts +56 -0
  366. package/dist/primitives/vendor/radix/react-primitive/primitive.js +84 -0
  367. package/dist/primitives/vendor/radix/react-primitive/primitive.js.map +1 -0
  368. package/dist/primitives/vendor/radix/react-progress/index.d.ts +2 -0
  369. package/dist/primitives/vendor/radix/react-progress/progress.d.ts +17 -0
  370. package/dist/primitives/vendor/radix/react-progress/progress.js +79 -0
  371. package/dist/primitives/vendor/radix/react-progress/progress.js.map +1 -0
  372. package/dist/primitives/vendor/radix/react-radio-group/index.d.ts +2 -0
  373. package/dist/primitives/vendor/radix/react-radio-group/radio-group.d.ts +55 -0
  374. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js +173 -0
  375. package/dist/primitives/vendor/radix/react-radio-group/radio-group.js.map +1 -0
  376. package/dist/primitives/vendor/radix/react-radio-group/radio.d.ts +62 -0
  377. package/dist/primitives/vendor/radix/react-radio-group/radio.js +150 -0
  378. package/dist/primitives/vendor/radix/react-radio-group/radio.js.map +1 -0
  379. package/dist/primitives/vendor/radix/react-roving-focus/index.d.ts +2 -0
  380. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.d.ts +47 -0
  381. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js +218 -0
  382. package/dist/primitives/vendor/radix/react-roving-focus/roving-focus-group.js.map +1 -0
  383. package/dist/primitives/vendor/radix/react-scroll-area/index.d.ts +2 -0
  384. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.d.ts +121 -0
  385. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js +713 -0
  386. package/dist/primitives/vendor/radix/react-scroll-area/scroll-area.js.map +1 -0
  387. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.d.ts +10 -0
  388. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js +12 -0
  389. package/dist/primitives/vendor/radix/react-scroll-area/use-state-machine.js.map +1 -0
  390. package/dist/primitives/vendor/radix/react-select/index.d.ts +2 -0
  391. package/dist/primitives/vendor/radix/react-select/select.d.ts +163 -0
  392. package/dist/primitives/vendor/radix/react-select/select.js +1040 -0
  393. package/dist/primitives/vendor/radix/react-select/select.js.map +1 -0
  394. package/dist/primitives/vendor/radix/react-separator/index.d.ts +2 -0
  395. package/dist/primitives/vendor/radix/react-separator/separator.d.ts +20 -0
  396. package/dist/primitives/vendor/radix/react-separator/separator.js +29 -0
  397. package/dist/primitives/vendor/radix/react-separator/separator.js.map +1 -0
  398. package/dist/primitives/vendor/radix/react-slot/index.d.ts +1 -0
  399. package/dist/primitives/vendor/radix/react-slot/slot.d.ts +29 -0
  400. package/dist/primitives/vendor/radix/react-slot/slot.js +107 -0
  401. package/dist/primitives/vendor/radix/react-slot/slot.js.map +1 -0
  402. package/dist/primitives/vendor/radix/react-switch/index.d.ts +2 -0
  403. package/dist/primitives/vendor/radix/react-switch/switch.d.ts +41 -0
  404. package/dist/primitives/vendor/radix/react-switch/switch.js +185 -0
  405. package/dist/primitives/vendor/radix/react-switch/switch.js.map +1 -0
  406. package/dist/primitives/vendor/radix/react-tabs/index.d.ts +2 -0
  407. package/dist/primitives/vendor/radix/react-tabs/tabs.d.ts +54 -0
  408. package/dist/primitives/vendor/radix/react-tabs/tabs.js +145 -0
  409. package/dist/primitives/vendor/radix/react-tabs/tabs.js.map +1 -0
  410. package/dist/primitives/vendor/radix/react-toast/index.d.ts +2 -0
  411. package/dist/primitives/vendor/radix/react-toast/toast.d.ts +125 -0
  412. package/dist/primitives/vendor/radix/react-toast/toast.js +557 -0
  413. package/dist/primitives/vendor/radix/react-toast/toast.js.map +1 -0
  414. package/dist/primitives/vendor/radix/react-tooltip/index.d.ts +2 -0
  415. package/dist/primitives/vendor/radix/react-tooltip/tooltip.d.ts +99 -0
  416. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js +503 -0
  417. package/dist/primitives/vendor/radix/react-tooltip/tooltip.js.map +1 -0
  418. package/dist/primitives/vendor/radix/react-use-callback-ref/index.d.ts +1 -0
  419. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.d.ts +6 -0
  420. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js +18 -0
  421. package/dist/primitives/vendor/radix/react-use-callback-ref/use-callback-ref.js.map +1 -0
  422. package/dist/primitives/vendor/radix/react-use-controllable-state/index.d.ts +2 -0
  423. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state-reducer.d.ts +28 -0
  424. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.d.ts +11 -0
  425. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js +59 -0
  426. package/dist/primitives/vendor/radix/react-use-controllable-state/use-controllable-state.js.map +1 -0
  427. package/dist/primitives/vendor/radix/react-use-effect-event/index.d.ts +1 -0
  428. package/dist/primitives/vendor/radix/react-use-effect-event/use-effect-event.d.ts +7 -0
  429. package/dist/primitives/vendor/radix/react-use-is-hydrated/index.d.ts +1 -0
  430. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.d.ts +1 -0
  431. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js +18 -0
  432. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated-legacy.js.map +1 -0
  433. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.d.ts +6 -0
  434. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js +19 -0
  435. package/dist/primitives/vendor/radix/react-use-is-hydrated/use-is-hydrated.js.map +1 -0
  436. package/dist/primitives/vendor/radix/react-use-layout-effect/index.d.ts +1 -0
  437. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.d.ts +10 -0
  438. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js +15 -0
  439. package/dist/primitives/vendor/radix/react-use-layout-effect/use-layout-effect.js.map +1 -0
  440. package/dist/primitives/vendor/radix/react-use-previous/index.d.ts +1 -0
  441. package/dist/primitives/vendor/radix/react-use-previous/use-previous.d.ts +2 -0
  442. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js +20 -0
  443. package/dist/primitives/vendor/radix/react-use-previous/use-previous.js.map +1 -0
  444. package/dist/primitives/vendor/radix/react-use-size/index.d.ts +1 -0
  445. package/dist/primitives/vendor/radix/react-use-size/use-size.d.ts +5 -0
  446. package/dist/primitives/vendor/radix/react-use-size/use-size.js +42 -0
  447. package/dist/primitives/vendor/radix/react-use-size/use-size.js.map +1 -0
  448. package/dist/primitives/vendor/radix/react-visually-hidden/index.d.ts +2 -0
  449. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.d.ts +21 -0
  450. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js +32 -0
  451. package/dist/primitives/vendor/radix/react-visually-hidden/visually-hidden.js.map +1 -0
  452. package/dist/primitives/vendor/radix/rect/index.d.ts +2 -0
  453. package/dist/primitives/vendor/radix/rect/observe-element-rect.d.ts +16 -0
  454. package/dist/styles.css +1 -1
  455. package/dist/theme.css +36 -17
  456. package/dist/tokens.d.ts +78 -36
  457. package/dist/tokens.js +63 -32
  458. package/dist/tokens.js.map +1 -1
  459. package/package.json +25 -13
  460. package/vendor-manifest.json +1101 -0
@@ -1,4 +1,5 @@
1
- import { cn } from "../lib/utils.js";
1
+ "use client";
2
+ import { cn, focusRingClasses, noOutlineClasses } from "../lib/utils.js";
2
3
  import { Button } from "./button.js";
3
4
  import { formatBytes } from "./attachment.js";
4
5
  import { VoiceMessage } from "./audio-player.js";
@@ -17,9 +18,10 @@ import ThumbsUp from "@burtson-labs/icons/react/thumbs-up";
17
18
  * small icon buttons. Pass it to Message's `actions`, which shows it on
18
19
  * hover and focus (always on touch screens).
19
20
  */
20
- function MessageActions({ copyText, onRegenerate, onEdit, feedback = null, onFeedback, className, ...props }) {
21
- const small = "size-7 text-muted-foreground hover:text-foreground pointer-coarse:size-10";
21
+ var MessageActions = React.forwardRef(function MessageActions({ copyText, onRegenerate, onEdit, feedback = null, onFeedback, className, ...props }, ref) {
22
+ const small = "size-7 text-muted-foreground hover:text-foreground pointer-coarse:size-11";
22
23
  return /* @__PURE__ */ jsxs("div", {
24
+ ref,
23
25
  "data-slot": "message-actions",
24
26
  role: "toolbar",
25
27
  "aria-label": "Message actions",
@@ -66,17 +68,18 @@ function MessageActions({ copyText, onRegenerate, onEdit, feedback = null, onFee
66
68
  })] })
67
69
  ]
68
70
  });
69
- }
71
+ });
70
72
  /**
71
73
  * Edit-and-resend in place of a sent message. Enter sends (never mid-IME
72
74
  * composition), Shift+Enter adds a line, Escape cancels.
73
75
  */
74
- function MessageEditor({ defaultValue, onSubmit, onCancel, submitLabel = "Send", className, ...props }) {
76
+ var MessageEditor = React.forwardRef(function MessageEditor({ defaultValue, onSubmit, onCancel, submitLabel = "Send", className, ...props }, ref) {
75
77
  const [value, setValue] = React.useState(defaultValue);
76
78
  const send = () => {
77
79
  if (value.trim()) onSubmit(value.trim());
78
80
  };
79
81
  return /* @__PURE__ */ jsxs("form", {
82
+ ref,
80
83
  "data-slot": "message-editor",
81
84
  onSubmit: (e) => {
82
85
  e.preventDefault();
@@ -99,7 +102,7 @@ function MessageEditor({ defaultValue, onSubmit, onCancel, submitLabel = "Send",
99
102
  send();
100
103
  }
101
104
  },
102
- className: "field-sizing-content max-h-60 min-h-16 w-full resize-none rounded-lg border border-ring bg-surface px-3 py-2 text-base leading-6 inset-ring-1 inset-ring-ring outline-hidden! sm:text-sm"
105
+ className: cn("field-sizing-content max-h-60 min-h-16 w-full resize-none rounded-lg border border-ring bg-surface px-3 py-2 text-base leading-6 inset-ring-1 inset-ring-ring sm:text-sm", noOutlineClasses)
103
106
  }), /* @__PURE__ */ jsxs("div", {
104
107
  className: "flex justify-end gap-2",
105
108
  children: [/* @__PURE__ */ jsx(Button, {
@@ -116,14 +119,15 @@ function MessageEditor({ defaultValue, onSubmit, onCancel, submitLabel = "Send",
116
119
  })]
117
120
  })]
118
121
  });
119
- }
122
+ });
120
123
  /**
121
124
  * Files sent with a message: voice notes play inline, images show a
122
125
  * thumbnail, anything else is a named chip that opens the file.
123
126
  */
124
- function MessageAttachments({ files, className, ...props }) {
127
+ var MessageAttachments = React.forwardRef(function MessageAttachments({ files, className, ...props }, ref) {
125
128
  if (!files.length) return null;
126
129
  return /* @__PURE__ */ jsx("div", {
130
+ ref,
127
131
  "data-slot": "message-attachments",
128
132
  className: cn("flex flex-wrap gap-2", className),
129
133
  ...props,
@@ -140,7 +144,7 @@ function MessageAttachments({ files, className, ...props }) {
140
144
  href: f.href,
141
145
  target: "_blank",
142
146
  rel: "noreferrer",
143
- className: "block overflow-hidden rounded-lg border outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20",
147
+ className: cn("block overflow-hidden rounded-lg border", focusRingClasses),
144
148
  children: /* @__PURE__ */ jsx("img", {
145
149
  src: f.href,
146
150
  alt: f.name,
@@ -161,12 +165,12 @@ function MessageAttachments({ files, className, ...props }) {
161
165
  children: formatBytes(f.size)
162
166
  })
163
167
  ] });
164
- const chipClass = "inline-flex max-w-64 items-center gap-2 rounded-md border bg-surface px-2.5 py-1.5 text-sm";
168
+ const chipClass = "inline-flex max-w-64 items-center gap-2 rounded-md border bg-surface px-2.5 py-1.5 text-sm pointer-coarse:min-h-11";
165
169
  return f.href ? /* @__PURE__ */ jsx("a", {
166
170
  href: f.href,
167
171
  target: "_blank",
168
172
  rel: "noreferrer",
169
- className: cn(chipClass, "outline-none hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20"),
173
+ className: cn(chipClass, "hover:bg-muted", focusRingClasses),
170
174
  children: chip
171
175
  }, `${f.name}-${i}`) : /* @__PURE__ */ jsx("span", {
172
176
  className: chipClass,
@@ -174,7 +178,7 @@ function MessageAttachments({ files, className, ...props }) {
174
178
  }, `${f.name}-${i}`);
175
179
  })
176
180
  });
177
- }
181
+ });
178
182
  //#endregion
179
183
  export { MessageActions, MessageAttachments, MessageEditor };
180
184
 
@@ -1 +1 @@
1
- {"version":3,"file":"message-actions.js","names":["_Fragment"],"sources":["../../src/components/message-actions.tsx"],"sourcesContent":["import Edit from '@burtson-labs/icons/react/edit';\nimport FileText from '@burtson-labs/icons/react/file-text';\nimport RotateCcw from '@burtson-labs/icons/react/rotate-ccw';\nimport ThumbsDown from '@burtson-labs/icons/react/thumbs-down';\nimport ThumbsUp from '@burtson-labs/icons/react/thumbs-up';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { formatBytes } from './attachment';\nimport { VoiceMessage } from './audio-player';\nimport { Button } from './button';\nimport { CopyButton } from './copy-button';\nimport { IconButton } from './icon-button';\n\nexport type MessageFeedback = 'up' | 'down' | null;\n\nexport interface MessageActionsProps extends React.ComponentProps<'div'> {\n /** Text for the copy button; leave out to hide it. */\n copyText?: string;\n onRegenerate?: () => void;\n /** Edit a sent message (user turns). Pair with MessageEditor. */\n onEdit?: () => void;\n /** The current rating; controlled. */\n feedback?: MessageFeedback;\n /** Adds thumbs up and down. Clicking the chosen one again clears it (null). */\n onFeedback?: (value: MessageFeedback) => void;\n}\n\n/**\n * The row under a message: copy, regenerate, edit and a thumbs rating, as\n * small icon buttons. Pass it to Message's `actions`, which shows it on\n * hover and focus (always on touch screens).\n */\nfunction MessageActions({\n copyText,\n onRegenerate,\n onEdit,\n feedback = null,\n onFeedback,\n className,\n ...props\n}: MessageActionsProps) {\n const small = 'size-7 text-muted-foreground hover:text-foreground pointer-coarse:size-10';\n return (\n <div\n data-slot=\"message-actions\"\n role=\"toolbar\"\n aria-label=\"Message actions\"\n className={cn('flex items-center gap-0.5', className)}\n {...props}\n >\n {copyText !== undefined && (\n <CopyButton value={copyText} label=\"Copy message\" className={small} />\n )}\n {onEdit && (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Edit message\"\n onClick={onEdit}\n className={small}\n >\n <Edit />\n </IconButton>\n )}\n {onRegenerate && (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Regenerate response\"\n onClick={onRegenerate}\n className={small}\n >\n <RotateCcw />\n </IconButton>\n )}\n {onFeedback && (\n <>\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Good response\"\n aria-pressed={feedback === 'up'}\n onClick={() => onFeedback(feedback === 'up' ? null : 'up')}\n className={cn(small, feedback === 'up' && 'text-brand hover:text-brand')}\n >\n <ThumbsUp className={cn(feedback === 'up' && 'fill-current')} />\n </IconButton>\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Bad response\"\n aria-pressed={feedback === 'down'}\n onClick={() => onFeedback(feedback === 'down' ? null : 'down')}\n className={cn(small, feedback === 'down' && 'text-foreground')}\n >\n <ThumbsDown className={cn(feedback === 'down' && 'fill-current')} />\n </IconButton>\n </>\n )}\n </div>\n );\n}\n\nexport interface MessageEditorProps extends Omit<React.ComponentProps<'form'>, 'onSubmit'> {\n /** The text being edited. */\n defaultValue: string;\n /** Save and send the edited message again. */\n onSubmit: (text: string) => void;\n onCancel: () => void;\n submitLabel?: string;\n}\n\n/**\n * Edit-and-resend in place of a sent message. Enter sends (never mid-IME\n * composition), Shift+Enter adds a line, Escape cancels.\n */\nfunction MessageEditor({\n defaultValue,\n onSubmit,\n onCancel,\n submitLabel = 'Send',\n className,\n ...props\n}: MessageEditorProps) {\n const [value, setValue] = React.useState(defaultValue);\n const send = () => {\n if (value.trim()) onSubmit(value.trim());\n };\n return (\n <form\n data-slot=\"message-editor\"\n onSubmit={(e) => {\n e.preventDefault();\n send();\n }}\n className={cn('grid w-full max-w-[85%] gap-2 justify-self-end', className)}\n {...props}\n >\n <textarea\n aria-label=\"Edit message\"\n value={value}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- editing was just asked for\n autoFocus\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;\n if (e.key === 'Escape') {\n e.preventDefault();\n onCancel();\n } else if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n }}\n className=\"field-sizing-content max-h-60 min-h-16 w-full resize-none rounded-lg border border-ring bg-surface px-3 py-2 text-base leading-6 inset-ring-1 inset-ring-ring outline-hidden! sm:text-sm\"\n />\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n Cancel\n </Button>\n <Button type=\"submit\" size=\"sm\" disabled={!value.trim()}>\n {submitLabel}\n </Button>\n </div>\n </form>\n );\n}\n\nexport interface MessageFile {\n name: string;\n /** Bytes. */\n size?: number;\n /** MIME type; audio renders a player, images a thumbnail. */\n type?: string;\n /** Where to open or play it. */\n href?: string;\n /** Waveform peaks for audio (see computePeaks). */\n peaks?: number[];\n /** Seconds, for audio. */\n duration?: number;\n /** Transcript for audio. */\n transcript?: React.ReactNode;\n}\n\nexport interface MessageAttachmentsProps extends React.ComponentProps<'div'> {\n files: MessageFile[];\n}\n\n/**\n * Files sent with a message: voice notes play inline, images show a\n * thumbnail, anything else is a named chip that opens the file.\n */\nfunction MessageAttachments({ files, className, ...props }: MessageAttachmentsProps) {\n if (!files.length) return null;\n return (\n <div\n data-slot=\"message-attachments\"\n className={cn('flex flex-wrap gap-2', className)}\n {...props}\n >\n {files.map((f, i) => {\n const type = f.type ?? '';\n if (type.startsWith('audio/') && f.href) {\n return (\n <VoiceMessage\n key={`${f.name}-${i}`}\n src={f.href}\n peaks={f.peaks}\n duration={f.duration}\n transcript={f.transcript}\n title={f.name}\n />\n );\n }\n if (type.startsWith('image/') && f.href) {\n return (\n <a\n key={`${f.name}-${i}`}\n href={f.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"block overflow-hidden rounded-lg border outline-none focus-visible:ring-[3px] focus-visible:ring-ring/20\"\n >\n <img src={f.href} alt={f.name} className=\"h-28 w-auto max-w-56 object-cover\" />\n </a>\n );\n }\n const chip = (\n <>\n <FileText aria-hidden className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{f.name}</span>\n {f.size !== undefined && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">{formatBytes(f.size)}</span>\n )}\n </>\n );\n const chipClass =\n 'inline-flex max-w-64 items-center gap-2 rounded-md border bg-surface px-2.5 py-1.5 text-sm';\n return f.href ? (\n <a\n key={`${f.name}-${i}`}\n href={f.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={cn(\n chipClass,\n 'outline-none hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20',\n )}\n >\n {chip}\n </a>\n ) : (\n <span key={`${f.name}-${i}`} className={chipClass}>\n {chip}\n </span>\n );\n })}\n </div>\n );\n}\n\nexport { MessageActions, MessageAttachments, MessageEditor };\n"],"mappings":"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"}
1
+ {"version":3,"file":"message-actions.js","names":["_Fragment"],"sources":["../../src/components/message-actions.tsx"],"sourcesContent":["import Edit from '@burtson-labs/icons/react/edit';\nimport FileText from '@burtson-labs/icons/react/file-text';\nimport RotateCcw from '@burtson-labs/icons/react/rotate-ccw';\nimport ThumbsDown from '@burtson-labs/icons/react/thumbs-down';\nimport ThumbsUp from '@burtson-labs/icons/react/thumbs-up';\nimport * as React from 'react';\n\nimport { cn, focusRingClasses, noOutlineClasses } from '../lib/utils';\n\nimport { formatBytes } from './attachment';\nimport { VoiceMessage } from './audio-player';\nimport { Button } from './button';\nimport { CopyButton } from './copy-button';\nimport { IconButton } from './icon-button';\n\nexport type MessageFeedback = 'up' | 'down' | null;\n\nexport interface MessageActionsProps extends React.ComponentProps<'div'> {\n /** Text for the copy button; leave out to hide it. */\n copyText?: string;\n onRegenerate?: () => void;\n /** Edit a sent message (user turns). Pair with MessageEditor. */\n onEdit?: () => void;\n /** The current rating; controlled. */\n feedback?: MessageFeedback;\n /** Adds thumbs up and down. Clicking the chosen one again clears it (null). */\n onFeedback?: (value: MessageFeedback) => void;\n}\n\n/**\n * The row under a message: copy, regenerate, edit and a thumbs rating, as\n * small icon buttons. Pass it to Message's `actions`, which shows it on\n * hover and focus (always on touch screens).\n */\nconst MessageActions = React.forwardRef<HTMLDivElement, MessageActionsProps>(\n function MessageActions(\n { copyText, onRegenerate, onEdit, feedback = null, onFeedback, className, ...props },\n ref,\n ) {\n const small = 'size-7 text-muted-foreground hover:text-foreground pointer-coarse:size-11';\n return (\n <div\n ref={ref}\n data-slot=\"message-actions\"\n role=\"toolbar\"\n aria-label=\"Message actions\"\n className={cn('flex items-center gap-0.5', className)}\n {...props}\n >\n {copyText !== undefined && (\n <CopyButton value={copyText} label=\"Copy message\" className={small} />\n )}\n {onEdit && (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Edit message\"\n onClick={onEdit}\n className={small}\n >\n <Edit />\n </IconButton>\n )}\n {onRegenerate && (\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Regenerate response\"\n onClick={onRegenerate}\n className={small}\n >\n <RotateCcw />\n </IconButton>\n )}\n {onFeedback && (\n <>\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Good response\"\n aria-pressed={feedback === 'up'}\n onClick={() => onFeedback(feedback === 'up' ? null : 'up')}\n className={cn(small, feedback === 'up' && 'text-brand hover:text-brand')}\n >\n <ThumbsUp className={cn(feedback === 'up' && 'fill-current')} />\n </IconButton>\n <IconButton\n variant=\"ghost\"\n size=\"icon-sm\"\n label=\"Bad response\"\n aria-pressed={feedback === 'down'}\n onClick={() => onFeedback(feedback === 'down' ? null : 'down')}\n className={cn(small, feedback === 'down' && 'text-foreground')}\n >\n <ThumbsDown className={cn(feedback === 'down' && 'fill-current')} />\n </IconButton>\n </>\n )}\n </div>\n );\n },\n);\n\nexport interface MessageEditorProps extends Omit<React.ComponentProps<'form'>, 'onSubmit'> {\n /** The text being edited. */\n defaultValue: string;\n /** Save and send the edited message again. */\n onSubmit: (text: string) => void;\n onCancel: () => void;\n submitLabel?: string;\n}\n\n/**\n * Edit-and-resend in place of a sent message. Enter sends (never mid-IME\n * composition), Shift+Enter adds a line, Escape cancels.\n */\nconst MessageEditor = React.forwardRef<HTMLFormElement, MessageEditorProps>(function MessageEditor(\n { defaultValue, onSubmit, onCancel, submitLabel = 'Send', className, ...props },\n ref,\n) {\n const [value, setValue] = React.useState(defaultValue);\n const send = () => {\n if (value.trim()) onSubmit(value.trim());\n };\n return (\n <form\n ref={ref}\n data-slot=\"message-editor\"\n onSubmit={(e) => {\n e.preventDefault();\n send();\n }}\n className={cn('grid w-full max-w-[85%] gap-2 justify-self-end', className)}\n {...props}\n >\n <textarea\n aria-label=\"Edit message\"\n value={value}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- editing was just asked for\n autoFocus\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;\n if (e.key === 'Escape') {\n e.preventDefault();\n onCancel();\n } else if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n send();\n }\n }}\n className={cn(\n 'field-sizing-content max-h-60 min-h-16 w-full resize-none rounded-lg border border-ring bg-surface px-3 py-2 text-base leading-6 inset-ring-1 inset-ring-ring sm:text-sm',\n noOutlineClasses,\n )}\n />\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n Cancel\n </Button>\n <Button type=\"submit\" size=\"sm\" disabled={!value.trim()}>\n {submitLabel}\n </Button>\n </div>\n </form>\n );\n});\n\nexport interface MessageFile {\n name: string;\n /** Bytes. */\n size?: number;\n /** MIME type; audio renders a player, images a thumbnail. */\n type?: string;\n /** Where to open or play it. */\n href?: string;\n /** Waveform peaks for audio (see computePeaks). */\n peaks?: number[];\n /** Seconds, for audio. */\n duration?: number;\n /** Transcript for audio. */\n transcript?: React.ReactNode;\n}\n\nexport interface MessageAttachmentsProps extends React.ComponentProps<'div'> {\n files: MessageFile[];\n}\n\n/**\n * Files sent with a message: voice notes play inline, images show a\n * thumbnail, anything else is a named chip that opens the file.\n */\nconst MessageAttachments = React.forwardRef<HTMLDivElement, MessageAttachmentsProps>(\n function MessageAttachments({ files, className, ...props }, ref) {\n if (!files.length) return null;\n return (\n <div\n ref={ref}\n data-slot=\"message-attachments\"\n className={cn('flex flex-wrap gap-2', className)}\n {...props}\n >\n {files.map((f, i) => {\n const type = f.type ?? '';\n if (type.startsWith('audio/') && f.href) {\n return (\n <VoiceMessage\n key={`${f.name}-${i}`}\n src={f.href}\n peaks={f.peaks}\n duration={f.duration}\n transcript={f.transcript}\n title={f.name}\n />\n );\n }\n if (type.startsWith('image/') && f.href) {\n return (\n <a\n key={`${f.name}-${i}`}\n href={f.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={cn('block overflow-hidden rounded-lg border', focusRingClasses)}\n >\n <img src={f.href} alt={f.name} className=\"h-28 w-auto max-w-56 object-cover\" />\n </a>\n );\n }\n const chip = (\n <>\n <FileText aria-hidden className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{f.name}</span>\n {f.size !== undefined && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {formatBytes(f.size)}\n </span>\n )}\n </>\n );\n const chipClass =\n 'inline-flex max-w-64 items-center gap-2 rounded-md border bg-surface px-2.5 py-1.5 text-sm pointer-coarse:min-h-11';\n return f.href ? (\n <a\n key={`${f.name}-${i}`}\n href={f.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={cn(chipClass, 'hover:bg-muted', focusRingClasses)}\n >\n {chip}\n </a>\n ) : (\n <span key={`${f.name}-${i}`} className={chipClass}>\n {chip}\n </span>\n );\n })}\n </div>\n );\n },\n);\n\nexport { MessageActions, MessageAttachments, MessageEditor };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,IAAM,iBAAiB,MAAM,WAC3B,SAAS,eACP,EAAE,UAAU,cAAc,QAAQ,WAAW,MAAM,YAAY,WAAW,GAAG,SAC7E,KACA;CACA,MAAM,QAAQ;CACd,OACE,qBAAC,OAAD;EACO;EACL,aAAU;EACV,MAAK;EACL,cAAW;EACX,WAAW,GAAG,6BAA6B,SAAS;EACpD,GAAI;EANN,UAAA;GAQG,aAAa,KAAA,KACZ,oBAAC,YAAD;IAAY,OAAO;IAAU,OAAM;IAAe,WAAW;GAAQ,CAAA;GAEtE,UACC,oBAAC,YAAD;IACE,SAAQ;IACR,MAAK;IACL,OAAM;IACN,SAAS;IACT,WAAW;IAEX,UAAA,oBAAC,MAAD,CAAO,CAAA;GACG,CAAA;GAEb,gBACC,oBAAC,YAAD;IACE,SAAQ;IACR,MAAK;IACL,OAAM;IACN,SAAS;IACT,WAAW;IAEX,UAAA,oBAAC,WAAD,CAAY,CAAA;GACF,CAAA;GAEb,cACC,qBAAAA,UAAA,EAAA,UAAA,CACE,oBAAC,YAAD;IACE,SAAQ;IACR,MAAK;IACL,OAAM;IACN,gBAAc,aAAa;IAC3B,eAAe,WAAW,aAAa,OAAO,OAAO,IAAI;IACzD,WAAW,GAAG,OAAO,aAAa,QAAQ,6BAA6B;IAEvE,UAAA,oBAAC,UAAD,EAAU,WAAW,GAAG,aAAa,QAAQ,cAAc,EAAI,CAAA;GACrD,CAAA,GACZ,oBAAC,YAAD;IACE,SAAQ;IACR,MAAK;IACL,OAAM;IACN,gBAAc,aAAa;IAC3B,eAAe,WAAW,aAAa,SAAS,OAAO,MAAM;IAC7D,WAAW,GAAG,OAAO,aAAa,UAAU,iBAAiB;IAE7D,UAAA,oBAAC,YAAD,EAAY,WAAW,GAAG,aAAa,UAAU,cAAc,EAAI,CAAA;GACzD,CAAA,CACZ,EAAA,CAAA;EAED;;AAET,CACF;;;;;AAeA,IAAM,gBAAgB,MAAM,WAAgD,SAAS,cACnF,EAAE,cAAc,UAAU,UAAU,cAAc,QAAQ,WAAW,GAAG,SACxE,KACA;CACA,MAAM,CAAC,OAAO,YAAY,MAAM,SAAS,YAAY;CACrD,MAAM,aAAa;EACjB,IAAI,MAAM,KAAK,GAAG,SAAS,MAAM,KAAK,CAAC;CACzC;CACA,OACE,qBAAC,QAAD;EACO;EACL,aAAU;EACV,WAAW,MAAM;GACf,EAAE,eAAe;GACjB,KAAK;EACP;EACA,WAAW,GAAG,kDAAkD,SAAS;EACzE,GAAI;EARN,UAAA,CAUE,oBAAC,YAAD;GACE,cAAW;GACJ;GAEP,WAAA;GACA,WAAW,MAAM,SAAS,EAAE,OAAO,KAAK;GACxC,YAAY,MAAM;IAChB,IAAI,EAAE,YAAY,eAAe,EAAE,YAAY,YAAY,KAAK;IAChE,IAAI,EAAE,QAAQ,UAAU;KACtB,EAAE,eAAe;KACjB,SAAS;IACX,OAAO,IAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;KAC3C,EAAE,eAAe;KACjB,KAAK;IACP;GACF;GACA,WAAW,GACT,4KACA,gBACF;EACD,CAAA,GACD,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAQ,MAAK;IAAK,SAAS;IAAU,UAAA;GAE3D,CAAA,GACR,oBAAC,QAAD;IAAQ,MAAK;IAAS,MAAK;IAAK,UAAU,CAAC,MAAM,KAAK;IACnD,UAAA;GACK,CAAA,CACL;EACD,CAAA,CAAA;;AAEV,CAAC;;;;;AA0BD,IAAM,qBAAqB,MAAM,WAC/B,SAAS,mBAAmB,EAAE,OAAO,WAAW,GAAG,SAAS,KAAK;CAC/D,IAAI,CAAC,MAAM,QAAQ,OAAO;CAC1B,OACE,oBAAC,OAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;EAEH,UAAA,MAAM,KAAK,GAAG,MAAM;GACnB,MAAM,OAAO,EAAE,QAAQ;GACvB,IAAI,KAAK,WAAW,QAAQ,KAAK,EAAE,MACjC,OACE,oBAAC,cAAD;IAEE,KAAK,EAAE;IACP,OAAO,EAAE;IACT,UAAU,EAAE;IACZ,YAAY,EAAE;IACd,OAAO,EAAE;GACV,GANM,GAAG,EAAE,KAAK,GAAG,GAMnB;GAGL,IAAI,KAAK,WAAW,QAAQ,KAAK,EAAE,MACjC,OACE,oBAAC,KAAD;IAEE,MAAM,EAAE;IACR,QAAO;IACP,KAAI;IACJ,WAAW,GAAG,2CAA2C,gBAAgB;IAEzE,UAAA,oBAAC,OAAD;KAAK,KAAK,EAAE;KAAM,KAAK,EAAE;KAAM,WAAU;IAAqC,CAAA;GAC7E,GAPI,GAAG,EAAE,KAAK,GAAG,GAOjB;GAGP,MAAM,OACJ,qBAAAA,UAAA,EAAA,UAAA;IACE,oBAAC,UAAD;KAAU,eAAA;KAAY,WAAU;IAAyC,CAAA;IACzE,oBAAC,QAAD;KAAM,WAAU;KAAoB,UAAA,EAAE;IAAW,CAAA;IAChD,EAAE,SAAS,KAAA,KACV,oBAAC,QAAD;KAAM,WAAU;KACb,UAAA,YAAY,EAAE,IAAI;IACf,CAAA;GAER,EAAA,CAAA;GAEJ,MAAM,YACJ;GACF,OAAO,EAAE,OACP,oBAAC,KAAD;IAEE,MAAM,EAAE;IACR,QAAO;IACP,KAAI;IACJ,WAAW,GAAG,WAAW,kBAAkB,gBAAgB;IAE1D,UAAA;GACA,GAPI,GAAG,EAAE,KAAK,GAAG,GAOjB,IAEH,oBAAC,QAAD;IAA6B,WAAW;IACrC,UAAA;GACG,GAFK,GAAG,EAAE,KAAK,GAAG,GAElB;EAEV,CAAC;CACE,CAAA;AAET,CACF"}
@@ -17,5 +17,5 @@ export interface MessageProps extends React.ComponentProps<'div'> {
17
17
  * assistant turns read full width with an optional avatar, and system notes
18
18
  * are centred and small.
19
19
  */
20
- declare function Message({ from, avatar, name, meta, actions, children, className, ...props }: MessageProps): React.JSX.Element;
20
+ declare const Message: React.ForwardRefExoticComponent<Omit<MessageProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
21
21
  export { Message };
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../lib/utils.js";
2
- import "react";
3
+ import * as React from "react";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/components/message.tsx
5
6
  /**
@@ -7,8 +8,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
7
8
  * assistant turns read full width with an optional avatar, and system notes
8
9
  * are centred and small.
9
10
  */
10
- function Message({ from, avatar, name, meta, actions, children, className, ...props }) {
11
+ var Message = React.forwardRef(function Message({ from, avatar, name, meta, actions, children, className, ...props }, ref) {
11
12
  if (from === "system") return /* @__PURE__ */ jsx("div", {
13
+ ref,
12
14
  "data-slot": "message",
13
15
  "data-role": "system",
14
16
  className: cn("mx-auto max-w-prose text-center text-xs text-muted-foreground", className),
@@ -17,6 +19,7 @@ function Message({ from, avatar, name, meta, actions, children, className, ...pr
17
19
  });
18
20
  const user = from === "user";
19
21
  return /* @__PURE__ */ jsxs("div", {
22
+ ref,
20
23
  "data-slot": "message",
21
24
  "data-role": from,
22
25
  className: cn("group/message flex animate-in gap-3", user ? "justify-end" : "justify-start", className),
@@ -49,7 +52,7 @@ function Message({ from, avatar, name, meta, actions, children, className, ...pr
49
52
  ]
50
53
  })]
51
54
  });
52
- }
55
+ });
53
56
  //#endregion
54
57
  export { Message };
55
58
 
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","names":[],"sources":["../../src/components/message.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport type MessageRole = 'user' | 'assistant' | 'system';\n\nexport interface MessageProps extends React.ComponentProps<'div'> {\n /** Who wrote it. (Not `role`, which is the ARIA attribute.) */\n from: MessageRole;\n /** Avatar or agent mark beside assistant messages. */\n avatar?: React.ReactNode;\n /** Sender name shown above the message, e.g. the agent's name. */\n name?: React.ReactNode;\n /** Timestamp or status text. */\n meta?: React.ReactNode;\n /** Actions such as copy and retry, shown on hover and focus. */\n actions?: React.ReactNode;\n}\n\n/**\n * One turn in a conversation. User turns sit on the right in a quiet bubble,\n * assistant turns read full width with an optional avatar, and system notes\n * are centred and small.\n */\nfunction Message({\n from,\n avatar,\n name,\n meta,\n actions,\n children,\n className,\n ...props\n}: MessageProps) {\n if (from === 'system') {\n return (\n <div\n data-slot=\"message\"\n data-role=\"system\"\n className={cn('mx-auto max-w-prose text-center text-xs text-muted-foreground', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n const user = from === 'user';\n return (\n <div\n data-slot=\"message\"\n data-role={from}\n className={cn(\n 'group/message flex animate-in gap-3',\n user ? 'justify-end' : 'justify-start',\n className,\n )}\n {...props}\n >\n {!user && avatar && (\n <div className=\"mt-0.5 grid size-7 shrink-0 place-items-center overflow-hidden rounded-md border border-brand/15 bg-brand-soft text-brand [&_svg]:size-4\">\n {avatar}\n </div>\n )}\n <div\n className={cn('grid min-w-0 gap-1.5', user ? 'max-w-[85%] justify-items-end' : 'flex-1')}\n >\n {(name || meta) && (\n <div className=\"flex items-baseline gap-2 text-xs\">\n {name && <span className=\"font-semibold text-foreground\">{name}</span>}\n {meta && <span className=\"text-muted-foreground\">{meta}</span>}\n </div>\n )}\n <div\n data-slot=\"message-body\"\n className={cn(\n 'min-w-0 break-words text-sm leading-6',\n user && 'rounded-lg rounded-tr-xs bg-secondary px-3.5 py-2 text-secondary-foreground',\n )}\n >\n {children}\n </div>\n {actions && (\n <div className=\"flex gap-1 opacity-0 transition-opacity group-focus-within/message:opacity-100 group-hover/message:opacity-100 max-md:opacity-100\">\n {actions}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport { Message };\n"],"mappings":";;;;;;;;;AAwBA,SAAS,QAAQ,EACf,MACA,QACA,MACA,MACA,SACA,UACA,WACA,GAAG,SACY;CACf,IAAI,SAAS,UACX,OACE,oBAAC,OAAD;EACE,aAAU;EACV,aAAU;EACV,WAAW,GAAG,iEAAiE,SAAS;EACxF,GAAI;EAEH;CACE,CAAA;CAGT,MAAM,OAAO,SAAS;CACtB,OACE,qBAAC,OAAD;EACE,aAAU;EACV,aAAW;EACX,WAAW,GACT,uCACA,OAAO,gBAAgB,iBACvB,SACF;EACA,GAAI;EARN,UAAA,CAUG,CAAC,QAAQ,UACR,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA;EACE,CAAA,GAEP,qBAAC,OAAD;GACE,WAAW,GAAG,wBAAwB,OAAO,kCAAkC,QAAQ;GADzF,UAAA;KAGI,QAAQ,SACR,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACG,QAAQ,oBAAC,QAAD;MAAM,WAAU;MAAiC,UAAA;KAAW,CAAA,GACpE,QAAQ,oBAAC,QAAD;MAAM,WAAU;MAAyB,UAAA;KAAW,CAAA,CAC1D;;IAEP,oBAAC,OAAD;KACE,aAAU;KACV,WAAW,GACT,yCACA,QAAQ,6EACV;KAEC;IACE,CAAA;IACJ,WACC,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA;IACE,CAAA;GAEJ;EACF,CAAA,CAAA;;AAET"}
1
+ {"version":3,"file":"message.js","names":[],"sources":["../../src/components/message.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport type MessageRole = 'user' | 'assistant' | 'system';\n\nexport interface MessageProps extends React.ComponentProps<'div'> {\n /** Who wrote it. (Not `role`, which is the ARIA attribute.) */\n from: MessageRole;\n /** Avatar or agent mark beside assistant messages. */\n avatar?: React.ReactNode;\n /** Sender name shown above the message, e.g. the agent's name. */\n name?: React.ReactNode;\n /** Timestamp or status text. */\n meta?: React.ReactNode;\n /** Actions such as copy and retry, shown on hover and focus. */\n actions?: React.ReactNode;\n}\n\n/**\n * One turn in a conversation. User turns sit on the right in a quiet bubble,\n * assistant turns read full width with an optional avatar, and system notes\n * are centred and small.\n */\nconst Message = React.forwardRef<HTMLDivElement, MessageProps>(function Message(\n { from, avatar, name, meta, actions, children, className, ...props },\n ref,\n) {\n if (from === 'system') {\n return (\n <div\n ref={ref}\n data-slot=\"message\"\n data-role=\"system\"\n className={cn('mx-auto max-w-prose text-center text-xs text-muted-foreground', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n const user = from === 'user';\n return (\n <div\n ref={ref}\n data-slot=\"message\"\n data-role={from}\n className={cn(\n 'group/message flex animate-in gap-3',\n user ? 'justify-end' : 'justify-start',\n className,\n )}\n {...props}\n >\n {!user && avatar && (\n <div className=\"mt-0.5 grid size-7 shrink-0 place-items-center overflow-hidden rounded-md border border-brand/15 bg-brand-soft text-brand [&_svg]:size-4\">\n {avatar}\n </div>\n )}\n <div\n className={cn('grid min-w-0 gap-1.5', user ? 'max-w-[85%] justify-items-end' : 'flex-1')}\n >\n {(name || meta) && (\n <div className=\"flex items-baseline gap-2 text-xs\">\n {name && <span className=\"font-semibold text-foreground\">{name}</span>}\n {meta && <span className=\"text-muted-foreground\">{meta}</span>}\n </div>\n )}\n <div\n data-slot=\"message-body\"\n className={cn(\n 'min-w-0 break-words text-sm leading-6',\n user && 'rounded-lg rounded-tr-xs bg-secondary px-3.5 py-2 text-secondary-foreground',\n )}\n >\n {children}\n </div>\n {actions && (\n <div className=\"flex gap-1 opacity-0 transition-opacity group-focus-within/message:opacity-100 group-hover/message:opacity-100 max-md:opacity-100\">\n {actions}\n </div>\n )}\n </div>\n </div>\n );\n});\n\nexport { Message };\n"],"mappings":";;;;;;;;;;AAwBA,IAAM,UAAU,MAAM,WAAyC,SAAS,QACtE,EAAE,MAAM,QAAQ,MAAM,MAAM,SAAS,UAAU,WAAW,GAAG,SAC7D,KACA;CACA,IAAI,SAAS,UACX,OACE,oBAAC,OAAD;EACO;EACL,aAAU;EACV,aAAU;EACV,WAAW,GAAG,iEAAiE,SAAS;EACxF,GAAI;EAEH;CACE,CAAA;CAGT,MAAM,OAAO,SAAS;CACtB,OACE,qBAAC,OAAD;EACO;EACL,aAAU;EACV,aAAW;EACX,WAAW,GACT,uCACA,OAAO,gBAAgB,iBACvB,SACF;EACA,GAAI;EATN,UAAA,CAWG,CAAC,QAAQ,UACR,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA;EACE,CAAA,GAEP,qBAAC,OAAD;GACE,WAAW,GAAG,wBAAwB,OAAO,kCAAkC,QAAQ;GADzF,UAAA;KAGI,QAAQ,SACR,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACG,QAAQ,oBAAC,QAAD;MAAM,WAAU;MAAiC,UAAA;KAAW,CAAA,GACpE,QAAQ,oBAAC,QAAD;MAAM,WAAU;MAAyB,UAAA;KAAW,CAAA,CAC1D;;IAEP,oBAAC,OAAD;KACE,aAAU;KACV,WAAW,GACT,yCACA,QAAQ,6EACV;KAEC;IACE,CAAA;IACJ,WACC,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA;IACE,CAAA;GAEJ;EACF,CAAA,CAAA;;AAET,CAAC"}
@@ -28,5 +28,5 @@ export interface MobileNavProps extends Omit<React.ComponentProps<'nav'>, 'onCha
28
28
  * room for the home indicator (safe-area insets). Destinations come from the
29
29
  * app; don't pad it with empty sections.
30
30
  */
31
- declare function MobileNav({ items, value, onValueChange, position, className, 'aria-label': ariaLabel, ...props }: MobileNavProps): React.JSX.Element;
31
+ declare const MobileNav: React.ForwardRefExoticComponent<Omit<MobileNavProps, "ref"> & React.RefAttributes<HTMLElement>>;
32
32
  export { MobileNav };
@@ -1,5 +1,6 @@
1
- import { cn } from "../lib/utils.js";
2
- import "react";
1
+ "use client";
2
+ import { cn, focusRingClasses } from "../lib/utils.js";
3
+ import * as React from "react";
3
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/components/mobile-nav.tsx
5
6
  /**
@@ -7,8 +8,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
8
  * room for the home indicator (safe-area insets). Destinations come from the
8
9
  * app; don't pad it with empty sections.
9
10
  */
10
- function MobileNav({ items, value, onValueChange, position = "static", className, "aria-label": ariaLabel = "Primary", ...props }) {
11
+ var MobileNav = React.forwardRef(function MobileNav({ items, value, onValueChange, position = "static", className, "aria-label": ariaLabel = "Primary", ...props }, ref) {
11
12
  return /* @__PURE__ */ jsx("nav", {
13
+ ref,
12
14
  "data-slot": "mobile-nav",
13
15
  "aria-label": ariaLabel,
14
16
  className: cn("border-t bg-surface/95 pr-[env(safe-area-inset-right)] pb-[env(safe-area-inset-bottom)] pl-[env(safe-area-inset-left)] backdrop-blur supports-[backdrop-filter]:bg-surface/80", position === "fixed" && "fixed inset-x-0 bottom-0 z-40", className),
@@ -45,7 +47,7 @@ function MobileNav({ items, value, onValueChange, position = "static", className
45
47
  children: ", new"
46
48
  })
47
49
  ] });
48
- const classes = cn("flex min-h-14 w-full min-w-11 flex-col items-center justify-center gap-1 px-1 py-1.5 text-[11px] font-medium text-muted-foreground outline-none transition-colors select-none [-webkit-tap-highlight-color:transparent] hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/25 focus-visible:ring-inset", active && "text-brand hover:text-brand");
50
+ const classes = cn("flex min-h-14 w-full min-w-11 flex-col items-center justify-center gap-1 px-1 py-1.5 text-[11px] font-medium text-muted-foreground transition-colors select-none [-webkit-tap-highlight-color:transparent] hover:text-foreground", focusRingClasses, "focus-visible:outline-offset-[-2px]", active && "text-brand hover:text-brand");
49
51
  return /* @__PURE__ */ jsx("li", {
50
52
  className: "min-w-0 flex-1",
51
53
  children: item.href ? /* @__PURE__ */ jsx("a", {
@@ -65,7 +67,7 @@ function MobileNav({ items, value, onValueChange, position = "static", className
65
67
  })
66
68
  })
67
69
  });
68
- }
70
+ });
69
71
  //#endregion
70
72
  export { MobileNav };
71
73
 
@@ -1 +1 @@
1
- {"version":3,"file":"mobile-nav.js","names":["_Fragment"],"sources":["../../src/components/mobile-nav.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nexport interface MobileNavItem {\n id: string;\n label: string;\n /** An icon element, e.g. <MessageSquare />; sized to 20px. */\n icon: React.ReactNode;\n /** Renders a link; leave out for a button that only calls onValueChange. */\n href?: string;\n /** A count, or true for a dot. */\n badge?: number | boolean;\n}\n\nexport interface MobileNavProps extends Omit<React.ComponentProps<'nav'>, 'onChange'> {\n /** Three to five destinations the app defines. */\n items: MobileNavItem[];\n /** The current destination's id. */\n value: string;\n /**\n * Called on every press. For a link, call `event.preventDefault()` and\n * route yourself to keep a single-page app from reloading.\n */\n onValueChange?: (id: string, event: React.MouseEvent<HTMLElement>) => void;\n /** `fixed` pins it to the bottom of the viewport. */\n position?: 'fixed' | 'static';\n 'aria-label'?: string;\n}\n\n/**\n * The phone's bottom tab bar: icon over a visible label, 44px+ targets, and\n * room for the home indicator (safe-area insets). Destinations come from the\n * app; don't pad it with empty sections.\n */\nfunction MobileNav({\n items,\n value,\n onValueChange,\n position = 'static',\n className,\n 'aria-label': ariaLabel = 'Primary',\n ...props\n}: MobileNavProps) {\n return (\n <nav\n data-slot=\"mobile-nav\"\n aria-label={ariaLabel}\n className={cn(\n 'border-t bg-surface/95 pr-[env(safe-area-inset-right)] pb-[env(safe-area-inset-bottom)] pl-[env(safe-area-inset-left)] backdrop-blur supports-[backdrop-filter]:bg-surface/80',\n position === 'fixed' && 'fixed inset-x-0 bottom-0 z-40',\n className,\n )}\n {...props}\n >\n <ul className=\"mx-auto flex max-w-lg\">\n {items.map((item) => {\n const active = item.id === value;\n const count = typeof item.badge === 'number' && item.badge > 0 ? item.badge : undefined;\n const dot = item.badge === true;\n const content = (\n <>\n <span className=\"relative [&_svg]:size-5\" aria-hidden>\n {item.icon}\n {(count !== undefined || dot) && (\n <span\n className={cn(\n 'absolute -top-1 left-3 grid place-items-center rounded-full bg-destructive text-[10px] leading-none font-semibold text-destructive-foreground ring-2 ring-surface tabular-nums',\n count !== undefined ? 'h-4 min-w-4 px-1' : 'size-2',\n )}\n >\n {count !== undefined ? (count > 99 ? '99+' : count) : null}\n </span>\n )}\n </span>\n <span className=\"max-w-full truncate\">{item.label}</span>\n {count !== undefined && <span className=\"sr-only\">, {count} new</span>}\n {dot && <span className=\"sr-only\">, new</span>}\n </>\n );\n const classes = cn(\n 'flex min-h-14 w-full min-w-11 flex-col items-center justify-center gap-1 px-1 py-1.5 text-[11px] font-medium text-muted-foreground outline-none transition-colors select-none [-webkit-tap-highlight-color:transparent] hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/25 focus-visible:ring-inset',\n active && 'text-brand hover:text-brand',\n );\n return (\n <li key={item.id} className=\"min-w-0 flex-1\">\n {item.href ? (\n <a\n href={item.href}\n aria-current={active ? 'page' : undefined}\n onClick={(e) => onValueChange?.(item.id, e)}\n className={classes}\n >\n {content}\n </a>\n ) : (\n <button\n type=\"button\"\n aria-current={active ? 'page' : undefined}\n onClick={(e) => onValueChange?.(item.id, e)}\n className={classes}\n >\n {content}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n\nexport { MobileNav };\n"],"mappings":";;;;;;;;;AAmCA,SAAS,UAAU,EACjB,OACA,OACA,eACA,WAAW,UACX,WACA,cAAc,YAAY,WAC1B,GAAG,SACc;CACjB,OACE,oBAAC,OAAD;EACE,aAAU;EACV,cAAY;EACZ,WAAW,GACT,iLACA,aAAa,WAAW,iCACxB,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,MAAM,KAAK,SAAS;IACnB,MAAM,SAAS,KAAK,OAAO;IAC3B,MAAM,QAAQ,OAAO,KAAK,UAAU,YAAY,KAAK,QAAQ,IAAI,KAAK,QAAQ,KAAA;IAC9E,MAAM,MAAM,KAAK,UAAU;IAC3B,MAAM,UACJ,qBAAAA,UAAA,EAAA,UAAA;KACE,qBAAC,QAAD;MAAM,WAAU;MAA0B,eAAA;MAA1C,UAAA,CACG,KAAK,OACJ,UAAU,KAAA,KAAa,QACvB,oBAAC,QAAD;OACE,WAAW,GACT,kLACA,UAAU,KAAA,IAAY,qBAAqB,QAC7C;OAEC,UAAA,UAAU,KAAA,IAAa,QAAQ,KAAK,QAAQ,QAAS;MAClD,CAAA,CAEJ;;KACN,oBAAC,QAAD;MAAM,WAAU;MAAuB,UAAA,KAAK;KAAY,CAAA;KACvD,UAAU,KAAA,KAAa,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA;OAA0B;OAAG;OAAM;MAAU;;KACpE,OAAO,oBAAC,QAAD;MAAM,WAAU;MAAU,UAAA;KAAW,CAAA;IAC7C,EAAA,CAAA;IAEJ,MAAM,UAAU,GACd,8TACA,UAAU,6BACZ;IACA,OACE,oBAAC,MAAD;KAAkB,WAAU;KACzB,UAAA,KAAK,OACJ,oBAAC,KAAD;MACE,MAAM,KAAK;MACX,gBAAc,SAAS,SAAS,KAAA;MAChC,UAAU,MAAM,gBAAgB,KAAK,IAAI,CAAC;MAC1C,WAAW;MAEV,UAAA;KACA,CAAA,IAEH,oBAAC,UAAD;MACE,MAAK;MACL,gBAAc,SAAS,SAAS,KAAA;MAChC,UAAU,MAAM,gBAAgB,KAAK,IAAI,CAAC;MAC1C,WAAW;MAEV,UAAA;KACK,CAAA;IAER,GApBK,KAAK,EAoBV;GAER,CAAC;EACC,CAAA;CACD,CAAA;AAET"}
1
+ {"version":3,"file":"mobile-nav.js","names":["_Fragment"],"sources":["../../src/components/mobile-nav.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn, focusRingClasses } from '../lib/utils';\n\nexport interface MobileNavItem {\n id: string;\n label: string;\n /** An icon element, e.g. <MessageSquare />; sized to 20px. */\n icon: React.ReactNode;\n /** Renders a link; leave out for a button that only calls onValueChange. */\n href?: string;\n /** A count, or true for a dot. */\n badge?: number | boolean;\n}\n\nexport interface MobileNavProps extends Omit<React.ComponentProps<'nav'>, 'onChange'> {\n /** Three to five destinations the app defines. */\n items: MobileNavItem[];\n /** The current destination's id. */\n value: string;\n /**\n * Called on every press. For a link, call `event.preventDefault()` and\n * route yourself to keep a single-page app from reloading.\n */\n onValueChange?: (id: string, event: React.MouseEvent<HTMLElement>) => void;\n /** `fixed` pins it to the bottom of the viewport. */\n position?: 'fixed' | 'static';\n 'aria-label'?: string;\n}\n\n/**\n * The phone's bottom tab bar: icon over a visible label, 44px+ targets, and\n * room for the home indicator (safe-area insets). Destinations come from the\n * app; don't pad it with empty sections.\n */\nconst MobileNav = React.forwardRef<HTMLElement, MobileNavProps>(function MobileNav(\n {\n items,\n value,\n onValueChange,\n position = 'static',\n className,\n 'aria-label': ariaLabel = 'Primary',\n ...props\n },\n ref,\n) {\n return (\n <nav\n ref={ref}\n data-slot=\"mobile-nav\"\n aria-label={ariaLabel}\n className={cn(\n 'border-t bg-surface/95 pr-[env(safe-area-inset-right)] pb-[env(safe-area-inset-bottom)] pl-[env(safe-area-inset-left)] backdrop-blur supports-[backdrop-filter]:bg-surface/80',\n position === 'fixed' && 'fixed inset-x-0 bottom-0 z-40',\n className,\n )}\n {...props}\n >\n <ul className=\"mx-auto flex max-w-lg\">\n {items.map((item) => {\n const active = item.id === value;\n const count = typeof item.badge === 'number' && item.badge > 0 ? item.badge : undefined;\n const dot = item.badge === true;\n const content = (\n <>\n <span className=\"relative [&_svg]:size-5\" aria-hidden>\n {item.icon}\n {(count !== undefined || dot) && (\n <span\n className={cn(\n 'absolute -top-1 left-3 grid place-items-center rounded-full bg-destructive text-[10px] leading-none font-semibold text-destructive-foreground ring-2 ring-surface tabular-nums',\n count !== undefined ? 'h-4 min-w-4 px-1' : 'size-2',\n )}\n >\n {count !== undefined ? (count > 99 ? '99+' : count) : null}\n </span>\n )}\n </span>\n <span className=\"max-w-full truncate\">{item.label}</span>\n {count !== undefined && <span className=\"sr-only\">, {count} new</span>}\n {dot && <span className=\"sr-only\">, new</span>}\n </>\n );\n const classes = cn(\n 'flex min-h-14 w-full min-w-11 flex-col items-center justify-center gap-1 px-1 py-1.5 text-[11px] font-medium text-muted-foreground transition-colors select-none [-webkit-tap-highlight-color:transparent] hover:text-foreground',\n focusRingClasses,\n 'focus-visible:outline-offset-[-2px]',\n active && 'text-brand hover:text-brand',\n );\n return (\n <li key={item.id} className=\"min-w-0 flex-1\">\n {item.href ? (\n <a\n href={item.href}\n aria-current={active ? 'page' : undefined}\n onClick={(e) => onValueChange?.(item.id, e)}\n className={classes}\n >\n {content}\n </a>\n ) : (\n <button\n type=\"button\"\n aria-current={active ? 'page' : undefined}\n onClick={(e) => onValueChange?.(item.id, e)}\n className={classes}\n >\n {content}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n );\n});\n\nexport { MobileNav };\n"],"mappings":";;;;;;;;;;AAmCA,IAAM,YAAY,MAAM,WAAwC,SAAS,UACvE,EACE,OACA,OACA,eACA,WAAW,UACX,WACA,cAAc,YAAY,WAC1B,GAAG,SAEL,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,aAAU;EACV,cAAY;EACZ,WAAW,GACT,iLACA,aAAa,WAAW,iCACxB,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,MAAD;GAAI,WAAU;GACX,UAAA,MAAM,KAAK,SAAS;IACnB,MAAM,SAAS,KAAK,OAAO;IAC3B,MAAM,QAAQ,OAAO,KAAK,UAAU,YAAY,KAAK,QAAQ,IAAI,KAAK,QAAQ,KAAA;IAC9E,MAAM,MAAM,KAAK,UAAU;IAC3B,MAAM,UACJ,qBAAAA,UAAA,EAAA,UAAA;KACE,qBAAC,QAAD;MAAM,WAAU;MAA0B,eAAA;MAA1C,UAAA,CACG,KAAK,OACJ,UAAU,KAAA,KAAa,QACvB,oBAAC,QAAD;OACE,WAAW,GACT,kLACA,UAAU,KAAA,IAAY,qBAAqB,QAC7C;OAEC,UAAA,UAAU,KAAA,IAAa,QAAQ,KAAK,QAAQ,QAAS;MAClD,CAAA,CAEJ;;KACN,oBAAC,QAAD;MAAM,WAAU;MAAuB,UAAA,KAAK;KAAY,CAAA;KACvD,UAAU,KAAA,KAAa,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA;OAA0B;OAAG;OAAM;MAAU;;KACpE,OAAO,oBAAC,QAAD;MAAM,WAAU;MAAU,UAAA;KAAW,CAAA;IAC7C,EAAA,CAAA;IAEJ,MAAM,UAAU,GACd,oOACA,kBACA,uCACA,UAAU,6BACZ;IACA,OACE,oBAAC,MAAD;KAAkB,WAAU;KACzB,UAAA,KAAK,OACJ,oBAAC,KAAD;MACE,MAAM,KAAK;MACX,gBAAc,SAAS,SAAS,KAAA;MAChC,UAAU,MAAM,gBAAgB,KAAK,IAAI,CAAC;MAC1C,WAAW;MAEV,UAAA;KACA,CAAA,IAEH,oBAAC,UAAD;MACE,MAAK;MACL,gBAAc,SAAS,SAAS,KAAA;MAChC,UAAU,MAAM,gBAAgB,KAAK,IAAI,CAAC;MAC1C,WAAW;MAEV,UAAA;KACK,CAAA;IAER,GApBK,KAAK,EAoBV;GAER,CAAC;EACC,CAAA;CACD,CAAA;AAET,CAAC"}
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { type FieldWidth } from './input';
3
+ export interface NativeSelectProps extends React.ComponentProps<'select'> {
4
+ /** How wide the field is from 640px up; full width on phones. */
5
+ width?: FieldWidth;
6
+ /** Classes for the wrapper that positions the chevron; `className` goes to the select. */
7
+ containerClassName?: string;
8
+ }
9
+ /**
10
+ * The browser's own `<select>`, drawn like the kit's fields. Use it for short
11
+ * lists in forms on phones, where the platform picker beats a popover, and
12
+ * anywhere a portal is unwelcome. For search, descriptions or long lists use
13
+ * Select or Combobox.
14
+ */
15
+ declare const NativeSelect: React.ForwardRefExoticComponent<Omit<NativeSelectProps, "ref"> & React.RefAttributes<HTMLSelectElement>>;
16
+ export { NativeSelect };
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { cn } from "../lib/utils.js";
3
+ import { fieldClasses, fieldWidthClasses } from "./input.js";
4
+ import * as React from "react";
5
+ import ChevronDown from "@burtson-labs/icons/react/chevron-down";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/components/native-select.tsx
8
+ /**
9
+ * The browser's own `<select>`, drawn like the kit's fields. Use it for short
10
+ * lists in forms on phones, where the platform picker beats a popover, and
11
+ * anywhere a portal is unwelcome. For search, descriptions or long lists use
12
+ * Select or Combobox.
13
+ */
14
+ var NativeSelect = React.forwardRef(function NativeSelect({ className, containerClassName, width, children, ...props }, ref) {
15
+ return /* @__PURE__ */ jsxs("span", {
16
+ "data-slot": "native-select-container",
17
+ className: cn("relative flex min-w-0", width ? fieldWidthClasses[width] : "w-full", containerClassName),
18
+ children: [/* @__PURE__ */ jsx("select", {
19
+ ref,
20
+ "data-slot": "native-select",
21
+ className: cn(fieldClasses, "h-9 w-full cursor-pointer appearance-none py-1.5 pr-9", className),
22
+ ...props,
23
+ children
24
+ }), /* @__PURE__ */ jsx(ChevronDown, {
25
+ "aria-hidden": true,
26
+ className: "pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground"
27
+ })]
28
+ });
29
+ });
30
+ //#endregion
31
+ export { NativeSelect };
32
+
33
+ //# sourceMappingURL=native-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-select.js","names":[],"sources":["../../src/components/native-select.tsx"],"sourcesContent":["import ChevronDown from '@burtson-labs/icons/react/chevron-down';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { fieldClasses, type FieldWidth, fieldWidthClasses } from './input';\n\nexport interface NativeSelectProps extends React.ComponentProps<'select'> {\n /** How wide the field is from 640px up; full width on phones. */\n width?: FieldWidth;\n /** Classes for the wrapper that positions the chevron; `className` goes to the select. */\n containerClassName?: string;\n}\n\n/**\n * The browser's own `<select>`, drawn like the kit's fields. Use it for short\n * lists in forms on phones, where the platform picker beats a popover, and\n * anywhere a portal is unwelcome. For search, descriptions or long lists use\n * Select or Combobox.\n */\nconst NativeSelect = React.forwardRef<HTMLSelectElement, NativeSelectProps>(function NativeSelect(\n { className, containerClassName, width, children, ...props }: NativeSelectProps,\n ref,\n) {\n return (\n <span\n data-slot=\"native-select-container\"\n className={cn(\n 'relative flex min-w-0',\n width ? fieldWidthClasses[width] : 'w-full',\n containerClassName,\n )}\n >\n <select\n ref={ref}\n data-slot=\"native-select\"\n className={cn(\n fieldClasses,\n 'h-9 w-full cursor-pointer appearance-none py-1.5 pr-9',\n className,\n )}\n {...props}\n >\n {children}\n </select>\n <ChevronDown\n aria-hidden\n className=\"pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n </span>\n );\n});\n\nexport { NativeSelect };\n"],"mappings":";;;;;;;;;;;;;AAoBA,IAAM,eAAe,MAAM,WAAiD,SAAS,aACnF,EAAE,WAAW,oBAAoB,OAAO,UAAU,GAAG,SACrD,KACA;CACA,OACE,qBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,yBACA,QAAQ,kBAAkB,SAAS,UACnC,kBACF;EANF,UAAA,CAQE,oBAAC,UAAD;GACO;GACL,aAAU;GACV,WAAW,GACT,cACA,yDACA,SACF;GACA,GAAI;GAEH;EACK,CAAA,GACR,oBAAC,aAAD;GACE,eAAA;GACA,WAAU;EACX,CAAA,CACG;;AAEV,CAAC"}
@@ -1,20 +1,21 @@
1
- import { NavigationMenu as NavigationMenuPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as NavigationMenuPrimitive from '../primitives/vendor/radix/react-navigation-menu';
3
3
  /**
4
4
  * Site navigation with dropdown panels (a products menu, docs sections).
5
5
  * Keyboard and screen-reader behaviour come from Radix; the panel renders in
6
6
  * a shared viewport under the bar, sized to its content.
7
7
  */
8
- declare function NavigationMenu({ className, children, viewport, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
8
+ declare const NavigationMenu: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuProps & React.RefAttributes<HTMLElement> & {
9
9
  viewport?: boolean;
10
- }): React.JSX.Element;
11
- declare function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>): React.JSX.Element;
12
- declare function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>): React.JSX.Element;
13
- /** The look of a top-level entry, for links that sit beside triggers. */
14
- declare const navigationMenuTriggerStyle = "group inline-flex h-9 w-max items-center justify-center gap-1 rounded-md px-3 text-sm font-semibold text-foreground/80 outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:pointer-events-none disabled:opacity-50 data-[active]:text-foreground data-[state=open]:bg-muted data-[state=open]:text-foreground";
15
- declare function NavigationMenuTrigger({ className, children, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>): React.JSX.Element;
16
- declare function NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>): React.JSX.Element;
17
- declare function NavigationMenuViewport({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>): React.JSX.Element;
18
- declare function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>): React.JSX.Element;
19
- declare function NavigationMenuIndicator({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>): React.JSX.Element;
10
+ }, "ref"> & React.RefAttributes<HTMLElement>>;
11
+ declare const NavigationMenuList: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuListProps & React.RefAttributes<HTMLUListElement>, "ref"> & React.RefAttributes<HTMLUListElement>>;
12
+ declare const NavigationMenuItem: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuItemProps & React.RefAttributes<HTMLLIElement>, "ref"> & React.RefAttributes<HTMLLIElement>>;
13
+ /** The look of a top-level entry, for links that sit beside triggers; 44px on touch screens. */
14
+ declare const navigationMenuTriggerStyle: string;
15
+ declare const NavigationMenuTrigger: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
16
+ declare const NavigationMenuContent: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
17
+ /** The shared panel: the floating surface (12px radius, elevation 4). */
18
+ declare const NavigationMenuViewport: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuViewportProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
19
+ declare const NavigationMenuLink: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuLinkProps & React.RefAttributes<HTMLAnchorElement>, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
20
+ declare const NavigationMenuIndicator: React.ForwardRefExoticComponent<Omit<NavigationMenuPrimitive.NavigationMenuIndicatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
20
21
  export { NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle, NavigationMenuViewport, };
@@ -1,7 +1,8 @@
1
- import { cn } from "../lib/utils.js";
1
+ "use client";
2
+ import { cn, focusRingClasses } from "../lib/utils.js";
3
+ import { Content, Indicator, Item, Link, List, Root, Trigger, Viewport } from "../primitives/vendor/radix/react-navigation-menu/navigation-menu.js";
4
+ import * as React from "react";
2
5
  import ChevronDown from "@burtson-labs/icons/react/chevron-down";
3
- import { NavigationMenu } from "radix-ui";
4
- import "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/navigation-menu.tsx
7
8
  /**
@@ -9,75 +10,84 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
10
  * Keyboard and screen-reader behaviour come from Radix; the panel renders in
10
11
  * a shared viewport under the bar, sized to its content.
11
12
  */
12
- function NavigationMenu$1({ className, children, viewport = true, ...props }) {
13
- return /* @__PURE__ */ jsxs(NavigationMenu.Root, {
13
+ var NavigationMenu = React.forwardRef(function NavigationMenu({ className, children, viewport = true, ...props }, ref) {
14
+ return /* @__PURE__ */ jsxs(Root, {
15
+ ref,
14
16
  "data-slot": "navigation-menu",
15
17
  "data-viewport": viewport,
16
18
  className: cn("group/navigation-menu relative flex max-w-max flex-1 items-center justify-center", className),
17
19
  ...props,
18
20
  children: [children, viewport && /* @__PURE__ */ jsx(NavigationMenuViewport, {})]
19
21
  });
20
- }
21
- function NavigationMenuList({ className, ...props }) {
22
- return /* @__PURE__ */ jsx(NavigationMenu.List, {
22
+ });
23
+ var NavigationMenuList = React.forwardRef(function NavigationMenuList({ className, ...props }, ref) {
24
+ return /* @__PURE__ */ jsx(List, {
25
+ ref,
23
26
  "data-slot": "navigation-menu-list",
24
27
  className: cn("group flex flex-1 list-none items-center justify-center gap-1", className),
25
28
  ...props
26
29
  });
27
- }
28
- function NavigationMenuItem({ className, ...props }) {
29
- return /* @__PURE__ */ jsx(NavigationMenu.Item, {
30
+ });
31
+ var NavigationMenuItem = React.forwardRef(function NavigationMenuItem({ className, ...props }, ref) {
32
+ return /* @__PURE__ */ jsx(Item, {
33
+ ref,
30
34
  "data-slot": "navigation-menu-item",
31
35
  className: cn("relative", className),
32
36
  ...props
33
37
  });
34
- }
35
- /** The look of a top-level entry, for links that sit beside triggers. */
36
- var navigationMenuTriggerStyle = "group inline-flex h-9 w-max items-center justify-center gap-1 rounded-md px-3 text-sm font-semibold text-foreground/80 outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:pointer-events-none disabled:opacity-50 data-[active]:text-foreground data-[state=open]:bg-muted data-[state=open]:text-foreground";
37
- function NavigationMenuTrigger({ className, children, ...props }) {
38
- return /* @__PURE__ */ jsxs(NavigationMenu.Trigger, {
38
+ });
39
+ /** The look of a top-level entry, for links that sit beside triggers; 44px on touch screens. */
40
+ var navigationMenuTriggerStyle = cn("group inline-flex h-9 w-max items-center justify-center gap-1 rounded-md px-3 text-sm font-semibold text-foreground/80 transition-colors hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50 data-[active]:text-foreground data-[state=open]:bg-muted data-[state=open]:text-foreground pointer-coarse:h-11", focusRingClasses);
41
+ var NavigationMenuTrigger = React.forwardRef(function NavigationMenuTrigger({ className, children, ...props }, ref) {
42
+ return /* @__PURE__ */ jsxs(Trigger, {
43
+ ref,
39
44
  "data-slot": "navigation-menu-trigger",
40
45
  className: cn(navigationMenuTriggerStyle, className),
41
46
  ...props,
42
47
  children: [children, /* @__PURE__ */ jsx(ChevronDown, {
43
48
  "aria-hidden": true,
44
- className: "relative top-px size-3.5 transition-transform duration-200 group-data-[state=open]:rotate-180"
49
+ className: "relative top-px size-4 transition-transform duration-(--duration-standard) group-data-[state=open]:rotate-180"
45
50
  })]
46
51
  });
47
- }
48
- function NavigationMenuContent({ className, ...props }) {
49
- return /* @__PURE__ */ jsx(NavigationMenu.Content, {
52
+ });
53
+ var NavigationMenuContent = React.forwardRef(function NavigationMenuContent({ className, ...props }, ref) {
54
+ return /* @__PURE__ */ jsx(Content, {
55
+ ref,
50
56
  "data-slot": "navigation-menu-content",
51
57
  className: cn("top-0 left-0 w-full p-2 md:absolute md:w-auto data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion=from-end]:[--bl-tx:24px] data-[motion=from-start]:[--bl-tx:-24px] data-[motion=to-end]:[--bl-tx:24px] data-[motion=to-start]:[--bl-tx:-24px] [--bl-scale:1]", className),
52
58
  ...props
53
59
  });
54
- }
55
- function NavigationMenuViewport({ className, ...props }) {
60
+ });
61
+ /** The shared panel: the floating surface (12px radius, elevation 4). */
62
+ var NavigationMenuViewport = React.forwardRef(function NavigationMenuViewport({ className, ...props }, ref) {
56
63
  return /* @__PURE__ */ jsx("div", {
57
64
  className: "absolute top-full left-0 z-50 flex justify-center",
58
- children: /* @__PURE__ */ jsx(NavigationMenu.Viewport, {
65
+ children: /* @__PURE__ */ jsx(Viewport, {
66
+ ref,
59
67
  "data-slot": "navigation-menu-viewport",
60
- className: cn("relative mt-2 h-(--radix-navigation-menu-viewport-height) w-full origin-top overflow-hidden rounded-lg border border-border-strong bg-surface-raised text-popover-foreground shadow-[0_16px_48px_rgb(0_0_0_/_0.18)] transition-[width,height] duration-200 [--bl-ty:-6px] data-[state=closed]:animate-out data-[state=open]:animate-in md:w-(--radix-navigation-menu-viewport-width)", className),
68
+ className: cn("relative mt-2 h-(--radix-navigation-menu-viewport-height) w-full origin-top overflow-hidden rounded-lg border border-border-strong bg-surface-raised text-popover-foreground shadow-lg transition-[width,height] duration-(--duration-standard) [--bl-ty:-6px] data-[state=closed]:animate-out data-[state=open]:animate-in md:w-(--radix-navigation-menu-viewport-width)", className),
61
69
  ...props
62
70
  })
63
71
  });
64
- }
65
- function NavigationMenuLink({ className, ...props }) {
66
- return /* @__PURE__ */ jsx(NavigationMenu.Link, {
72
+ });
73
+ var NavigationMenuLink = React.forwardRef(function NavigationMenuLink({ className, ...props }, ref) {
74
+ return /* @__PURE__ */ jsx(Link, {
75
+ ref,
67
76
  "data-slot": "navigation-menu-link",
68
- className: cn("flex flex-col gap-1 rounded-sm p-2 text-sm outline-none transition-colors hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20 data-[active=true]:bg-muted data-[active=true]:shadow-[inset_2px_0_0_var(--color-brand)] [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
77
+ className: cn("flex flex-col gap-1 rounded-sm p-2 text-sm transition-colors hover:bg-muted data-[active=true]:bg-muted data-[active=true]:shadow-[inset_2px_0_0_var(--color-brand)] [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", focusRingClasses, "focus-visible:outline-offset-[-2px]", className),
69
78
  ...props
70
79
  });
71
- }
72
- function NavigationMenuIndicator({ className, ...props }) {
73
- return /* @__PURE__ */ jsx(NavigationMenu.Indicator, {
80
+ });
81
+ var NavigationMenuIndicator = React.forwardRef(function NavigationMenuIndicator({ className, ...props }, ref) {
82
+ return /* @__PURE__ */ jsx(Indicator, {
83
+ ref,
74
84
  "data-slot": "navigation-menu-indicator",
75
85
  className: cn("top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=visible]:animate-in", className),
76
86
  ...props,
77
87
  children: /* @__PURE__ */ jsx("div", { className: "relative top-[60%] size-2 rotate-45 rounded-tl-sm bg-border-strong" })
78
88
  });
79
- }
89
+ });
80
90
  //#endregion
81
- export { NavigationMenu$1 as NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, navigationMenuTriggerStyle };
91
+ export { NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, navigationMenuTriggerStyle };
82
92
 
83
93
  //# sourceMappingURL=navigation-menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-menu.js","names":["NavigationMenu","NavigationMenuPrimitive"],"sources":["../../src/components/navigation-menu.tsx"],"sourcesContent":["import ChevronDown from '@burtson-labs/icons/react/chevron-down';\nimport { NavigationMenu as NavigationMenuPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\n/**\n * Site navigation with dropdown panels (a products menu, docs sections).\n * Keyboard and screen-reader behaviour come from Radix; the panel renders in\n * a shared viewport under the bar, sized to its content.\n */\nfunction NavigationMenu({\n className,\n children,\n viewport = true,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & { viewport?: boolean }) {\n return (\n <NavigationMenuPrimitive.Root\n data-slot=\"navigation-menu\"\n data-viewport={viewport}\n className={cn(\n 'group/navigation-menu relative flex max-w-max flex-1 items-center justify-center',\n className,\n )}\n {...props}\n >\n {children}\n {viewport && <NavigationMenuViewport />}\n </NavigationMenuPrimitive.Root>\n );\n}\n\nfunction NavigationMenuList({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {\n return (\n <NavigationMenuPrimitive.List\n data-slot=\"navigation-menu-list\"\n className={cn('group flex flex-1 list-none items-center justify-center gap-1', className)}\n {...props}\n />\n );\n}\n\nfunction NavigationMenuItem({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {\n return (\n <NavigationMenuPrimitive.Item\n data-slot=\"navigation-menu-item\"\n className={cn('relative', className)}\n {...props}\n />\n );\n}\n\n/** The look of a top-level entry, for links that sit beside triggers. */\nconst navigationMenuTriggerStyle =\n 'group inline-flex h-9 w-max items-center justify-center gap-1 rounded-md px-3 text-sm font-semibold text-foreground/80 outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20 disabled:pointer-events-none disabled:opacity-50 data-[active]:text-foreground data-[state=open]:bg-muted data-[state=open]:text-foreground';\n\nfunction NavigationMenuTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {\n return (\n <NavigationMenuPrimitive.Trigger\n data-slot=\"navigation-menu-trigger\"\n className={cn(navigationMenuTriggerStyle, className)}\n {...props}\n >\n {children}\n <ChevronDown\n aria-hidden\n className=\"relative top-px size-3.5 transition-transform duration-200 group-data-[state=open]:rotate-180\"\n />\n </NavigationMenuPrimitive.Trigger>\n );\n}\n\nfunction NavigationMenuContent({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {\n return (\n <NavigationMenuPrimitive.Content\n data-slot=\"navigation-menu-content\"\n className={cn(\n 'top-0 left-0 w-full p-2 md:absolute md:w-auto data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion=from-end]:[--bl-tx:24px] data-[motion=from-start]:[--bl-tx:-24px] data-[motion=to-end]:[--bl-tx:24px] data-[motion=to-start]:[--bl-tx:-24px] [--bl-scale:1]',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction NavigationMenuViewport({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {\n return (\n <div className=\"absolute top-full left-0 z-50 flex justify-center\">\n <NavigationMenuPrimitive.Viewport\n data-slot=\"navigation-menu-viewport\"\n className={cn(\n 'relative mt-2 h-(--radix-navigation-menu-viewport-height) w-full origin-top overflow-hidden rounded-lg border border-border-strong bg-surface-raised text-popover-foreground shadow-[0_16px_48px_rgb(0_0_0_/_0.18)] transition-[width,height] duration-200 [--bl-ty:-6px] data-[state=closed]:animate-out data-[state=open]:animate-in md:w-(--radix-navigation-menu-viewport-width)',\n className,\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction NavigationMenuLink({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {\n return (\n <NavigationMenuPrimitive.Link\n data-slot=\"navigation-menu-link\"\n className={cn(\n \"flex flex-col gap-1 rounded-sm p-2 text-sm outline-none transition-colors hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/20 data-[active=true]:bg-muted data-[active=true]:shadow-[inset_2px_0_0_var(--color-brand)] [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction NavigationMenuIndicator({\n className,\n ...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {\n return (\n <NavigationMenuPrimitive.Indicator\n data-slot=\"navigation-menu-indicator\"\n className={cn(\n 'top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=visible]:animate-in',\n className,\n )}\n {...props}\n >\n <div className=\"relative top-[60%] size-2 rotate-45 rounded-tl-sm bg-border-strong\" />\n </NavigationMenuPrimitive.Indicator>\n );\n}\n\nexport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuIndicator,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n NavigationMenuViewport,\n};\n"],"mappings":";;;;;;;;;;;AAWA,SAASA,iBAAe,EACtB,WACA,UACA,WAAW,MACX,GAAG,SACkF;CACrF,OACE,qBAACC,eAAwB,MAAzB;EACE,aAAU;EACV,iBAAe;EACf,WAAW,GACT,oFACA,SACF;EACA,GAAI;EAPN,UAAA,CASG,UACA,YAAY,oBAAC,wBAAD,CAAyB,CAAA,CACV;;AAElC;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,oBAACA,eAAwB,MAAzB;EACE,aAAU;EACV,WAAW,GAAG,iEAAiE,SAAS;EACxF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,oBAACA,eAAwB,MAAzB;EACE,aAAU;EACV,WAAW,GAAG,YAAY,SAAS;EACnC,GAAI;CACL,CAAA;AAEL;;AAGA,IAAM,6BACJ;AAEF,SAAS,sBAAsB,EAC7B,WACA,UACA,GAAG,SAC4D;CAC/D,OACE,qBAACA,eAAwB,SAAzB;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;EAHN,UAAA,CAKG,UACD,oBAAC,aAAD;GACE,eAAA;GACA,WAAU;EACX,CAAA,CAC8B;;AAErC;AAEA,SAAS,sBAAsB,EAC7B,WACA,GAAG,SAC4D;CAC/D,OACE,oBAACA,eAAwB,SAAzB;EACE,aAAU;EACV,WAAW,GACT,yRACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAAC,OAAD;EAAK,WAAU;EACb,UAAA,oBAACA,eAAwB,UAAzB;GACE,aAAU;GACV,WAAW,GACT,wXACA,SACF;GACA,GAAI;EACL,CAAA;CACE,CAAA;AAET;AAEA,SAAS,mBAAmB,EAC1B,WACA,GAAG,SACyD;CAC5D,OACE,oBAACA,eAAwB,MAAzB;EACE,aAAU;EACV,WAAW,GACT,kUACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,oBAACA,eAAwB,WAAzB;EACE,aAAU;EACV,WAAW,GACT,sIACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,OAAD,EAAK,WAAU,qEAAsE,CAAA;CACpD,CAAA;AAEvC"}
1
+ {"version":3,"file":"navigation-menu.js","names":["NavigationMenuPrimitive.Root","NavigationMenuPrimitive.List","NavigationMenuPrimitive.Item","NavigationMenuPrimitive.Trigger","NavigationMenuPrimitive.Content","NavigationMenuPrimitive.Viewport","NavigationMenuPrimitive.Link","NavigationMenuPrimitive.Indicator"],"sources":["../../src/components/navigation-menu.tsx"],"sourcesContent":["import ChevronDown from '@burtson-labs/icons/react/chevron-down';\nimport * as React from 'react';\n\nimport { cn, focusRingClasses } from '../lib/utils';\nimport * as NavigationMenuPrimitive from '../primitives/vendor/radix/react-navigation-menu';\n\n/**\n * Site navigation with dropdown panels (a products menu, docs sections).\n * Keyboard and screen-reader behaviour come from Radix; the panel renders in\n * a shared viewport under the bar, sized to its content.\n */\nconst NavigationMenu = React.forwardRef<\n HTMLElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Root> & { viewport?: boolean }\n>(function NavigationMenu({ className, children, viewport = true, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.Root\n ref={ref}\n data-slot=\"navigation-menu\"\n data-viewport={viewport}\n className={cn(\n 'group/navigation-menu relative flex max-w-max flex-1 items-center justify-center',\n className,\n )}\n {...props}\n >\n {children}\n {viewport && <NavigationMenuViewport />}\n </NavigationMenuPrimitive.Root>\n );\n});\n\nconst NavigationMenuList = React.forwardRef<\n HTMLUListElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.List>\n>(function NavigationMenuList({ className, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.List\n ref={ref}\n data-slot=\"navigation-menu-list\"\n className={cn('group flex flex-1 list-none items-center justify-center gap-1', className)}\n {...props}\n />\n );\n});\n\nconst NavigationMenuItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Item>\n>(function NavigationMenuItem({ className, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.Item\n ref={ref}\n data-slot=\"navigation-menu-item\"\n className={cn('relative', className)}\n {...props}\n />\n );\n});\n\n/** The look of a top-level entry, for links that sit beside triggers; 44px on touch screens. */\nconst navigationMenuTriggerStyle = cn(\n 'group inline-flex h-9 w-max items-center justify-center gap-1 rounded-md px-3 text-sm font-semibold text-foreground/80 transition-colors hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50 data-[active]:text-foreground data-[state=open]:bg-muted data-[state=open]:text-foreground pointer-coarse:h-11',\n focusRingClasses,\n);\n\nconst NavigationMenuTrigger = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>\n>(function NavigationMenuTrigger({ className, children, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.Trigger\n ref={ref}\n data-slot=\"navigation-menu-trigger\"\n className={cn(navigationMenuTriggerStyle, className)}\n {...props}\n >\n {children}\n <ChevronDown\n aria-hidden\n className=\"relative top-px size-4 transition-transform duration-(--duration-standard) group-data-[state=open]:rotate-180\"\n />\n </NavigationMenuPrimitive.Trigger>\n );\n});\n\nconst NavigationMenuContent = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Content>\n>(function NavigationMenuContent({ className, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.Content\n ref={ref}\n data-slot=\"navigation-menu-content\"\n className={cn(\n 'top-0 left-0 w-full p-2 md:absolute md:w-auto data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion=from-end]:[--bl-tx:24px] data-[motion=from-start]:[--bl-tx:-24px] data-[motion=to-end]:[--bl-tx:24px] data-[motion=to-start]:[--bl-tx:-24px] [--bl-scale:1]',\n className,\n )}\n {...props}\n />\n );\n});\n\n/** The shared panel: the floating surface (12px radius, elevation 4). */\nconst NavigationMenuViewport = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>\n>(function NavigationMenuViewport({ className, ...props }, ref) {\n return (\n <div className=\"absolute top-full left-0 z-50 flex justify-center\">\n <NavigationMenuPrimitive.Viewport\n ref={ref}\n data-slot=\"navigation-menu-viewport\"\n className={cn(\n 'relative mt-2 h-(--radix-navigation-menu-viewport-height) w-full origin-top overflow-hidden rounded-lg border border-border-strong bg-surface-raised text-popover-foreground shadow-lg transition-[width,height] duration-(--duration-standard) [--bl-ty:-6px] data-[state=closed]:animate-out data-[state=open]:animate-in md:w-(--radix-navigation-menu-viewport-width)',\n className,\n )}\n {...props}\n />\n </div>\n );\n});\n\nconst NavigationMenuLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Link>\n>(function NavigationMenuLink({ className, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.Link\n ref={ref}\n data-slot=\"navigation-menu-link\"\n className={cn(\n \"flex flex-col gap-1 rounded-sm p-2 text-sm transition-colors hover:bg-muted data-[active=true]:bg-muted data-[active=true]:shadow-[inset_2px_0_0_var(--color-brand)] [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n focusRingClasses,\n 'focus-visible:outline-offset-[-2px]',\n className,\n )}\n {...props}\n />\n );\n});\n\nconst NavigationMenuIndicator = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>\n>(function NavigationMenuIndicator({ className, ...props }, ref) {\n return (\n <NavigationMenuPrimitive.Indicator\n ref={ref}\n data-slot=\"navigation-menu-indicator\"\n className={cn(\n 'top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=visible]:animate-in',\n className,\n )}\n {...props}\n >\n <div className=\"relative top-[60%] size-2 rotate-45 rounded-tl-sm bg-border-strong\" />\n </NavigationMenuPrimitive.Indicator>\n );\n});\n\nexport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuIndicator,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n NavigationMenuViewport,\n};\n"],"mappings":";;;;;;;;;;;;AAWA,IAAM,iBAAiB,MAAM,WAG3B,SAAS,eAAe,EAAE,WAAW,UAAU,WAAW,MAAM,GAAG,SAAS,KAAK;CACjF,OACE,qBAACA,MAAD;EACO;EACL,aAAU;EACV,iBAAe;EACf,WAAW,GACT,oFACA,SACF;EACA,GAAI;EARN,UAAA,CAUG,UACA,YAAY,oBAAC,wBAAD,CAAyB,CAAA,CACV;;AAElC,CAAC;AAED,IAAM,qBAAqB,MAAM,WAG/B,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAS,KAAK;CAC1D,OACE,oBAACC,MAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,iEAAiE,SAAS;EACxF,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,qBAAqB,MAAM,WAG/B,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAS,KAAK;CAC1D,OACE,oBAACC,MAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,YAAY,SAAS;EACnC,GAAI;CACL,CAAA;AAEL,CAAC;;AAGD,IAAM,6BAA6B,GACjC,iVACA,gBACF;AAEA,IAAM,wBAAwB,MAAM,WAGlC,SAAS,sBAAsB,EAAE,WAAW,UAAU,GAAG,SAAS,KAAK;CACvE,OACE,qBAACC,SAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;EAJN,UAAA,CAMG,UACD,oBAAC,aAAD;GACE,eAAA;GACA,WAAU;EACX,CAAA,CAC8B;;AAErC,CAAC;AAED,IAAM,wBAAwB,MAAM,WAGlC,SAAS,sBAAsB,EAAE,WAAW,GAAG,SAAS,KAAK;CAC7D,OACE,oBAACC,SAAD;EACO;EACL,aAAU;EACV,WAAW,GACT,yRACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CAAC;;AAGD,IAAM,yBAAyB,MAAM,WAGnC,SAAS,uBAAuB,EAAE,WAAW,GAAG,SAAS,KAAK;CAC9D,OACE,oBAAC,OAAD;EAAK,WAAU;EACb,UAAA,oBAACC,UAAD;GACO;GACL,aAAU;GACV,WAAW,GACT,6WACA,SACF;GACA,GAAI;EACL,CAAA;CACE,CAAA;AAET,CAAC;AAED,IAAM,qBAAqB,MAAM,WAG/B,SAAS,mBAAmB,EAAE,WAAW,GAAG,SAAS,KAAK;CAC1D,OACE,oBAACC,MAAD;EACO;EACL,aAAU;EACV,WAAW,GACT,iQACA,kBACA,uCACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,0BAA0B,MAAM,WAGpC,SAAS,wBAAwB,EAAE,WAAW,GAAG,SAAS,KAAK;CAC/D,OACE,oBAACC,WAAD;EACO;EACL,aAAU;EACV,WAAW,GACT,sIACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,OAAD,EAAK,WAAU,qEAAsE,CAAA;CACpD,CAAA;AAEvC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { type FieldWidth } from './input';
3
+ export interface NumberInputProps extends Omit<React.ComponentProps<'input'>, 'prefix' | 'type'> {
4
+ /** Inside the field, before the number: "$". */
5
+ prefix?: React.ReactNode;
6
+ /** Inside the field, after the number: "gal", "min", "%". */
7
+ suffix?: React.ReactNode;
8
+ /** How wide the field is from 640px up; `sm` (money, a count) by default. */
9
+ width?: FieldWidth;
10
+ /** Allows a decimal point on the phone keyboard (`inputMode="decimal"`). */
11
+ decimal?: boolean;
12
+ /** Classes for the box; `className` goes to the input itself. */
13
+ containerClassName?: string;
14
+ }
15
+ /**
16
+ * A number with its unit inside the field, right-aligned in tabular figures
17
+ * so a column of them lines up, with the numeric keyboard on phones. The box
18
+ * is the field: it carries the border, the focus ring and the invalid and
19
+ * disabled states, and the input inside is borderless. The value stays a
20
+ * string, as with any input: parse it on change.
21
+ */
22
+ declare const NumberInput: React.ForwardRefExoticComponent<Omit<NumberInputProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
23
+ export { NumberInput };