@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
@@ -98,9 +98,14 @@ export interface DataTableProps<T> extends Omit<React.ComponentProps<'div'>, 'ch
98
98
  stickyHeader?: boolean;
99
99
  /**
100
100
  * Below this width the rows become a list of cards (see DataTableColumn
101
- * `card`). `md` (768px) by default; `false` keeps the table everywhere.
101
+ * `card`). Cards need a column that says where it goes: with no `card`
102
+ * placement and no `cardsBelow`, the table stays a table (a scrolling
103
+ * region) at every width. Set `cardsBelow` (`md` is 768px) to get cards
104
+ * with the first column as the title; `false` keeps the table.
102
105
  */
103
106
  cardsBelow?: DataTableBreakpoint | false;
107
+ /** Keep the first column in view while the table scrolls sideways. */
108
+ pinFirstColumn?: boolean;
104
109
  }
105
110
  /**
106
111
  * A table recipe for records: sort, search, select, page, and row actions,
@@ -108,5 +113,5 @@ export interface DataTableProps<T> extends Omit<React.ComponentProps<'div'>, 'ch
108
113
  * come from a server; the table never reorders rows itself. On a phone the
109
114
  * rows become cards (`cardsBelow`), with the same columns.
110
115
  */
111
- declare function DataTable<T>({ 'aria-label': ariaLabel, columns, rows: rowsProp, getRowId, getRowLabel, sort, onSortChange, filter, onFilterChange, filterPlaceholder, selected, onSelectedChange, onRowAction, rowActions, page, pageCount, onPageChange, pageSummary, pageSize, pageSizeOptions, onPageSizeChange, totalRows, paginate, rowNoun, loading, error, onRetry, empty, toolbar, density, stickyHeader, cardsBelow, className, ...props }: DataTableProps<T>): React.JSX.Element;
116
+ declare function DataTable<T>({ 'aria-label': ariaLabel, columns, rows: rowsProp, getRowId, getRowLabel, sort, onSortChange, filter, onFilterChange, filterPlaceholder, selected, onSelectedChange, onRowAction, rowActions, page, pageCount, onPageChange, pageSummary, pageSize, pageSizeOptions, onPageSizeChange, totalRows, paginate, rowNoun, loading, error, onRetry, empty, toolbar, density, stickyHeader, cardsBelow, pinFirstColumn, className, ...props }: DataTableProps<T>): React.JSX.Element;
112
117
  export { DataTable };
@@ -1,6 +1,8 @@
1
- import { cn } from "../lib/utils.js";
1
+ "use client";
2
+ import { cn, focusRingClasses, noOutlineClasses } from "../lib/utils.js";
3
+ import { useNarrowerThan } from "../lib/media.js";
2
4
  import { Button } from "./button.js";
3
- import { Input } from "./input.js";
5
+ import { SearchInput } from "./input.js";
4
6
  import { Checkbox } from "./checkbox.js";
5
7
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
6
8
  import { Pagination, pageWindow, paginationSummary, usePagination } from "./pagination.js";
@@ -8,38 +10,16 @@ import { Skeleton } from "./skeleton.js";
8
10
  import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
9
11
  import * as React from "react";
10
12
  import { jsx, jsxs } from "react/jsx-runtime";
11
- import Search from "@burtson-labs/icons/react/search";
12
13
  import ChevronsUpDown from "@burtson-labs/icons/react/chevrons-up-down";
13
14
  import ArrowUp from "@burtson-labs/icons/react/arrow-up";
14
15
  import ArrowDown from "@burtson-labs/icons/react/arrow-down";
15
16
  //#region src/components/data-table.tsx
16
- var BREAKPOINTS = {
17
- sm: 640,
18
- md: 768,
19
- lg: 1024,
20
- xl: 1280
21
- };
22
17
  var hideBelowClass = {
23
18
  sm: "hidden sm:table-cell",
24
19
  md: "hidden md:table-cell",
25
20
  lg: "hidden lg:table-cell",
26
21
  xl: "hidden xl:table-cell"
27
22
  };
28
- var subscribeNone = () => () => void 0;
29
- /**
30
- * True while the viewport is narrower than `bp`. Without matchMedia (server
31
- * render, tests) it is false, so the table is the fallback.
32
- */
33
- function useNarrowerThan(bp) {
34
- const query = bp ? `(max-width: ${BREAKPOINTS[bp] - .02}px)` : null;
35
- const subscribe = React.useCallback((onChange) => {
36
- if (!query || typeof matchMedia !== "function") return () => void 0;
37
- const mq = matchMedia(query);
38
- mq.addEventListener?.("change", onChange);
39
- return () => mq.removeEventListener?.("change", onChange);
40
- }, [query]);
41
- return React.useSyncExternalStore(query ? subscribe : subscribeNone, () => Boolean(query && typeof matchMedia === "function" && matchMedia(query).matches), () => false);
42
- }
43
23
  var textOf = (node) => typeof node === "string" || typeof node === "number" ? String(node) : void 0;
44
24
  var nextSort = (current, id) => {
45
25
  if (!current || current.columnId !== id) return {
@@ -58,7 +38,7 @@ var INTERACTIVE = "a,button,input,select,textarea,[role=\"checkbox\"],[role=\"me
58
38
  * come from a server; the table never reorders rows itself. On a phone the
59
39
  * rows become cards (`cardsBelow`), with the same columns.
60
40
  */
61
- function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId, getRowLabel, sort, onSortChange, filter, onFilterChange, filterPlaceholder = "Search", selected, onSelectedChange, onRowAction, rowActions, page, pageCount, onPageChange, pageSummary, pageSize, pageSizeOptions, onPageSizeChange, totalRows, paginate, rowNoun, loading = false, error, onRetry, empty = "No results.", toolbar, density = "default", stickyHeader, cardsBelow = "md", className, ...props }) {
41
+ function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId, getRowLabel, sort, onSortChange, filter, onFilterChange, filterPlaceholder = "Search", selected, onSelectedChange, onRowAction, rowActions, page, pageCount, onPageChange, pageSummary, pageSize, pageSizeOptions, onPageSizeChange, totalRows, paginate, rowNoun, loading = false, error, onRetry, empty = "No results.", toolbar, density = "default", stickyHeader, cardsBelow, pinFirstColumn, className, ...props }) {
62
42
  const paginateOptions = paginate === true ? {} : paginate || void 0;
63
43
  const paging = usePagination(rowsProp, {
64
44
  defaultPageSize: paginateOptions?.pageSize,
@@ -67,7 +47,8 @@ function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId,
67
47
  resetKey: `${filter ?? ""}\u0000${sort?.columnId ?? ""}\u0000${sort?.direction ?? ""}`
68
48
  });
69
49
  const rows = paginateOptions ? paging.rows : rowsProp;
70
- const cards = useNarrowerThan(cardsBelow);
50
+ const placed = columns.some((c) => c.card !== void 0);
51
+ const cards = useNarrowerThan(cardsBelow ?? (placed ? "md" : false));
71
52
  const uid = React.useId();
72
53
  const selectable = Boolean(onSelectedChange);
73
54
  const selectedSet = React.useMemo(() => new Set(selected ?? []), [selected]);
@@ -195,19 +176,12 @@ function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId,
195
176
  const toolbarNode = showToolbar && /* @__PURE__ */ jsxs("div", {
196
177
  className: "flex flex-wrap items-center gap-2",
197
178
  children: [
198
- onFilterChange && /* @__PURE__ */ jsxs("div", {
199
- className: "relative min-w-0 basis-full sm:max-w-xs sm:flex-1 sm:basis-0",
200
- children: [/* @__PURE__ */ jsx(Search, {
201
- className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground",
202
- "aria-hidden": true
203
- }), /* @__PURE__ */ jsx(Input, {
204
- type: "search",
205
- value: filter ?? "",
206
- onChange: (e) => onFilterChange(e.target.value),
207
- placeholder: filterPlaceholder,
208
- "aria-label": `Search ${ariaLabel.toLowerCase()}`,
209
- className: "pl-8"
210
- })]
179
+ onFilterChange && /* @__PURE__ */ jsx(SearchInput, {
180
+ value: filter ?? "",
181
+ onChange: (e) => onFilterChange(e.target.value),
182
+ placeholder: filterPlaceholder,
183
+ "aria-label": `Search ${ariaLabel.toLowerCase()}`,
184
+ containerClassName: "min-w-0 basis-full sm:max-w-xs sm:flex-1 sm:basis-0"
211
185
  }),
212
186
  cardSelectAll,
213
187
  selectable && /* @__PURE__ */ jsx("span", {
@@ -224,7 +198,7 @@ function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId,
224
198
  return /* @__PURE__ */ jsxs("div", {
225
199
  "data-slot": "data-table",
226
200
  "data-layout": cards ? "cards" : "table",
227
- className: cn("grid min-w-0 grid-cols-[minmax(0,1fr)] gap-3", className),
201
+ className: cn("grid w-full min-w-0 grid-cols-[minmax(0,1fr)] gap-3", className),
228
202
  ...props,
229
203
  children: [
230
204
  toolbarNode,
@@ -251,6 +225,7 @@ function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId,
251
225
  "aria-busy": loading || void 0,
252
226
  density,
253
227
  stickyHeader,
228
+ pinFirstColumn,
254
229
  className: cn(loading && rows.length > 0 && "opacity-60 transition-opacity"),
255
230
  children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, {
256
231
  className: "hover:bg-transparent",
@@ -273,7 +248,7 @@ function DataTable({ "aria-label": ariaLabel, columns, rows: rowsProp, getRowId,
273
248
  children: col.sortable && onSortChange ? /* @__PURE__ */ jsxs("button", {
274
249
  type: "button",
275
250
  onClick: () => onSortChange(nextSort(sort, col.id)),
276
- className: cn("-mx-1.5 inline-flex h-7 items-center gap-1 rounded-sm px-1.5 uppercase outline-none hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20", sorted && "text-foreground", col.numeric && "flex-row-reverse"),
251
+ className: cn("-mx-1.5 inline-flex h-7 items-center gap-1 rounded-sm px-1.5 uppercase hover:bg-muted hover:text-foreground", focusRingClasses, "focus-visible:outline-offset-[-2px]", sorted && "text-foreground", col.numeric && "flex-row-reverse"),
277
252
  children: [col.header, sorted === "asc" ? /* @__PURE__ */ jsx(ArrowUp, {
278
253
  className: "size-3.5",
279
254
  "aria-hidden": true
@@ -449,7 +424,7 @@ function DataTableCards({ "aria-label": ariaLabel, columns, rows, getRowId, getR
449
424
  type: "button",
450
425
  "data-row-action": "",
451
426
  onClick: () => onRowAction(row),
452
- className: "text-left outline-hidden! after:absolute after:inset-0 after:rounded-lg",
427
+ className: cn("text-left after:absolute after:inset-0 after:rounded-lg", noOutlineClasses),
453
428
  children: show(c, row)
454
429
  }) : show(c, row)
455
430
  }, c.id))
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.js","names":[],"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import ArrowDown from '@burtson-labs/icons/react/arrow-down';\nimport ArrowUp from '@burtson-labs/icons/react/arrow-up';\nimport ChevronsUpDown from '@burtson-labs/icons/react/chevrons-up-down';\nimport Search from '@burtson-labs/icons/react/search';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nimport { Button } from './button';\nimport { Checkbox } from './checkbox';\nimport { Input } from './input';\nimport { Pagination, pageWindow, paginationSummary, usePagination } from './pagination';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './select';\nimport { Skeleton } from './skeleton';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './table';\n\n/**\n * Where a column goes on a phone card: `title` and `subtitle` head the card,\n * `aside` sits top right (a status badge), `field` is a labelled value in a\n * two-column grid, `footer` is a full-width line at the bottom (links,\n * buttons), `hidden` is left off the card.\n */\nexport type DataTableCardSlot = 'title' | 'subtitle' | 'aside' | 'field' | 'footer' | 'hidden';\n\nexport type DataTableBreakpoint = 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface DataTableColumn<T> {\n id: string;\n header: React.ReactNode;\n cell: (row: T) => React.ReactNode;\n sortable?: boolean;\n /** Right-aligned tabular figures. */\n numeric?: boolean;\n className?: string;\n /**\n * Place on a phone card. With no column marked `title`, the first column\n * is the title; every other column is a `field` unless it says otherwise.\n */\n card?: DataTableCardSlot;\n /** The field's label on a card when `header` is not plain text. */\n cardLabel?: string;\n /** A shorter rendering for the card, e.g. a date without the time. */\n cardCell?: (row: T) => React.ReactNode;\n /** Only on cards, never a table column (e.g. a subtitle the table shows in another cell). */\n cardOnly?: boolean;\n /** Leave the column out of the table below this width (tablets). */\n hideBelow?: DataTableBreakpoint;\n}\n\nexport interface DataTablePaginateOptions {\n /** Starting rows per page; the first option by default. */\n pageSize?: number;\n /** 25, 50 and 100 by default. */\n pageSizeOptions?: readonly number[];\n /** Remembers the chosen page size in localStorage under this key. */\n storageKey?: string;\n}\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport interface DataTableSort {\n columnId: string;\n direction: SortDirection;\n}\n\nexport interface DataTableProps<T> extends Omit<React.ComponentProps<'div'>, 'children'> {\n /** Required: what the table lists, e.g. \"Workspace members\". */\n 'aria-label': string;\n columns: DataTableColumn<T>[];\n /** The rows to show now: already sorted, filtered and paged by the app or server. */\n rows: T[];\n getRowId: (row: T) => string;\n /** Names a row for screen readers (\"Select Ada Lovelace\"). Defaults to its id. */\n getRowLabel?: (row: T) => string;\n\n /** Controlled sort. A sortable header cycles ascending, descending, none. */\n sort?: DataTableSort | null;\n onSortChange?: (sort: DataTableSort | null) => void;\n\n /** Controlled filter text; a search box appears when onFilterChange is set. */\n filter?: string;\n onFilterChange?: (value: string) => void;\n filterPlaceholder?: string;\n\n /** Controlled selection by row id; checkboxes appear when onSelectedChange is set. */\n selected?: string[];\n onSelectedChange?: (ids: string[]) => void;\n\n /** Enter or a click on the row, e.g. open the record. */\n onRowAction?: (row: T) => void;\n /** Per-row controls in a trailing column, e.g. a DropdownMenu. */\n rowActions?: (row: T) => React.ReactNode;\n\n /** 1-based; Pagination appears when onPageChange is set. */\n page?: number;\n pageCount?: number;\n onPageChange?: (page: number) => void;\n /** e.g. \"1–25 of 312\". Worked out from `totalRows` and `pageSize` when left out. */\n pageSummary?: React.ReactNode;\n /** Rows per page, for the page-size menu and the summary. */\n pageSize?: number;\n pageSizeOptions?: readonly number[];\n /** Adds a rows-per-page menu beside the pages. */\n onPageSizeChange?: (pageSize: number) => void;\n /** Every row on every page (server paging), for the summary. */\n totalRows?: number;\n /**\n * Page in the browser: pass every row in `rows` and the table shows one\n * page, with a rows-per-page menu. It goes back to page 1 when `filter` or\n * `sort` changes. Leave out to page in your app or on the server.\n */\n paginate?: boolean | DataTablePaginateOptions;\n /** Plural noun appended to the built-in summary: \"1–25 of 312 members\". */\n rowNoun?: string;\n\n loading?: boolean;\n /** A message shown in place of the rows. */\n error?: React.ReactNode;\n onRetry?: () => void;\n /** Shown when there are no rows and nothing failed. */\n empty?: React.ReactNode;\n /** Extra controls beside the search box, e.g. filters or a bulk action. */\n toolbar?: React.ReactNode;\n density?: 'compact' | 'default';\n stickyHeader?: boolean;\n /**\n * Below this width the rows become a list of cards (see DataTableColumn\n * `card`). `md` (768px) by default; `false` keeps the table everywhere.\n */\n cardsBelow?: DataTableBreakpoint | false;\n}\n\nconst BREAKPOINTS: Record<DataTableBreakpoint, number> = { sm: 640, md: 768, lg: 1024, xl: 1280 };\n\nconst hideBelowClass: Record<DataTableBreakpoint, string> = {\n sm: 'hidden sm:table-cell',\n md: 'hidden md:table-cell',\n lg: 'hidden lg:table-cell',\n xl: 'hidden xl:table-cell',\n};\n\nconst subscribeNone = () => () => undefined;\n\n/**\n * True while the viewport is narrower than `bp`. Without matchMedia (server\n * render, tests) it is false, so the table is the fallback.\n */\nfunction useNarrowerThan(bp: DataTableBreakpoint | false): boolean {\n const query = bp ? `(max-width: ${BREAKPOINTS[bp] - 0.02}px)` : null;\n const subscribe = React.useCallback(\n (onChange: () => void) => {\n if (!query || typeof matchMedia !== 'function') return () => undefined;\n const mq = matchMedia(query);\n mq.addEventListener?.('change', onChange);\n return () => mq.removeEventListener?.('change', onChange);\n },\n [query],\n );\n return React.useSyncExternalStore(\n query ? subscribe : subscribeNone,\n () => Boolean(query && typeof matchMedia === 'function' && matchMedia(query).matches),\n () => false,\n );\n}\n\nconst textOf = (node: React.ReactNode): string | undefined =>\n typeof node === 'string' || typeof node === 'number' ? String(node) : undefined;\n\nconst nextSort = (current: DataTableSort | null | undefined, id: string): DataTableSort | null => {\n if (!current || current.columnId !== id) return { columnId: id, direction: 'asc' };\n return current.direction === 'asc' ? { columnId: id, direction: 'desc' } : null;\n};\n\n// Clicks and keys aimed at these belong to them, not to the row.\nconst INTERACTIVE = 'a,button,input,select,textarea,[role=\"checkbox\"],[role=\"menuitem\"]';\n\n/**\n * A table recipe for records: sort, search, select, page, and row actions,\n * with loading, empty and error states. Fully controlled, so the data can\n * come from a server; the table never reorders rows itself. On a phone the\n * rows become cards (`cardsBelow`), with the same columns.\n */\nfunction DataTable<T>({\n 'aria-label': ariaLabel,\n columns,\n rows: rowsProp,\n getRowId,\n getRowLabel,\n sort,\n onSortChange,\n filter,\n onFilterChange,\n filterPlaceholder = 'Search',\n selected,\n onSelectedChange,\n onRowAction,\n rowActions,\n page,\n pageCount,\n onPageChange,\n pageSummary,\n pageSize,\n pageSizeOptions,\n onPageSizeChange,\n totalRows,\n paginate,\n rowNoun,\n loading = false,\n error,\n onRetry,\n empty = 'No results.',\n toolbar,\n density = 'default',\n stickyHeader,\n cardsBelow = 'md',\n className,\n ...props\n}: DataTableProps<T>) {\n const paginateOptions = paginate === true ? {} : paginate || undefined;\n const paging = usePagination(rowsProp, {\n defaultPageSize: paginateOptions?.pageSize,\n pageSizeOptions: paginateOptions?.pageSizeOptions,\n storageKey: paginateOptions?.storageKey,\n // A new search or sort starts again at page 1.\n resetKey: `${filter ?? ''}\\u0000${sort?.columnId ?? ''}\\u0000${sort?.direction ?? ''}`,\n });\n const rows = paginateOptions ? paging.rows : rowsProp;\n const cards = useNarrowerThan(cardsBelow);\n const uid = React.useId();\n\n const selectable = Boolean(onSelectedChange);\n const selectedSet = React.useMemo(() => new Set(selected ?? []), [selected]);\n const ids = rows.map(getRowId);\n const pageSelected = ids.filter((id) => selectedSet.has(id)).length;\n const allState: boolean | 'indeterminate' =\n ids.length > 0 && pageSelected === ids.length\n ? true\n : pageSelected > 0\n ? 'indeterminate'\n : false;\n const tableColumns = columns.filter((c) => !c.cardOnly);\n const colCount = tableColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0);\n const interactive = Boolean(onRowAction) || selectable;\n\n // One tab stop in the body: the active row. Arrows move it.\n const [active, setActive] = React.useState(0);\n const frameRef = React.useRef<HTMLDivElement>(null);\n // Rows can shrink under the active index (a new page, a filter).\n const activeRow = Math.min(active, Math.max(0, rows.length - 1));\n\n const toggle = (id: string) => {\n if (!onSelectedChange) return;\n const next = new Set(selectedSet);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n onSelectedChange([...next]);\n };\n const toggleAll = () => {\n if (!onSelectedChange) return;\n const next = new Set(selectedSet);\n if (allState === true) ids.forEach((id) => next.delete(id));\n else ids.forEach((id) => next.add(id));\n onSelectedChange([...next]);\n };\n const focusRow = (i: number) => {\n const clamped = Math.min(Math.max(i, 0), rows.length - 1);\n setActive(clamped);\n frameRef.current\n ?.querySelectorAll<HTMLElement>('[data-slot=\"table-body\"] > [data-slot=\"table-row\"]')\n [clamped]?.focus();\n };\n\n const onRowKeyDown = (event: React.KeyboardEvent<HTMLTableRowElement>, i: number, row: T) => {\n if (event.target !== event.currentTarget) return;\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focusRow(i + 1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focusRow(i - 1);\n break;\n case 'Home':\n event.preventDefault();\n focusRow(0);\n break;\n case 'End':\n event.preventDefault();\n focusRow(rows.length - 1);\n break;\n case 'Enter':\n if (onRowAction) {\n event.preventDefault();\n onRowAction(row);\n }\n break;\n case ' ':\n if (selectable) {\n event.preventDefault();\n toggle(getRowId(row));\n }\n break;\n }\n };\n\n // Headers are gone on cards, so sorting moves to a menu in the toolbar.\n const sortable = onSortChange ? columns.filter((c) => c.sortable) : [];\n const columnLabel = (c: DataTableColumn<T>) => c.cardLabel ?? textOf(c.header) ?? c.id;\n const cardSort =\n cards && sortable.length > 0 && onSortChange ? (\n <Select\n value={sort ? `${sort.columnId}:${sort.direction}` : 'none'}\n onValueChange={(v) => {\n if (v === 'none') return onSortChange(null);\n const [columnId = '', direction] = v.split(':');\n onSortChange({ columnId, direction: direction === 'desc' ? 'desc' : 'asc' });\n }}\n >\n <SelectTrigger aria-label=\"Sort by\" className=\"pointer-coarse:h-11\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectItem value=\"none\">Default order</SelectItem>\n {sortable.flatMap((c) => [\n <SelectItem key={`${c.id}:asc`} value={`${c.id}:asc`}>\n {columnLabel(c)} ascending\n </SelectItem>,\n <SelectItem key={`${c.id}:desc`} value={`${c.id}:desc`}>\n {columnLabel(c)} descending\n </SelectItem>,\n ])}\n </SelectContent>\n </Select>\n ) : null;\n const cardSelectAll =\n cards && selectable ? (\n <label\n htmlFor={`${uid}-all`}\n className=\"flex min-h-11 cursor-pointer items-center gap-2.5 pr-1 text-sm sm:min-h-9\"\n >\n <Checkbox\n id={`${uid}-all`}\n checked={allState}\n onCheckedChange={toggleAll}\n disabled={rows.length === 0}\n aria-label=\"Select all rows on this page\"\n />\n Select all\n </label>\n ) : null;\n\n const showToolbar = Boolean(\n onFilterChange || toolbar || (selectable && selectedSet.size) || cardSort || cardSelectAll,\n );\n\n const withNoun = (summary: string, total: number) =>\n rowNoun && total ? `${summary} ${rowNoun}` : summary;\n let pager: React.ReactNode = null;\n if (paginateOptions) {\n if (paging.hasPages)\n pager = (\n <Pagination {...paging.paginationProps} summary={withNoun(paging.summary, paging.total)} />\n );\n } else if (onPageChange && page !== undefined && pageCount !== undefined && pageCount > 0) {\n pager = (\n <Pagination\n page={page}\n pageCount={pageCount}\n onPageChange={onPageChange}\n summary={\n pageSummary ??\n (totalRows !== undefined && pageSize\n ? withNoun(\n paginationSummary(pageWindow({ page, pageSize, total: totalRows })),\n totalRows,\n )\n : undefined)\n }\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n onPageSizeChange={onPageSizeChange}\n />\n );\n }\n\n const toolbarNode = showToolbar && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {onFilterChange && (\n <div className=\"relative min-w-0 basis-full sm:max-w-xs sm:flex-1 sm:basis-0\">\n <Search\n className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\"\n aria-hidden\n />\n <Input\n type=\"search\"\n value={filter ?? ''}\n onChange={(e) => onFilterChange(e.target.value)}\n placeholder={filterPlaceholder}\n aria-label={`Search ${ariaLabel.toLowerCase()}`}\n className=\"pl-8\"\n />\n </div>\n )}\n {cardSelectAll}\n {selectable && (\n <span aria-live=\"polite\" className=\"text-xs text-muted-foreground tabular-nums\">\n {selectedSet.size ? `${selectedSet.size} selected` : ''}\n </span>\n )}\n {(toolbar || cardSort) && (\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {cardSort}\n {toolbar}\n </div>\n )}\n </div>\n );\n\n return (\n <div\n data-slot=\"data-table\"\n data-layout={cards ? 'cards' : 'table'}\n // One minmax(0,1fr) track: a wide table scrolls inside its frame instead\n // of stretching a grid or flex parent.\n className={cn('grid min-w-0 grid-cols-[minmax(0,1fr)] gap-3', className)}\n {...props}\n >\n {toolbarNode}\n {cards ? (\n <DataTableCards\n aria-label={ariaLabel}\n columns={columns}\n rows={rows}\n getRowId={getRowId}\n getRowLabel={getRowLabel}\n selectedSet={selectedSet}\n onToggle={selectable ? toggle : undefined}\n onRowAction={onRowAction}\n rowActions={rowActions}\n loading={loading}\n error={error}\n onRetry={onRetry}\n empty={empty}\n />\n ) : (\n <div ref={frameRef} className=\"rounded-lg border bg-surface\">\n <Table\n aria-label={ariaLabel}\n scrollLabel={ariaLabel}\n aria-busy={loading || undefined}\n density={density}\n stickyHeader={stickyHeader}\n className={cn(loading && rows.length > 0 && 'opacity-60 transition-opacity')}\n >\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n {selectable && (\n <TableHead className=\"w-10\">\n <Checkbox\n checked={allState}\n onCheckedChange={toggleAll}\n disabled={rows.length === 0}\n aria-label=\"Select all rows on this page\"\n />\n </TableHead>\n )}\n {tableColumns.map((col) => {\n const sorted = sort?.columnId === col.id ? sort.direction : undefined;\n return (\n <TableHead\n key={col.id}\n numeric={col.numeric}\n className={cn(col.hideBelow && hideBelowClass[col.hideBelow], col.className)}\n aria-sort={\n col.sortable\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n {col.sortable && onSortChange ? (\n <button\n type=\"button\"\n onClick={() => onSortChange(nextSort(sort, col.id))}\n className={cn(\n '-mx-1.5 inline-flex h-7 items-center gap-1 rounded-sm px-1.5 uppercase outline-none hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20',\n sorted && 'text-foreground',\n col.numeric && 'flex-row-reverse',\n )}\n >\n {col.header}\n {sorted === 'asc' ? (\n <ArrowUp className=\"size-3.5\" aria-hidden />\n ) : sorted === 'desc' ? (\n <ArrowDown className=\"size-3.5\" aria-hidden />\n ) : (\n <ChevronsUpDown className=\"size-3.5 opacity-50\" aria-hidden />\n )}\n </button>\n ) : (\n col.header\n )}\n </TableHead>\n );\n })}\n {rowActions && (\n <TableHead className=\"w-12\">\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n )}\n </TableRow>\n </TableHeader>\n <TableBody>\n {error ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n colSpan={colCount}\n className=\"h-auto py-8 text-center whitespace-normal\"\n >\n <ErrorMessage error={error} onRetry={onRetry} />\n </TableCell>\n </TableRow>\n ) : loading && rows.length === 0 ? (\n Array.from({ length: 3 }, (_, r) => (\n <TableRow key={`loading-${r}`} className=\"hover:bg-transparent\" aria-hidden>\n {Array.from({ length: colCount }, (_, c) => (\n <TableCell key={c}>\n <Skeleton className=\"h-3.5 w-full max-w-40\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : rows.length === 0 ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n colSpan={colCount}\n className=\"h-auto py-10 text-center whitespace-normal text-muted-foreground\"\n >\n {empty}\n </TableCell>\n </TableRow>\n ) : (\n rows.map((row, i) => {\n const id = getRowId(row);\n const isSelected = selectedSet.has(id);\n const label = getRowLabel?.(row) ?? id;\n return (\n <TableRow\n key={id}\n selected={isSelected}\n tabIndex={interactive ? (i === activeRow ? 0 : -1) : undefined}\n onFocus={() => setActive(i)}\n onKeyDown={interactive ? (e) => onRowKeyDown(e, i, row) : undefined}\n onClick={\n onRowAction\n ? (e) => {\n if ((e.target as HTMLElement).closest(INTERACTIVE)) return;\n onRowAction(row);\n }\n : undefined\n }\n className={cn(\n interactive &&\n 'outline-none focus-visible:bg-muted/60 focus-visible:shadow-[inset_2px_0_0_var(--ring)]',\n onRowAction && 'cursor-pointer',\n )}\n >\n {selectable && (\n <TableCell className=\"w-10\">\n <Checkbox\n checked={isSelected}\n onCheckedChange={() => toggle(id)}\n aria-label={`Select ${label}`}\n tabIndex={-1}\n />\n </TableCell>\n )}\n {tableColumns.map((col) => (\n <TableCell\n key={col.id}\n numeric={col.numeric}\n className={cn(\n col.hideBelow && hideBelowClass[col.hideBelow],\n col.className,\n )}\n >\n {col.cell(row)}\n </TableCell>\n ))}\n {rowActions && (\n <TableCell className=\"w-12 text-right\">{rowActions(row)}</TableCell>\n )}\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n )}\n {pager}\n </div>\n );\n}\n\nfunction ErrorMessage({ error, onRetry }: { error: React.ReactNode; onRetry?: () => void }) {\n return (\n <div role=\"alert\" className=\"grid justify-items-center gap-3 text-sm\">\n <span className=\"text-destructive\">{error}</span>\n {onRetry && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onRetry}>\n Try again\n </Button>\n )}\n </div>\n );\n}\n\nconst cardLabelClass =\n 'text-[11px] font-semibold tracking-[0.06em] text-muted-foreground uppercase';\n\n// The title's open button covers the card with an ::after overlay. A link or\n// control inside a subtitle or field (a mailto link, a toggle) would sit under\n// it, unlike the table, where clicks on a control belong to the control\n// (INTERACTIVE). Lift them above the overlay; the rest of the area still opens\n// the row.\nconst liftControls =\n '[&_a]:relative [&_a]:z-10 [&_button]:relative [&_button]:z-10 [&_input]:relative [&_input]:z-10 [&_select]:relative [&_select]:z-10 [&_textarea]:relative [&_textarea]:z-10';\n\n/**\n * The phone layout: a list of articles, one per row, each named by its title.\n * The title is the row's open button (its hit area covers the card); the\n * checkbox, row actions and footer controls sit above it and keep their own\n * clicks. No roving focus: Tab walks the controls, as in any list of links.\n */\nfunction DataTableCards<T>({\n 'aria-label': ariaLabel,\n columns,\n rows,\n getRowId,\n getRowLabel,\n selectedSet,\n onToggle,\n onRowAction,\n rowActions,\n loading,\n error,\n onRetry,\n empty,\n}: {\n 'aria-label': string;\n columns: DataTableColumn<T>[];\n rows: T[];\n getRowId: (row: T) => string;\n getRowLabel?: (row: T) => string;\n selectedSet: Set<string>;\n onToggle?: (id: string) => void;\n onRowAction?: (row: T) => void;\n rowActions?: (row: T) => React.ReactNode;\n loading: boolean;\n error?: React.ReactNode;\n onRetry?: () => void;\n empty: React.ReactNode;\n}) {\n const uid = React.useId();\n if (error)\n return (\n <div className=\"rounded-lg border bg-surface px-4 py-8\">\n <ErrorMessage error={error} onRetry={onRetry} />\n </div>\n );\n if (rows.length === 0 && !loading)\n return (\n <div className=\"rounded-lg border bg-surface px-4 py-10 text-center text-sm text-muted-foreground\">\n {empty}\n </div>\n );\n\n const visible = columns.filter((c) => c.card !== 'hidden');\n // With no column marked as the title, the first unplaced column is it.\n const firstUnplaced = visible.some((c) => c.card === 'title')\n ? undefined\n : visible.find((c) => c.card === undefined);\n const slotOf = (c: DataTableColumn<T>): DataTableCardSlot =>\n c.card ?? (c === firstUnplaced ? 'title' : 'field');\n const inSlot = (s: DataTableCardSlot) => visible.filter((c) => slotOf(c) === s);\n const title = inSlot('title');\n const subtitle = inSlot('subtitle');\n const aside = inSlot('aside');\n const fields = inSlot('field');\n const footer = inSlot('footer');\n const show = (c: DataTableColumn<T>, row: T) => (c.cardCell ?? c.cell)(row);\n\n return (\n // role=\"list\": Safari drops list semantics from a list with no bullets.\n // eslint-disable-next-line jsx-a11y/no-redundant-roles\n <ul\n role=\"list\"\n aria-label={ariaLabel}\n aria-busy={loading || undefined}\n data-slot=\"data-table-cards\"\n className={cn('grid gap-2', loading && rows.length > 0 && 'opacity-60 transition-opacity')}\n >\n {loading && rows.length === 0\n ? Array.from({ length: 3 }, (_, r) => (\n <li\n key={`loading-${r}`}\n aria-hidden\n className=\"grid gap-3 rounded-lg border bg-surface p-3.5\"\n >\n <Skeleton className=\"h-4 w-1/2\" />\n <Skeleton className=\"h-3.5 w-3/4\" />\n </li>\n ))\n : rows.map((row, i) => {\n const id = getRowId(row);\n const label = getRowLabel?.(row) ?? id;\n const isSelected = selectedSet.has(id);\n const titleId = `${uid}-${i}`;\n return (\n <li key={id}>\n <article\n aria-labelledby={title.length ? titleId : undefined}\n aria-label={title.length ? undefined : label}\n data-slot=\"data-table-card\"\n data-state={isSelected ? 'selected' : undefined}\n className={cn(\n 'relative grid gap-3 rounded-lg border bg-surface p-3.5 shadow-xs transition-colors',\n onRowAction &&\n 'hover:bg-muted/40 has-[[data-row-action]:focus-visible]:border-ring has-[[data-row-action]:focus-visible]:inset-ring-1 has-[[data-row-action]:focus-visible]:inset-ring-ring',\n 'data-[state=selected]:border-brand/40 data-[state=selected]:bg-brand-soft/60',\n )}\n >\n <div className=\"flex items-start gap-3\">\n {onToggle && (\n // A 44px target around the 16px box.\n <label\n htmlFor={`${titleId}-select`}\n className=\"relative z-10 -mx-3.5 -my-3 grid size-11 shrink-0 cursor-pointer place-items-center\"\n >\n <Checkbox\n id={`${titleId}-select`}\n checked={isSelected}\n onCheckedChange={() => onToggle(id)}\n aria-label={`Select ${label}`}\n />\n </label>\n )}\n <div className=\"grid min-w-0 flex-1 gap-0.5\">\n {title.map((c, j) => (\n <div\n key={c.id}\n id={j === 0 ? titleId : undefined}\n className=\"min-w-0 text-[15px] leading-5 font-semibold [overflow-wrap:anywhere]\"\n >\n {onRowAction && j === 0 ? (\n <button\n type=\"button\"\n data-row-action=\"\"\n onClick={() => onRowAction(row)}\n className=\"text-left outline-hidden! after:absolute after:inset-0 after:rounded-lg\"\n >\n {show(c, row)}\n </button>\n ) : (\n show(c, row)\n )}\n </div>\n ))}\n </div>\n {aside.length > 0 && (\n <div className=\"relative z-10 flex shrink-0 flex-col items-end gap-1\">\n {aside.map((c) => (\n <div key={c.id}>{show(c, row)}</div>\n ))}\n </div>\n )}\n {rowActions && (\n <div className=\"relative z-10 -my-2.5 -mr-1.5 shrink-0\">\n {rowActions(row)}\n </div>\n )}\n </div>\n {subtitle.length > 0 && (\n // Under the header row, not beside the status, so it gets the card's width.\n <div\n className={cn('-mt-2 grid min-w-0 gap-0.5', liftControls, onToggle && 'pl-7')}\n >\n {subtitle.map((c) => (\n <div\n key={c.id}\n className=\"min-w-0 text-sm text-muted-foreground [overflow-wrap:anywhere]\"\n >\n {show(c, row)}\n </div>\n ))}\n </div>\n )}\n {fields.length > 0 && (\n <dl className={cn('grid grid-cols-2 gap-x-4 gap-y-2.5 text-sm', liftControls)}>\n {fields.map((c) => (\n <div key={c.id} className=\"min-w-0\">\n <dt className={cardLabelClass}>{c.cardLabel ?? c.header}</dt>\n <dd\n className={cn(\n 'mt-0.5 min-w-0 [overflow-wrap:anywhere]',\n c.numeric && 'tabular-nums',\n )}\n >\n {show(c, row)}\n </dd>\n </div>\n ))}\n </dl>\n )}\n {footer.map((c) => (\n <div key={c.id} className=\"relative z-10 flex flex-wrap gap-2\">\n {show(c, row)}\n </div>\n ))}\n </article>\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport { DataTable };\n"],"mappings":"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"}
1
+ {"version":3,"file":"data-table.js","names":[],"sources":["../../src/components/data-table.tsx"],"sourcesContent":["import ArrowDown from '@burtson-labs/icons/react/arrow-down';\nimport ArrowUp from '@burtson-labs/icons/react/arrow-up';\nimport ChevronsUpDown from '@burtson-labs/icons/react/chevrons-up-down';\nimport * as React from 'react';\n\nimport { useNarrowerThan } from '../lib/media';\nimport { cn, focusRingClasses, noOutlineClasses } from '../lib/utils';\n\nimport { Button } from './button';\nimport { Checkbox } from './checkbox';\nimport { SearchInput } from './input';\nimport { Pagination, pageWindow, paginationSummary, usePagination } from './pagination';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './select';\nimport { Skeleton } from './skeleton';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './table';\n\n/**\n * Where a column goes on a phone card: `title` and `subtitle` head the card,\n * `aside` sits top right (a status badge), `field` is a labelled value in a\n * two-column grid, `footer` is a full-width line at the bottom (links,\n * buttons), `hidden` is left off the card.\n */\nexport type DataTableCardSlot = 'title' | 'subtitle' | 'aside' | 'field' | 'footer' | 'hidden';\n\nexport type DataTableBreakpoint = 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface DataTableColumn<T> {\n id: string;\n header: React.ReactNode;\n cell: (row: T) => React.ReactNode;\n sortable?: boolean;\n /** Right-aligned tabular figures. */\n numeric?: boolean;\n className?: string;\n /**\n * Place on a phone card. With no column marked `title`, the first column\n * is the title; every other column is a `field` unless it says otherwise.\n */\n card?: DataTableCardSlot;\n /** The field's label on a card when `header` is not plain text. */\n cardLabel?: string;\n /** A shorter rendering for the card, e.g. a date without the time. */\n cardCell?: (row: T) => React.ReactNode;\n /** Only on cards, never a table column (e.g. a subtitle the table shows in another cell). */\n cardOnly?: boolean;\n /** Leave the column out of the table below this width (tablets). */\n hideBelow?: DataTableBreakpoint;\n}\n\nexport interface DataTablePaginateOptions {\n /** Starting rows per page; the first option by default. */\n pageSize?: number;\n /** 25, 50 and 100 by default. */\n pageSizeOptions?: readonly number[];\n /** Remembers the chosen page size in localStorage under this key. */\n storageKey?: string;\n}\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport interface DataTableSort {\n columnId: string;\n direction: SortDirection;\n}\n\nexport interface DataTableProps<T> extends Omit<React.ComponentProps<'div'>, 'children'> {\n /** Required: what the table lists, e.g. \"Workspace members\". */\n 'aria-label': string;\n columns: DataTableColumn<T>[];\n /** The rows to show now: already sorted, filtered and paged by the app or server. */\n rows: T[];\n getRowId: (row: T) => string;\n /** Names a row for screen readers (\"Select Ada Lovelace\"). Defaults to its id. */\n getRowLabel?: (row: T) => string;\n\n /** Controlled sort. A sortable header cycles ascending, descending, none. */\n sort?: DataTableSort | null;\n onSortChange?: (sort: DataTableSort | null) => void;\n\n /** Controlled filter text; a search box appears when onFilterChange is set. */\n filter?: string;\n onFilterChange?: (value: string) => void;\n filterPlaceholder?: string;\n\n /** Controlled selection by row id; checkboxes appear when onSelectedChange is set. */\n selected?: string[];\n onSelectedChange?: (ids: string[]) => void;\n\n /** Enter or a click on the row, e.g. open the record. */\n onRowAction?: (row: T) => void;\n /** Per-row controls in a trailing column, e.g. a DropdownMenu. */\n rowActions?: (row: T) => React.ReactNode;\n\n /** 1-based; Pagination appears when onPageChange is set. */\n page?: number;\n pageCount?: number;\n onPageChange?: (page: number) => void;\n /** e.g. \"1–25 of 312\". Worked out from `totalRows` and `pageSize` when left out. */\n pageSummary?: React.ReactNode;\n /** Rows per page, for the page-size menu and the summary. */\n pageSize?: number;\n pageSizeOptions?: readonly number[];\n /** Adds a rows-per-page menu beside the pages. */\n onPageSizeChange?: (pageSize: number) => void;\n /** Every row on every page (server paging), for the summary. */\n totalRows?: number;\n /**\n * Page in the browser: pass every row in `rows` and the table shows one\n * page, with a rows-per-page menu. It goes back to page 1 when `filter` or\n * `sort` changes. Leave out to page in your app or on the server.\n */\n paginate?: boolean | DataTablePaginateOptions;\n /** Plural noun appended to the built-in summary: \"1–25 of 312 members\". */\n rowNoun?: string;\n\n loading?: boolean;\n /** A message shown in place of the rows. */\n error?: React.ReactNode;\n onRetry?: () => void;\n /** Shown when there are no rows and nothing failed. */\n empty?: React.ReactNode;\n /** Extra controls beside the search box, e.g. filters or a bulk action. */\n toolbar?: React.ReactNode;\n density?: 'compact' | 'default';\n stickyHeader?: boolean;\n /**\n * Below this width the rows become a list of cards (see DataTableColumn\n * `card`). Cards need a column that says where it goes: with no `card`\n * placement and no `cardsBelow`, the table stays a table (a scrolling\n * region) at every width. Set `cardsBelow` (`md` is 768px) to get cards\n * with the first column as the title; `false` keeps the table.\n */\n cardsBelow?: DataTableBreakpoint | false;\n /** Keep the first column in view while the table scrolls sideways. */\n pinFirstColumn?: boolean;\n}\n\nconst hideBelowClass: Record<DataTableBreakpoint, string> = {\n sm: 'hidden sm:table-cell',\n md: 'hidden md:table-cell',\n lg: 'hidden lg:table-cell',\n xl: 'hidden xl:table-cell',\n};\n\nconst textOf = (node: React.ReactNode): string | undefined =>\n typeof node === 'string' || typeof node === 'number' ? String(node) : undefined;\n\nconst nextSort = (current: DataTableSort | null | undefined, id: string): DataTableSort | null => {\n if (!current || current.columnId !== id) return { columnId: id, direction: 'asc' };\n return current.direction === 'asc' ? { columnId: id, direction: 'desc' } : null;\n};\n\n// Clicks and keys aimed at these belong to them, not to the row.\nconst INTERACTIVE = 'a,button,input,select,textarea,[role=\"checkbox\"],[role=\"menuitem\"]';\n\n/**\n * A table recipe for records: sort, search, select, page, and row actions,\n * with loading, empty and error states. Fully controlled, so the data can\n * come from a server; the table never reorders rows itself. On a phone the\n * rows become cards (`cardsBelow`), with the same columns.\n */\nfunction DataTable<T>({\n 'aria-label': ariaLabel,\n columns,\n rows: rowsProp,\n getRowId,\n getRowLabel,\n sort,\n onSortChange,\n filter,\n onFilterChange,\n filterPlaceholder = 'Search',\n selected,\n onSelectedChange,\n onRowAction,\n rowActions,\n page,\n pageCount,\n onPageChange,\n pageSummary,\n pageSize,\n pageSizeOptions,\n onPageSizeChange,\n totalRows,\n paginate,\n rowNoun,\n loading = false,\n error,\n onRetry,\n empty = 'No results.',\n toolbar,\n density = 'default',\n stickyHeader,\n cardsBelow,\n pinFirstColumn,\n className,\n ...props\n}: DataTableProps<T>) {\n const paginateOptions = paginate === true ? {} : paginate || undefined;\n const paging = usePagination(rowsProp, {\n defaultPageSize: paginateOptions?.pageSize,\n pageSizeOptions: paginateOptions?.pageSizeOptions,\n storageKey: paginateOptions?.storageKey,\n // A new search or sort starts again at page 1.\n resetKey: `${filter ?? ''}\\u0000${sort?.columnId ?? ''}\\u0000${sort?.direction ?? ''}`,\n });\n const rows = paginateOptions ? paging.rows : rowsProp;\n // Cards only where a column has placed itself, or the caller asked.\n const placed = columns.some((c) => c.card !== undefined);\n const cards = useNarrowerThan(cardsBelow ?? (placed ? 'md' : false));\n const uid = React.useId();\n\n const selectable = Boolean(onSelectedChange);\n const selectedSet = React.useMemo(() => new Set(selected ?? []), [selected]);\n const ids = rows.map(getRowId);\n const pageSelected = ids.filter((id) => selectedSet.has(id)).length;\n const allState: boolean | 'indeterminate' =\n ids.length > 0 && pageSelected === ids.length\n ? true\n : pageSelected > 0\n ? 'indeterminate'\n : false;\n const tableColumns = columns.filter((c) => !c.cardOnly);\n const colCount = tableColumns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0);\n const interactive = Boolean(onRowAction) || selectable;\n\n // One tab stop in the body: the active row. Arrows move it.\n const [active, setActive] = React.useState(0);\n const frameRef = React.useRef<HTMLDivElement>(null);\n // Rows can shrink under the active index (a new page, a filter).\n const activeRow = Math.min(active, Math.max(0, rows.length - 1));\n\n const toggle = (id: string) => {\n if (!onSelectedChange) return;\n const next = new Set(selectedSet);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n onSelectedChange([...next]);\n };\n const toggleAll = () => {\n if (!onSelectedChange) return;\n const next = new Set(selectedSet);\n if (allState === true) ids.forEach((id) => next.delete(id));\n else ids.forEach((id) => next.add(id));\n onSelectedChange([...next]);\n };\n const focusRow = (i: number) => {\n const clamped = Math.min(Math.max(i, 0), rows.length - 1);\n setActive(clamped);\n frameRef.current\n ?.querySelectorAll<HTMLElement>('[data-slot=\"table-body\"] > [data-slot=\"table-row\"]')\n [clamped]?.focus();\n };\n\n const onRowKeyDown = (event: React.KeyboardEvent<HTMLTableRowElement>, i: number, row: T) => {\n if (event.target !== event.currentTarget) return;\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focusRow(i + 1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focusRow(i - 1);\n break;\n case 'Home':\n event.preventDefault();\n focusRow(0);\n break;\n case 'End':\n event.preventDefault();\n focusRow(rows.length - 1);\n break;\n case 'Enter':\n if (onRowAction) {\n event.preventDefault();\n onRowAction(row);\n }\n break;\n case ' ':\n if (selectable) {\n event.preventDefault();\n toggle(getRowId(row));\n }\n break;\n }\n };\n\n // Headers are gone on cards, so sorting moves to a menu in the toolbar.\n const sortable = onSortChange ? columns.filter((c) => c.sortable) : [];\n const columnLabel = (c: DataTableColumn<T>) => c.cardLabel ?? textOf(c.header) ?? c.id;\n const cardSort =\n cards && sortable.length > 0 && onSortChange ? (\n <Select\n value={sort ? `${sort.columnId}:${sort.direction}` : 'none'}\n onValueChange={(v) => {\n if (v === 'none') return onSortChange(null);\n const [columnId = '', direction] = v.split(':');\n onSortChange({ columnId, direction: direction === 'desc' ? 'desc' : 'asc' });\n }}\n >\n <SelectTrigger aria-label=\"Sort by\" className=\"pointer-coarse:h-11\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectItem value=\"none\">Default order</SelectItem>\n {sortable.flatMap((c) => [\n <SelectItem key={`${c.id}:asc`} value={`${c.id}:asc`}>\n {columnLabel(c)} ascending\n </SelectItem>,\n <SelectItem key={`${c.id}:desc`} value={`${c.id}:desc`}>\n {columnLabel(c)} descending\n </SelectItem>,\n ])}\n </SelectContent>\n </Select>\n ) : null;\n const cardSelectAll =\n cards && selectable ? (\n <label\n htmlFor={`${uid}-all`}\n className=\"flex min-h-11 cursor-pointer items-center gap-2.5 pr-1 text-sm sm:min-h-9\"\n >\n <Checkbox\n id={`${uid}-all`}\n checked={allState}\n onCheckedChange={toggleAll}\n disabled={rows.length === 0}\n aria-label=\"Select all rows on this page\"\n />\n Select all\n </label>\n ) : null;\n\n const showToolbar = Boolean(\n onFilterChange || toolbar || (selectable && selectedSet.size) || cardSort || cardSelectAll,\n );\n\n const withNoun = (summary: string, total: number) =>\n rowNoun && total ? `${summary} ${rowNoun}` : summary;\n let pager: React.ReactNode = null;\n if (paginateOptions) {\n if (paging.hasPages)\n pager = (\n <Pagination {...paging.paginationProps} summary={withNoun(paging.summary, paging.total)} />\n );\n } else if (onPageChange && page !== undefined && pageCount !== undefined && pageCount > 0) {\n pager = (\n <Pagination\n page={page}\n pageCount={pageCount}\n onPageChange={onPageChange}\n summary={\n pageSummary ??\n (totalRows !== undefined && pageSize\n ? withNoun(\n paginationSummary(pageWindow({ page, pageSize, total: totalRows })),\n totalRows,\n )\n : undefined)\n }\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n onPageSizeChange={onPageSizeChange}\n />\n );\n }\n\n const toolbarNode = showToolbar && (\n <div className=\"flex flex-wrap items-center gap-2\">\n {onFilterChange && (\n <SearchInput\n value={filter ?? ''}\n onChange={(e) => onFilterChange(e.target.value)}\n placeholder={filterPlaceholder}\n aria-label={`Search ${ariaLabel.toLowerCase()}`}\n containerClassName=\"min-w-0 basis-full sm:max-w-xs sm:flex-1 sm:basis-0\"\n />\n )}\n {cardSelectAll}\n {selectable && (\n <span aria-live=\"polite\" className=\"text-xs text-muted-foreground tabular-nums\">\n {selectedSet.size ? `${selectedSet.size} selected` : ''}\n </span>\n )}\n {(toolbar || cardSort) && (\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {cardSort}\n {toolbar}\n </div>\n )}\n </div>\n );\n\n return (\n <div\n data-slot=\"data-table\"\n data-layout={cards ? 'cards' : 'table'}\n // One minmax(0,1fr) track: a wide table scrolls inside its frame instead\n // of stretching a grid or flex parent.\n className={cn('grid w-full min-w-0 grid-cols-[minmax(0,1fr)] gap-3', className)}\n {...props}\n >\n {toolbarNode}\n {cards ? (\n <DataTableCards\n aria-label={ariaLabel}\n columns={columns}\n rows={rows}\n getRowId={getRowId}\n getRowLabel={getRowLabel}\n selectedSet={selectedSet}\n onToggle={selectable ? toggle : undefined}\n onRowAction={onRowAction}\n rowActions={rowActions}\n loading={loading}\n error={error}\n onRetry={onRetry}\n empty={empty}\n />\n ) : (\n <div ref={frameRef} className=\"rounded-lg border bg-surface\">\n <Table\n aria-label={ariaLabel}\n scrollLabel={ariaLabel}\n aria-busy={loading || undefined}\n density={density}\n stickyHeader={stickyHeader}\n pinFirstColumn={pinFirstColumn}\n className={cn(loading && rows.length > 0 && 'opacity-60 transition-opacity')}\n >\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n {selectable && (\n <TableHead className=\"w-10\">\n <Checkbox\n checked={allState}\n onCheckedChange={toggleAll}\n disabled={rows.length === 0}\n aria-label=\"Select all rows on this page\"\n />\n </TableHead>\n )}\n {tableColumns.map((col) => {\n const sorted = sort?.columnId === col.id ? sort.direction : undefined;\n return (\n <TableHead\n key={col.id}\n numeric={col.numeric}\n className={cn(col.hideBelow && hideBelowClass[col.hideBelow], col.className)}\n aria-sort={\n col.sortable\n ? sorted === 'asc'\n ? 'ascending'\n : sorted === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n {col.sortable && onSortChange ? (\n <button\n type=\"button\"\n onClick={() => onSortChange(nextSort(sort, col.id))}\n className={cn(\n '-mx-1.5 inline-flex h-7 items-center gap-1 rounded-sm px-1.5 uppercase hover:bg-muted hover:text-foreground',\n focusRingClasses,\n 'focus-visible:outline-offset-[-2px]',\n sorted && 'text-foreground',\n col.numeric && 'flex-row-reverse',\n )}\n >\n {col.header}\n {sorted === 'asc' ? (\n <ArrowUp className=\"size-3.5\" aria-hidden />\n ) : sorted === 'desc' ? (\n <ArrowDown className=\"size-3.5\" aria-hidden />\n ) : (\n <ChevronsUpDown className=\"size-3.5 opacity-50\" aria-hidden />\n )}\n </button>\n ) : (\n col.header\n )}\n </TableHead>\n );\n })}\n {rowActions && (\n <TableHead className=\"w-12\">\n <span className=\"sr-only\">Actions</span>\n </TableHead>\n )}\n </TableRow>\n </TableHeader>\n <TableBody>\n {error ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n colSpan={colCount}\n className=\"h-auto py-8 text-center whitespace-normal\"\n >\n <ErrorMessage error={error} onRetry={onRetry} />\n </TableCell>\n </TableRow>\n ) : loading && rows.length === 0 ? (\n Array.from({ length: 3 }, (_, r) => (\n <TableRow key={`loading-${r}`} className=\"hover:bg-transparent\" aria-hidden>\n {Array.from({ length: colCount }, (_, c) => (\n <TableCell key={c}>\n <Skeleton className=\"h-3.5 w-full max-w-40\" />\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : rows.length === 0 ? (\n <TableRow className=\"hover:bg-transparent\">\n <TableCell\n colSpan={colCount}\n className=\"h-auto py-10 text-center whitespace-normal text-muted-foreground\"\n >\n {empty}\n </TableCell>\n </TableRow>\n ) : (\n rows.map((row, i) => {\n const id = getRowId(row);\n const isSelected = selectedSet.has(id);\n const label = getRowLabel?.(row) ?? id;\n return (\n <TableRow\n key={id}\n selected={isSelected}\n tabIndex={interactive ? (i === activeRow ? 0 : -1) : undefined}\n onFocus={() => setActive(i)}\n onKeyDown={interactive ? (e) => onRowKeyDown(e, i, row) : undefined}\n onClick={\n onRowAction\n ? (e) => {\n if ((e.target as HTMLElement).closest(INTERACTIVE)) return;\n onRowAction(row);\n }\n : undefined\n }\n className={cn(\n interactive &&\n 'outline-none focus-visible:bg-muted/60 focus-visible:shadow-[inset_2px_0_0_var(--ring)]',\n onRowAction && 'cursor-pointer',\n )}\n >\n {selectable && (\n <TableCell className=\"w-10\">\n <Checkbox\n checked={isSelected}\n onCheckedChange={() => toggle(id)}\n aria-label={`Select ${label}`}\n tabIndex={-1}\n />\n </TableCell>\n )}\n {tableColumns.map((col) => (\n <TableCell\n key={col.id}\n numeric={col.numeric}\n className={cn(\n col.hideBelow && hideBelowClass[col.hideBelow],\n col.className,\n )}\n >\n {col.cell(row)}\n </TableCell>\n ))}\n {rowActions && (\n <TableCell className=\"w-12 text-right\">{rowActions(row)}</TableCell>\n )}\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n )}\n {pager}\n </div>\n );\n}\n\nfunction ErrorMessage({ error, onRetry }: { error: React.ReactNode; onRetry?: () => void }) {\n return (\n <div role=\"alert\" className=\"grid justify-items-center gap-3 text-sm\">\n <span className=\"text-destructive\">{error}</span>\n {onRetry && (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onRetry}>\n Try again\n </Button>\n )}\n </div>\n );\n}\n\nconst cardLabelClass =\n 'text-[11px] font-semibold tracking-[0.06em] text-muted-foreground uppercase';\n\n// The title's open button covers the card with an ::after overlay. A link or\n// control inside a subtitle or field (a mailto link, a toggle) would sit under\n// it, unlike the table, where clicks on a control belong to the control\n// (INTERACTIVE). Lift them above the overlay; the rest of the area still opens\n// the row.\nconst liftControls =\n '[&_a]:relative [&_a]:z-10 [&_button]:relative [&_button]:z-10 [&_input]:relative [&_input]:z-10 [&_select]:relative [&_select]:z-10 [&_textarea]:relative [&_textarea]:z-10';\n\n/**\n * The phone layout: a list of articles, one per row, each named by its title.\n * The title is the row's open button (its hit area covers the card); the\n * checkbox, row actions and footer controls sit above it and keep their own\n * clicks. No roving focus: Tab walks the controls, as in any list of links.\n */\nfunction DataTableCards<T>({\n 'aria-label': ariaLabel,\n columns,\n rows,\n getRowId,\n getRowLabel,\n selectedSet,\n onToggle,\n onRowAction,\n rowActions,\n loading,\n error,\n onRetry,\n empty,\n}: {\n 'aria-label': string;\n columns: DataTableColumn<T>[];\n rows: T[];\n getRowId: (row: T) => string;\n getRowLabel?: (row: T) => string;\n selectedSet: Set<string>;\n onToggle?: (id: string) => void;\n onRowAction?: (row: T) => void;\n rowActions?: (row: T) => React.ReactNode;\n loading: boolean;\n error?: React.ReactNode;\n onRetry?: () => void;\n empty: React.ReactNode;\n}) {\n const uid = React.useId();\n if (error)\n return (\n <div className=\"rounded-lg border bg-surface px-4 py-8\">\n <ErrorMessage error={error} onRetry={onRetry} />\n </div>\n );\n if (rows.length === 0 && !loading)\n return (\n <div className=\"rounded-lg border bg-surface px-4 py-10 text-center text-sm text-muted-foreground\">\n {empty}\n </div>\n );\n\n const visible = columns.filter((c) => c.card !== 'hidden');\n // With no column marked as the title, the first unplaced column is it.\n const firstUnplaced = visible.some((c) => c.card === 'title')\n ? undefined\n : visible.find((c) => c.card === undefined);\n const slotOf = (c: DataTableColumn<T>): DataTableCardSlot =>\n c.card ?? (c === firstUnplaced ? 'title' : 'field');\n const inSlot = (s: DataTableCardSlot) => visible.filter((c) => slotOf(c) === s);\n const title = inSlot('title');\n const subtitle = inSlot('subtitle');\n const aside = inSlot('aside');\n const fields = inSlot('field');\n const footer = inSlot('footer');\n const show = (c: DataTableColumn<T>, row: T) => (c.cardCell ?? c.cell)(row);\n\n return (\n // role=\"list\": Safari drops list semantics from a list with no bullets.\n // eslint-disable-next-line jsx-a11y/no-redundant-roles\n <ul\n role=\"list\"\n aria-label={ariaLabel}\n aria-busy={loading || undefined}\n data-slot=\"data-table-cards\"\n className={cn('grid gap-2', loading && rows.length > 0 && 'opacity-60 transition-opacity')}\n >\n {loading && rows.length === 0\n ? Array.from({ length: 3 }, (_, r) => (\n <li\n key={`loading-${r}`}\n aria-hidden\n className=\"grid gap-3 rounded-lg border bg-surface p-3.5\"\n >\n <Skeleton className=\"h-4 w-1/2\" />\n <Skeleton className=\"h-3.5 w-3/4\" />\n </li>\n ))\n : rows.map((row, i) => {\n const id = getRowId(row);\n const label = getRowLabel?.(row) ?? id;\n const isSelected = selectedSet.has(id);\n const titleId = `${uid}-${i}`;\n return (\n <li key={id}>\n <article\n aria-labelledby={title.length ? titleId : undefined}\n aria-label={title.length ? undefined : label}\n data-slot=\"data-table-card\"\n data-state={isSelected ? 'selected' : undefined}\n className={cn(\n 'relative grid gap-3 rounded-lg border bg-surface p-3.5 shadow-xs transition-colors',\n onRowAction &&\n 'hover:bg-muted/40 has-[[data-row-action]:focus-visible]:border-ring has-[[data-row-action]:focus-visible]:inset-ring-1 has-[[data-row-action]:focus-visible]:inset-ring-ring',\n 'data-[state=selected]:border-brand/40 data-[state=selected]:bg-brand-soft/60',\n )}\n >\n <div className=\"flex items-start gap-3\">\n {onToggle && (\n // A 44px target around the 16px box.\n <label\n htmlFor={`${titleId}-select`}\n className=\"relative z-10 -mx-3.5 -my-3 grid size-11 shrink-0 cursor-pointer place-items-center\"\n >\n <Checkbox\n id={`${titleId}-select`}\n checked={isSelected}\n onCheckedChange={() => onToggle(id)}\n aria-label={`Select ${label}`}\n />\n </label>\n )}\n <div className=\"grid min-w-0 flex-1 gap-0.5\">\n {title.map((c, j) => (\n <div\n key={c.id}\n id={j === 0 ? titleId : undefined}\n className=\"min-w-0 text-[15px] leading-5 font-semibold [overflow-wrap:anywhere]\"\n >\n {onRowAction && j === 0 ? (\n <button\n type=\"button\"\n data-row-action=\"\"\n onClick={() => onRowAction(row)}\n className={cn(\n 'text-left after:absolute after:inset-0 after:rounded-lg',\n noOutlineClasses,\n )}\n >\n {show(c, row)}\n </button>\n ) : (\n show(c, row)\n )}\n </div>\n ))}\n </div>\n {aside.length > 0 && (\n <div className=\"relative z-10 flex shrink-0 flex-col items-end gap-1\">\n {aside.map((c) => (\n <div key={c.id}>{show(c, row)}</div>\n ))}\n </div>\n )}\n {rowActions && (\n <div className=\"relative z-10 -my-2.5 -mr-1.5 shrink-0\">\n {rowActions(row)}\n </div>\n )}\n </div>\n {subtitle.length > 0 && (\n // Under the header row, not beside the status, so it gets the card's width.\n <div\n className={cn('-mt-2 grid min-w-0 gap-0.5', liftControls, onToggle && 'pl-7')}\n >\n {subtitle.map((c) => (\n <div\n key={c.id}\n className=\"min-w-0 text-sm text-muted-foreground [overflow-wrap:anywhere]\"\n >\n {show(c, row)}\n </div>\n ))}\n </div>\n )}\n {fields.length > 0 && (\n <dl className={cn('grid grid-cols-2 gap-x-4 gap-y-2.5 text-sm', liftControls)}>\n {fields.map((c) => (\n <div key={c.id} className=\"min-w-0\">\n <dt className={cardLabelClass}>{c.cardLabel ?? c.header}</dt>\n <dd\n className={cn(\n 'mt-0.5 min-w-0 [overflow-wrap:anywhere]',\n c.numeric && 'tabular-nums',\n )}\n >\n {show(c, row)}\n </dd>\n </div>\n ))}\n </dl>\n )}\n {footer.map((c) => (\n <div key={c.id} className=\"relative z-10 flex flex-wrap gap-2\">\n {show(c, row)}\n </div>\n ))}\n </article>\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport { DataTable };\n"],"mappings":"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"}
@@ -1,20 +1,29 @@
1
- import { Dialog as DialogPrimitive } from 'radix-ui';
2
1
  import * as React from 'react';
2
+ import * as DialogPrimitive from '../primitives/vendor/radix/react-dialog';
3
3
  declare function Dialog(props: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
4
- declare function DialogTrigger(props: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element;
5
- declare function DialogClose(props: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element;
4
+ declare const DialogTrigger: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
5
+ declare const DialogClose: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
6
6
  declare function DialogPortal(props: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element;
7
- declare function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>): React.JSX.Element;
8
- declare function DialogContent({ className, children, showCloseButton, mobile, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
7
+ /** The scrim under every modal surface: shared by Dialog, AlertDialog and Sheet. */
8
+ export declare const overlayClasses = "fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in";
9
+ /**
10
+ * The corner X of a modal surface: 32px with a mouse, 44px on touch screens,
11
+ * with the shared focus outline.
12
+ */
13
+ export declare const overlayCloseClasses: string;
14
+ declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
15
+ export interface DialogContentProps extends React.ComponentProps<typeof DialogPrimitive.Content> {
9
16
  showCloseButton?: boolean;
10
17
  /**
11
18
  * `sheet`: on phones (below 640px) the dialog is a bottom sheet, full
12
19
  * width with a grab bar. Larger screens keep the centred window.
13
20
  */
14
21
  mobile?: 'center' | 'sheet';
15
- }): React.JSX.Element;
16
- declare function DialogHeader({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
17
- declare function DialogFooter({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
18
- declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element;
19
- declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): React.JSX.Element;
22
+ }
23
+ /** A centred window, 16px radius, elevation 5 (the modal shadow). */
24
+ declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogContentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
25
+ declare const DialogHeader: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
26
+ declare const DialogFooter: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
27
+ declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
28
+ declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
20
29
  export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
@@ -1,47 +1,60 @@
1
- import { cn } from "../lib/utils.js";
2
- import { Dialog } from "radix-ui";
3
- import "react";
1
+ "use client";
2
+ import { cn, focusRingClasses } from "../lib/utils.js";
3
+ import { Close as DialogClose$1, Content as DialogContent$1, Description as DialogDescription$1, Dialog as Dialog$1, DialogOverlay as DialogOverlay$1, DialogPortal as DialogPortal$1, DialogTitle as DialogTitle$1, DialogTrigger as DialogTrigger$1 } from "../primitives/vendor/radix/react-dialog/dialog.js";
4
+ import * as React from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import X from "@burtson-labs/icons/react/x";
6
7
  //#region src/components/dialog.tsx
7
- function Dialog$1(props) {
8
- return /* @__PURE__ */ jsx(Dialog.Root, {
8
+ function Dialog(props) {
9
+ return /* @__PURE__ */ jsx(Dialog$1, {
9
10
  "data-slot": "dialog",
10
11
  ...props
11
12
  });
12
13
  }
13
- function DialogTrigger(props) {
14
- return /* @__PURE__ */ jsx(Dialog.Trigger, {
14
+ var DialogTrigger = React.forwardRef(function DialogTrigger(props, ref) {
15
+ return /* @__PURE__ */ jsx(DialogTrigger$1, {
16
+ ref,
15
17
  "data-slot": "dialog-trigger",
16
18
  ...props
17
19
  });
18
- }
19
- function DialogClose(props) {
20
- return /* @__PURE__ */ jsx(Dialog.Close, {
20
+ });
21
+ var DialogClose = React.forwardRef(function DialogClose(props, ref) {
22
+ return /* @__PURE__ */ jsx(DialogClose$1, {
23
+ ref,
21
24
  "data-slot": "dialog-close",
22
25
  ...props
23
26
  });
24
- }
27
+ });
25
28
  function DialogPortal(props) {
26
- return /* @__PURE__ */ jsx(Dialog.Portal, {
29
+ return /* @__PURE__ */ jsx(DialogPortal$1, {
27
30
  "data-slot": "dialog-portal",
28
31
  ...props
29
32
  });
30
33
  }
31
- function DialogOverlay({ className, ...props }) {
32
- return /* @__PURE__ */ jsx(Dialog.Overlay, {
34
+ /** The scrim under every modal surface: shared by Dialog, AlertDialog and Sheet. */
35
+ var overlayClasses = "fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in";
36
+ /**
37
+ * The corner X of a modal surface: 32px with a mouse, 44px on touch screens,
38
+ * with the shared focus outline.
39
+ */
40
+ var overlayCloseClasses = cn("absolute top-3 right-3 grid size-8 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:top-2 pointer-coarse:right-2 pointer-coarse:size-11 [&_svg]:size-4", focusRingClasses, "focus-visible:outline-offset-[-2px]");
41
+ var DialogOverlay = React.forwardRef(function DialogOverlay({ className, ...props }, ref) {
42
+ return /* @__PURE__ */ jsx(DialogOverlay$1, {
43
+ ref,
33
44
  "data-slot": "dialog-overlay",
34
- className: cn("fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in", className),
45
+ className: cn(overlayClasses, className),
35
46
  ...props
36
47
  });
37
- }
48
+ });
38
49
  var bottomSheetClasses = "max-sm:top-auto max-sm:bottom-0 max-sm:left-0 max-sm:w-full max-sm:max-w-none max-sm:translate-x-0 max-sm:translate-y-0 max-sm:max-h-[92dvh] max-sm:rounded-b-none max-sm:border-x-0 max-sm:border-b-0 max-sm:pb-[max(1.25rem,env(safe-area-inset-bottom))] max-sm:[--bl-scale:1] max-sm:[--bl-ty:100%]";
39
- function DialogContent({ className, children, showCloseButton = true, mobile = "center", ...props }) {
50
+ /** A centred window, 16px radius, elevation 5 (the modal shadow). */
51
+ var DialogContent = React.forwardRef(function DialogContent({ className, children, showCloseButton = true, mobile = "center", ...props }, ref) {
40
52
  const sheet = mobile === "sheet";
41
- return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(Dialog.Content, {
53
+ return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogContent$1, {
54
+ ref,
42
55
  "data-slot": "dialog-content",
43
56
  "data-mobile": mobile,
44
- className: cn("fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-lg max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-[0_24px_80px_rgb(0_0_0_/_0.28)] outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6", sheet && bottomSheetClasses, className),
57
+ className: cn("fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-lg max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6", sheet && bottomSheetClasses, className),
45
58
  ...props,
46
59
  children: [
47
60
  sheet && /* @__PURE__ */ jsx("div", {
@@ -50,9 +63,9 @@ function DialogContent({ className, children, showCloseButton = true, mobile = "
50
63
  className: "mx-auto -mt-2 -mb-3 hidden h-1 w-10 shrink-0 rounded-full bg-border-strong max-sm:block"
51
64
  }),
52
65
  children,
53
- showCloseButton ? /* @__PURE__ */ jsxs(Dialog.Close, {
66
+ showCloseButton ? /* @__PURE__ */ jsxs(DialogClose$1, {
54
67
  "data-slot": "dialog-close",
55
- className: cn("absolute top-3.5 right-3.5 grid size-8 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20 [&_svg]:size-4", sheet && "max-sm:top-3 max-sm:right-3 pointer-coarse:max-sm:size-11"),
68
+ className: overlayCloseClasses,
56
69
  children: [/* @__PURE__ */ jsx(X, { "aria-hidden": true }), /* @__PURE__ */ jsx("span", {
57
70
  className: "sr-only",
58
71
  children: "Close"
@@ -60,36 +73,40 @@ function DialogContent({ className, children, showCloseButton = true, mobile = "
60
73
  }) : null
61
74
  ]
62
75
  })] });
63
- }
64
- function DialogHeader({ className, ...props }) {
76
+ });
77
+ var DialogHeader = React.forwardRef(function DialogHeader({ className, ...props }, ref) {
65
78
  return /* @__PURE__ */ jsx("div", {
79
+ ref,
66
80
  "data-slot": "dialog-header",
67
81
  className: cn("grid gap-1.5 pr-7", className),
68
82
  ...props
69
83
  });
70
- }
71
- function DialogFooter({ className, ...props }) {
84
+ });
85
+ var DialogFooter = React.forwardRef(function DialogFooter({ className, ...props }, ref) {
72
86
  return /* @__PURE__ */ jsx("div", {
87
+ ref,
73
88
  "data-slot": "dialog-footer",
74
89
  className: cn("flex flex-col-reverse gap-2 border-t border-border pt-4 sm:flex-row sm:justify-end", className),
75
90
  ...props
76
91
  });
77
- }
78
- function DialogTitle({ className, ...props }) {
79
- return /* @__PURE__ */ jsx(Dialog.Title, {
92
+ });
93
+ var DialogTitle = React.forwardRef(function DialogTitle({ className, ...props }, ref) {
94
+ return /* @__PURE__ */ jsx(DialogTitle$1, {
95
+ ref,
80
96
  "data-slot": "dialog-title",
81
97
  className: cn("text-base font-semibold tracking-[-0.02em]", className),
82
98
  ...props
83
99
  });
84
- }
85
- function DialogDescription({ className, ...props }) {
86
- return /* @__PURE__ */ jsx(Dialog.Description, {
100
+ });
101
+ var DialogDescription = React.forwardRef(function DialogDescription({ className, ...props }, ref) {
102
+ return /* @__PURE__ */ jsx(DialogDescription$1, {
103
+ ref,
87
104
  "data-slot": "dialog-description",
88
105
  className: cn("text-sm leading-5 text-muted-foreground", className),
89
106
  ...props
90
107
  });
91
- }
108
+ });
92
109
  //#endregion
93
- export { Dialog$1 as Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger };
110
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, overlayClasses, overlayCloseClasses };
94
111
 
95
112
  //# sourceMappingURL=dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","names":["Dialog","DialogPrimitive"],"sources":["../../src/components/dialog.tsx"],"sourcesContent":["import X from '@burtson-labs/icons/react/x';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport * as React from 'react';\n\nimport { cn } from '../lib/utils';\n\nfunction Dialog(props: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger(props: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogClose(props: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogPortal(props: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n 'fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in',\n className,\n )}\n {...props}\n />\n );\n}\n\n// Below 640px the dialog docks to the bottom edge, full width, and slides up:\n// thumbs reach its buttons and the keyboard does not cover a centred box.\nconst bottomSheetClasses =\n 'max-sm:top-auto max-sm:bottom-0 max-sm:left-0 max-sm:w-full max-sm:max-w-none max-sm:translate-x-0 max-sm:translate-y-0 max-sm:max-h-[92dvh] max-sm:rounded-b-none max-sm:border-x-0 max-sm:border-b-0 max-sm:pb-[max(1.25rem,env(safe-area-inset-bottom))] max-sm:[--bl-scale:1] max-sm:[--bl-ty:100%]';\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n mobile = 'center',\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n /**\n * `sheet`: on phones (below 640px) the dialog is a bottom sheet, full\n * width with a grab bar. Larger screens keep the centred window.\n */\n mobile?: 'center' | 'sheet';\n}) {\n const sheet = mobile === 'sheet';\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n data-mobile={mobile}\n className={cn(\n 'fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-lg max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-[0_24px_80px_rgb(0_0_0_/_0.28)] outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6',\n sheet && bottomSheetClasses,\n className,\n )}\n {...props}\n >\n {sheet && (\n <div\n data-slot=\"dialog-handle\"\n aria-hidden\n className=\"mx-auto -mt-2 -mb-3 hidden h-1 w-10 shrink-0 rounded-full bg-border-strong max-sm:block\"\n />\n )}\n {children}\n {showCloseButton ? (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className={cn(\n 'absolute top-3.5 right-3.5 grid size-8 place-items-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/20 [&_svg]:size-4',\n // 44px on a touch screen when it is a sheet, like Sheet's.\n sheet && 'max-sm:top-3 max-sm:right-3 pointer-coarse:max-sm:size-11',\n )}\n >\n <X aria-hidden />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n ) : null}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"dialog-header\" className={cn('grid gap-1.5 pr-7', className)} {...props} />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n 'flex flex-col-reverse gap-2 border-t border-border pt-4 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn('text-base font-semibold tracking-[-0.02em]', className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn('text-sm leading-5 text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n"],"mappings":";;;;;;AAMA,SAASA,SAAO,OAA0D;CACxE,OAAO,oBAACC,OAAgB,MAAjB;EAAsB,aAAU;EAAS,GAAI;CAAQ,CAAA;AAC9D;AAEA,SAAS,cAAc,OAA6D;CAClF,OAAO,oBAACA,OAAgB,SAAjB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,YAAY,OAA2D;CAC9E,OAAO,oBAACA,OAAgB,OAAjB;EAAuB,aAAU;EAAe,GAAI;CAAQ,CAAA;AACrE;AAEA,SAAS,aAAa,OAA4D;CAChF,OAAO,oBAACA,OAAgB,QAAjB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAEA,SAAS,cAAc,EACrB,WACA,GAAG,SACoD;CACvD,OACE,oBAACA,OAAgB,SAAjB;EACE,aAAU;EACV,WAAW,GACT,6HACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAIA,IAAM,qBACJ;AAEF,SAAS,cAAc,EACrB,WACA,UACA,kBAAkB,MAClB,SAAS,UACT,GAAG,SAQF;CACD,MAAM,QAAQ,WAAW;CACzB,OACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,eAAD,CAAgB,CAAA,GAChB,qBAACA,OAAgB,SAAjB;EACE,aAAU;EACV,eAAa;EACb,WAAW,GACT,2YACA,SAAS,oBACT,SACF;EACA,GAAI;EARN,UAAA;GAUG,SACC,oBAAC,OAAD;IACE,aAAU;IACV,eAAA;IACA,WAAU;GACX,CAAA;GAEF;GACA,kBACC,qBAACA,OAAgB,OAAjB;IACE,aAAU;IACV,WAAW,GACT,qOAEA,SAAS,2DACX;IANF,UAAA,CAQE,oBAAC,GAAD,EAAG,eAAA,KAAa,CAAA,GAChB,oBAAC,QAAD;KAAM,WAAU;KAAU,UAAA;IAAW,CAAA,CAChB;GACrB,CAAA,IAAA;EACmB;CACb,CAAA,CAAA,EAAA,CAAA;AAElB;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAsC;CAC1E,OACE,oBAAC,OAAD;EAAK,aAAU;EAAgB,WAAW,GAAG,qBAAqB,SAAS;EAAG,GAAI;CAAQ,CAAA;AAE9F;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAsC;CAC1E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,sFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,OAAgB,OAAjB;EACE,aAAU;EACV,WAAW,GAAG,8CAA8C,SAAS;EACrE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,kBAAkB,EACzB,WACA,GAAG,SACwD;CAC3D,OACE,oBAACA,OAAgB,aAAjB;EACE,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"dialog.js","names":["DialogPrimitive.Root","DialogPrimitive.Trigger","DialogPrimitive.Close","DialogPrimitive.Portal","DialogPrimitive.Overlay","DialogPrimitive.Content","DialogPrimitive.Title","DialogPrimitive.Description"],"sources":["../../src/components/dialog.tsx"],"sourcesContent":["import X from '@burtson-labs/icons/react/x';\nimport * as React from 'react';\n\nimport { cn, focusRingClasses } from '../lib/utils';\nimport * as DialogPrimitive from '../primitives/vendor/radix/react-dialog';\n\nfunction Dialog(props: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nconst DialogTrigger = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof DialogPrimitive.Trigger>\n>(function DialogTrigger(props, ref) {\n return <DialogPrimitive.Trigger ref={ref} data-slot=\"dialog-trigger\" {...props} />;\n});\n\nconst DialogClose = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof DialogPrimitive.Close>\n>(function DialogClose(props, ref) {\n return <DialogPrimitive.Close ref={ref} data-slot=\"dialog-close\" {...props} />;\n});\n\nfunction DialogPortal(props: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\n/** The scrim under every modal surface: shared by Dialog, AlertDialog and Sheet. */\nexport const overlayClasses =\n 'fixed inset-0 z-50 bg-black/55 backdrop-blur-[3px] data-[state=closed]:animate-fade-out data-[state=open]:animate-fade-in';\n\n/**\n * The corner X of a modal surface: 32px with a mouse, 44px on touch screens,\n * with the shared focus outline.\n */\nexport const overlayCloseClasses = cn(\n 'absolute top-3 right-3 grid size-8 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:top-2 pointer-coarse:right-2 pointer-coarse:size-11 [&_svg]:size-4',\n focusRingClasses,\n 'focus-visible:outline-offset-[-2px]',\n);\n\nconst DialogOverlay = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof DialogPrimitive.Overlay>\n>(function DialogOverlay({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Overlay\n ref={ref}\n data-slot=\"dialog-overlay\"\n className={cn(overlayClasses, className)}\n {...props}\n />\n );\n});\n\n// Below 640px the dialog docks to the bottom edge, full width, and slides up:\n// thumbs reach its buttons and the keyboard does not cover a centred box.\nconst bottomSheetClasses =\n 'max-sm:top-auto max-sm:bottom-0 max-sm:left-0 max-sm:w-full max-sm:max-w-none max-sm:translate-x-0 max-sm:translate-y-0 max-sm:max-h-[92dvh] max-sm:rounded-b-none max-sm:border-x-0 max-sm:border-b-0 max-sm:pb-[max(1.25rem,env(safe-area-inset-bottom))] max-sm:[--bl-scale:1] max-sm:[--bl-ty:100%]';\n\nexport interface DialogContentProps extends React.ComponentProps<typeof DialogPrimitive.Content> {\n showCloseButton?: boolean;\n /**\n * `sheet`: on phones (below 640px) the dialog is a bottom sheet, full\n * width with a grab bar. Larger screens keep the centred window.\n */\n mobile?: 'center' | 'sheet';\n}\n\n/** A centred window, 16px radius, elevation 5 (the modal shadow). */\nconst DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(function DialogContent(\n { className, children, showCloseButton = true, mobile = 'center', ...props },\n ref,\n) {\n const sheet = mobile === 'sheet';\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n data-slot=\"dialog-content\"\n data-mobile={mobile}\n className={cn(\n 'fixed top-1/2 left-1/2 z-50 grid [--bl-scale:0.95] [--bl-ty:8px] w-[calc(100%-2rem)] max-w-lg max-h-[calc(100dvh-2rem)] overflow-y-auto overscroll-contain -translate-x-1/2 -translate-y-1/2 gap-5 rounded-xl border border-border-strong bg-surface-raised p-5 text-foreground shadow-xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in sm:p-6',\n sheet && bottomSheetClasses,\n className,\n )}\n {...props}\n >\n {sheet && (\n <div\n data-slot=\"dialog-handle\"\n aria-hidden\n className=\"mx-auto -mt-2 -mb-3 hidden h-1 w-10 shrink-0 rounded-full bg-border-strong max-sm:block\"\n />\n )}\n {children}\n {showCloseButton ? (\n <DialogPrimitive.Close data-slot=\"dialog-close\" className={overlayCloseClasses}>\n <X aria-hidden />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n ) : null}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n});\n\nconst DialogHeader = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(\n function DialogHeader({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"dialog-header\"\n className={cn('grid gap-1.5 pr-7', className)}\n {...props}\n />\n );\n },\n);\n\nconst DialogFooter = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(\n function DialogFooter({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"dialog-footer\"\n className={cn(\n 'flex flex-col-reverse gap-2 border-t border-border pt-4 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nconst DialogTitle = React.forwardRef<\n HTMLHeadingElement,\n React.ComponentProps<typeof DialogPrimitive.Title>\n>(function DialogTitle({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Title\n ref={ref}\n data-slot=\"dialog-title\"\n className={cn('text-base font-semibold tracking-[-0.02em]', className)}\n {...props}\n />\n );\n});\n\nconst DialogDescription = React.forwardRef<\n HTMLParagraphElement,\n React.ComponentProps<typeof DialogPrimitive.Description>\n>(function DialogDescription({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n data-slot=\"dialog-description\"\n className={cn('text-sm leading-5 text-muted-foreground', className)}\n {...props}\n />\n );\n});\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n"],"mappings":";;;;;;;AAMA,SAAS,OAAO,OAA0D;CACxE,OAAO,oBAACA,UAAD;EAAsB,aAAU;EAAS,GAAI;CAAQ,CAAA;AAC9D;AAEA,IAAM,gBAAgB,MAAM,WAG1B,SAAS,cAAc,OAAO,KAAK;CACnC,OAAO,oBAACC,iBAAD;EAA8B;EAAK,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACnF,CAAC;AAED,IAAM,cAAc,MAAM,WAGxB,SAAS,YAAY,OAAO,KAAK;CACjC,OAAO,oBAACC,eAAD;EAA4B;EAAK,aAAU;EAAe,GAAI;CAAQ,CAAA;AAC/E,CAAC;AAED,SAAS,aAAa,OAA4D;CAChF,OAAO,oBAACC,gBAAD;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;;AAGA,IAAa,iBACX;;;;;AAMF,IAAa,sBAAsB,GACjC,mOACA,kBACA,qCACF;AAEA,IAAM,gBAAgB,MAAM,WAG1B,SAAS,cAAc,EAAE,WAAW,GAAG,SAAS,KAAK;CACrD,OACE,oBAACC,iBAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,gBAAgB,SAAS;EACvC,GAAI;CACL,CAAA;AAEL,CAAC;AAID,IAAM,qBACJ;;AAYF,IAAM,gBAAgB,MAAM,WAA+C,SAAS,cAClF,EAAE,WAAW,UAAU,kBAAkB,MAAM,SAAS,UAAU,GAAG,SACrE,KACA;CACA,MAAM,QAAQ,WAAW;CACzB,OACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,eAAD,CAAgB,CAAA,GAChB,qBAACC,iBAAD;EACO;EACL,aAAU;EACV,eAAa;EACb,WAAW,GACT,8WACA,SAAS,oBACT,SACF;EACA,GAAI;EATN,UAAA;GAWG,SACC,oBAAC,OAAD;IACE,aAAU;IACV,eAAA;IACA,WAAU;GACX,CAAA;GAEF;GACA,kBACC,qBAACH,eAAD;IAAuB,aAAU;IAAe,WAAW;IAA3D,UAAA,CACE,oBAAC,GAAD,EAAG,eAAA,KAAa,CAAA,GAChB,oBAAC,QAAD;KAAM,WAAU;KAAU,UAAA;IAAW,CAAA,CAChB;GACrB,CAAA,IAAA;EACmB;CACb,CAAA,CAAA,EAAA,CAAA;AAElB,CAAC;AAED,IAAM,eAAe,MAAM,WACzB,SAAS,aAAa,EAAE,WAAW,GAAG,SAAS,KAAK;CAClD,OACE,oBAAC,OAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,qBAAqB,SAAS;EAC5C,GAAI;CACL,CAAA;AAEL,CACF;AAEA,IAAM,eAAe,MAAM,WACzB,SAAS,aAAa,EAAE,WAAW,GAAG,SAAS,KAAK;CAClD,OACE,oBAAC,OAAD;EACO;EACL,aAAU;EACV,WAAW,GACT,sFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL,CACF;AAEA,IAAM,cAAc,MAAM,WAGxB,SAAS,YAAY,EAAE,WAAW,GAAG,SAAS,KAAK;CACnD,OACE,oBAACI,eAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,8CAA8C,SAAS;EACrE,GAAI;CACL,CAAA;AAEL,CAAC;AAED,IAAM,oBAAoB,MAAM,WAG9B,SAAS,kBAAkB,EAAE,WAAW,GAAG,SAAS,KAAK;CACzD,OACE,oBAACC,qBAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EAClE,GAAI;CACL,CAAA;AAEL,CAAC"}