@eifi1/ui-kit 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/LICENSE +32 -0
  2. package/README.md +498 -57
  3. package/dist/chart.d.ts +10 -0
  4. package/dist/chart.js +10 -0
  5. package/dist/chart.js.map +1 -0
  6. package/dist/components/account-settings.d.ts +11 -0
  7. package/dist/components/account-settings.js +19 -12
  8. package/dist/components/account-settings.js.map +1 -1
  9. package/dist/components/alert-banner.d.ts +10 -6
  10. package/dist/components/alert-banner.js +20 -16
  11. package/dist/components/alert-banner.js.map +1 -1
  12. package/dist/components/amount-input.d.ts +30 -4
  13. package/dist/components/amount-input.js +36 -14
  14. package/dist/components/amount-input.js.map +1 -1
  15. package/dist/components/calculator.d.ts +24 -7
  16. package/dist/components/calculator.js +37 -20
  17. package/dist/components/calculator.js.map +1 -1
  18. package/dist/components/chart-zoom.d.ts +156 -0
  19. package/dist/components/chart-zoom.js +262 -0
  20. package/dist/components/chart-zoom.js.map +1 -0
  21. package/dist/components/chart.d.ts +28 -3
  22. package/dist/components/chart.js +71 -32
  23. package/dist/components/chart.js.map +1 -1
  24. package/dist/components/checkbox.d.ts +51 -0
  25. package/dist/components/checkbox.js +123 -0
  26. package/dist/components/checkbox.js.map +1 -0
  27. package/dist/components/chip.d.ts +128 -0
  28. package/dist/components/chip.js +357 -0
  29. package/dist/components/chip.js.map +1 -0
  30. package/dist/components/choice-parts.d.ts +24 -0
  31. package/dist/components/choice-parts.js +18 -0
  32. package/dist/components/choice-parts.js.map +1 -0
  33. package/dist/components/combobox-core.d.ts +52 -9
  34. package/dist/components/combobox-core.js +89 -19
  35. package/dist/components/combobox-core.js.map +1 -1
  36. package/dist/components/combobox.d.ts +43 -33
  37. package/dist/components/combobox.js +409 -340
  38. package/dist/components/combobox.js.map +1 -1
  39. package/dist/components/currency-select.d.ts +48 -8
  40. package/dist/components/currency-select.js +107 -65
  41. package/dist/components/currency-select.js.map +1 -1
  42. package/dist/components/data-table-filter-popover.d.ts +15 -3
  43. package/dist/components/data-table-filter-popover.js +23 -17
  44. package/dist/components/data-table-filter-popover.js.map +1 -1
  45. package/dist/components/data-table-filters.d.ts +1 -1
  46. package/dist/components/data-table-filters.js +3 -2
  47. package/dist/components/data-table-filters.js.map +1 -1
  48. package/dist/components/data-table-labels.d.ts +53 -2
  49. package/dist/components/data-table-labels.js +31 -2
  50. package/dist/components/data-table-labels.js.map +1 -1
  51. package/dist/components/data-table-pagination.d.ts +3 -1
  52. package/dist/components/data-table-pagination.js +16 -10
  53. package/dist/components/data-table-pagination.js.map +1 -1
  54. package/dist/components/data-table-sort.js +1 -0
  55. package/dist/components/data-table-sort.js.map +1 -1
  56. package/dist/components/data-table.d.ts +1 -1
  57. package/dist/components/data-table.js +201 -85
  58. package/dist/components/data-table.js.map +1 -1
  59. package/dist/components/date-picker.d.ts +25 -9
  60. package/dist/components/date-picker.js +232 -94
  61. package/dist/components/date-picker.js.map +1 -1
  62. package/dist/components/dropdown.d.ts +74 -19
  63. package/dist/components/dropdown.js +72 -22
  64. package/dist/components/dropdown.js.map +1 -1
  65. package/dist/components/entity-combobox.d.ts +5 -4
  66. package/dist/components/entity-combobox.js +107 -76
  67. package/dist/components/entity-combobox.js.map +1 -1
  68. package/dist/components/facing-pair.d.ts +36 -0
  69. package/dist/components/facing-pair.js +40 -0
  70. package/dist/components/facing-pair.js.map +1 -0
  71. package/dist/components/field-sync.d.ts +164 -0
  72. package/dist/components/field-sync.js +264 -0
  73. package/dist/components/field-sync.js.map +1 -0
  74. package/dist/components/file-dropzone.d.ts +21 -7
  75. package/dist/components/file-dropzone.js +28 -7
  76. package/dist/components/file-dropzone.js.map +1 -1
  77. package/dist/components/full-bleed-dialog.d.ts +37 -26
  78. package/dist/components/full-bleed-dialog.js +20 -5
  79. package/dist/components/full-bleed-dialog.js.map +1 -1
  80. package/dist/components/grouped-picker.d.ts +21 -10
  81. package/dist/components/grouped-picker.js +66 -52
  82. package/dist/components/grouped-picker.js.map +1 -1
  83. package/dist/components/hover-menu.d.ts +20 -4
  84. package/dist/components/hover-menu.js +15 -4
  85. package/dist/components/hover-menu.js.map +1 -1
  86. package/dist/components/mini-calendar.d.ts +102 -14
  87. package/dist/components/mini-calendar.js +256 -70
  88. package/dist/components/mini-calendar.js.map +1 -1
  89. package/dist/components/modal.d.ts +9 -3
  90. package/dist/components/modal.js +34 -45
  91. package/dist/components/modal.js.map +1 -1
  92. package/dist/components/month-picker.d.ts +79 -0
  93. package/dist/components/month-picker.js +342 -0
  94. package/dist/components/month-picker.js.map +1 -0
  95. package/dist/components/multi-entity-combobox.d.ts +7 -6
  96. package/dist/components/multi-entity-combobox.js +112 -72
  97. package/dist/components/multi-entity-combobox.js.map +1 -1
  98. package/dist/components/multi-select.d.ts +13 -11
  99. package/dist/components/multi-select.js +161 -84
  100. package/dist/components/multi-select.js.map +1 -1
  101. package/dist/components/number-field.d.ts +92 -0
  102. package/dist/components/number-field.js +111 -0
  103. package/dist/components/number-field.js.map +1 -0
  104. package/dist/components/number-input.d.ts +21 -2
  105. package/dist/components/number-input.js +2 -1
  106. package/dist/components/number-input.js.map +1 -1
  107. package/dist/components/numpad-sheet.d.ts +25 -4
  108. package/dist/components/numpad-sheet.js +30 -13
  109. package/dist/components/numpad-sheet.js.map +1 -1
  110. package/dist/components/page-contents.d.ts +90 -0
  111. package/dist/components/page-contents.js +170 -0
  112. package/dist/components/page-contents.js.map +1 -0
  113. package/dist/components/password-strength.d.ts +106 -0
  114. package/dist/components/password-strength.js +132 -0
  115. package/dist/components/password-strength.js.map +1 -0
  116. package/dist/components/picker-sheet.d.ts +23 -15
  117. package/dist/components/picker-sheet.js +34 -14
  118. package/dist/components/picker-sheet.js.map +1 -1
  119. package/dist/components/popover.d.ts +62 -4
  120. package/dist/components/popover.js +52 -2
  121. package/dist/components/popover.js.map +1 -1
  122. package/dist/components/search-field.d.ts +25 -7
  123. package/dist/components/search-field.js +7 -5
  124. package/dist/components/search-field.js.map +1 -1
  125. package/dist/components/series-chart-labels.d.ts +14 -0
  126. package/dist/components/series-chart-labels.js +11 -0
  127. package/dist/components/series-chart-labels.js.map +1 -0
  128. package/dist/components/series-chart.d.ts +207 -0
  129. package/dist/components/series-chart.js +223 -0
  130. package/dist/components/series-chart.js.map +1 -0
  131. package/dist/components/settings-fields.d.ts +14 -4
  132. package/dist/components/settings-fields.js +19 -8
  133. package/dist/components/settings-fields.js.map +1 -1
  134. package/dist/components/signature-pad.d.ts +119 -0
  135. package/dist/components/signature-pad.js +405 -0
  136. package/dist/components/signature-pad.js.map +1 -0
  137. package/dist/components/slider.d.ts +80 -0
  138. package/dist/components/slider.js +155 -0
  139. package/dist/components/slider.js.map +1 -0
  140. package/dist/components/sparkline.d.ts +93 -0
  141. package/dist/components/sparkline.js +205 -0
  142. package/dist/components/sparkline.js.map +1 -0
  143. package/dist/components/stat-tile.d.ts +151 -0
  144. package/dist/components/stat-tile.js +236 -0
  145. package/dist/components/stat-tile.js.map +1 -0
  146. package/dist/components/swipeable-row.d.ts +25 -2
  147. package/dist/components/swipeable-row.js +31 -0
  148. package/dist/components/swipeable-row.js.map +1 -1
  149. package/dist/components/switch.d.ts +60 -0
  150. package/dist/components/switch.js +81 -0
  151. package/dist/components/switch.js.map +1 -0
  152. package/dist/components/time-input.d.ts +58 -0
  153. package/dist/components/time-input.js +50 -0
  154. package/dist/components/time-input.js.map +1 -0
  155. package/dist/components/toggle-group.d.ts +18 -3
  156. package/dist/components/toggle-group.js +10 -6
  157. package/dist/components/toggle-group.js.map +1 -1
  158. package/dist/components/toggle-legend.d.ts +115 -0
  159. package/dist/components/toggle-legend.js +114 -0
  160. package/dist/components/toggle-legend.js.map +1 -0
  161. package/dist/components/tooltip.d.ts +40 -11
  162. package/dist/components/tooltip.js +77 -20
  163. package/dist/components/tooltip.js.map +1 -1
  164. package/dist/components/treemap.d.ts +132 -0
  165. package/dist/components/treemap.js +179 -0
  166. package/dist/components/treemap.js.map +1 -0
  167. package/dist/components/ui.d.ts +159 -46
  168. package/dist/components/ui.js +220 -115
  169. package/dist/components/ui.js.map +1 -1
  170. package/dist/components/use-mobile-reveal.js +1 -0
  171. package/dist/components/use-mobile-reveal.js.map +1 -1
  172. package/dist/components/use-table-state.d.ts +1 -1
  173. package/dist/components/use-table-state.js +38 -17
  174. package/dist/components/use-table-state.js.map +1 -1
  175. package/dist/components/user-avatar.d.ts +5 -3
  176. package/dist/components/user-avatar.js +4 -2
  177. package/dist/components/user-avatar.js.map +1 -1
  178. package/dist/components/wizard-stepper.js +3 -2
  179. package/dist/components/wizard-stepper.js.map +1 -1
  180. package/dist/{data-table-filters-aXyf0Xub.d.ts → data-table-filters-DM1auUfH.d.ts} +27 -5
  181. package/dist/data-table.d.ts +7 -0
  182. package/dist/data-table.js +12 -0
  183. package/dist/data-table.js.map +1 -0
  184. package/dist/feedback/feedback-attachment.js +12 -11
  185. package/dist/feedback/feedback-attachment.js.map +1 -1
  186. package/dist/feedback/feedback-dialog.js +2 -1
  187. package/dist/feedback/feedback-dialog.js.map +1 -1
  188. package/dist/feedback/feedback-inbox.d.ts +33 -7
  189. package/dist/feedback/feedback-inbox.js +49 -37
  190. package/dist/feedback/feedback-inbox.js.map +1 -1
  191. package/dist/feedback.d.ts +5 -0
  192. package/dist/feedback.js +5 -0
  193. package/dist/feedback.js.map +1 -0
  194. package/dist/hooks/use-anchored-panel.js +1 -0
  195. package/dist/hooks/use-anchored-panel.js.map +1 -1
  196. package/dist/hooks/use-anchored-rect.js +1 -0
  197. package/dist/hooks/use-anchored-rect.js.map +1 -1
  198. package/dist/hooks/use-announce.d.ts +46 -0
  199. package/dist/hooks/use-announce.js +37 -0
  200. package/dist/hooks/use-announce.js.map +1 -0
  201. package/dist/hooks/use-body-scroll-lock.js +1 -0
  202. package/dist/hooks/use-body-scroll-lock.js.map +1 -1
  203. package/dist/hooks/use-close-transition.js +1 -0
  204. package/dist/hooks/use-close-transition.js.map +1 -1
  205. package/dist/hooks/use-dismiss.js +1 -0
  206. package/dist/hooks/use-dismiss.js.map +1 -1
  207. package/dist/hooks/use-focus-trap.d.ts +16 -0
  208. package/dist/hooks/use-focus-trap.js +67 -0
  209. package/dist/hooks/use-focus-trap.js.map +1 -0
  210. package/dist/hooks/use-media-query.js +1 -0
  211. package/dist/hooks/use-media-query.js.map +1 -1
  212. package/dist/hooks/use-overlay-history.js +27 -1
  213. package/dist/hooks/use-overlay-history.js.map +1 -1
  214. package/dist/hooks/use-row-swipe.js +1 -0
  215. package/dist/hooks/use-row-swipe.js.map +1 -1
  216. package/dist/i18n/defaults.d.ts +31 -0
  217. package/dist/i18n/defaults.js +63 -0
  218. package/dist/i18n/defaults.js.map +1 -0
  219. package/dist/i18n/kit-labels.d.ts +250 -0
  220. package/dist/i18n/kit-labels.js +184 -0
  221. package/dist/i18n/kit-labels.js.map +1 -0
  222. package/dist/index.d.ts +47 -22
  223. package/dist/index.js +28 -0
  224. package/dist/index.js.map +1 -1
  225. package/dist/lib/calc.js +1 -0
  226. package/dist/lib/calc.js.map +1 -1
  227. package/dist/lib/cn.js +1 -0
  228. package/dist/lib/cn.js.map +1 -1
  229. package/dist/lib/dates.js +1 -0
  230. package/dist/lib/dates.js.map +1 -1
  231. package/dist/lib/logger.js +1 -0
  232. package/dist/lib/logger.js.map +1 -1
  233. package/dist/lib/safe-storage.js +1 -0
  234. package/dist/lib/safe-storage.js.map +1 -1
  235. package/dist/search/command-palette.d.ts +11 -1
  236. package/dist/search/command-palette.js +21 -15
  237. package/dist/search/command-palette.js.map +1 -1
  238. package/dist/search.d.ts +2 -0
  239. package/dist/search.js +3 -0
  240. package/dist/search.js.map +1 -0
  241. package/dist/shell/app-shell.d.ts +33 -4
  242. package/dist/shell/app-shell.js +275 -78
  243. package/dist/shell/app-shell.js.map +1 -1
  244. package/dist/shell/option-switcher-menu.js +3 -2
  245. package/dist/shell/option-switcher-menu.js.map +1 -1
  246. package/dist/shell/role-switcher.d.ts +6 -0
  247. package/dist/shell/role-switcher.js +7 -4
  248. package/dist/shell/role-switcher.js.map +1 -1
  249. package/dist/shell/top-bar.d.ts +15 -7
  250. package/dist/shell/top-bar.js +3 -5
  251. package/dist/shell/top-bar.js.map +1 -1
  252. package/dist/shell/topbar-action-menu.js +3 -2
  253. package/dist/shell/topbar-action-menu.js.map +1 -1
  254. package/dist/shell/topbar-controls.d.ts +5 -2
  255. package/dist/shell/topbar-controls.js +20 -15
  256. package/dist/shell/topbar-controls.js.map +1 -1
  257. package/dist/shell.d.ts +13 -0
  258. package/dist/shell.js +8 -0
  259. package/dist/shell.js.map +1 -0
  260. package/dist/theme/chart-palette.d.ts +19 -12
  261. package/dist/theme/chart-palette.js +24 -30
  262. package/dist/theme/chart-palette.js.map +1 -1
  263. package/dist/theme/color.d.ts +78 -0
  264. package/dist/theme/color.js +148 -0
  265. package/dist/theme/color.js.map +1 -0
  266. package/dist/theme/palette-derive.d.ts +140 -0
  267. package/dist/theme/palette-derive.js +376 -0
  268. package/dist/theme/palette-derive.js.map +1 -0
  269. package/dist/theme/palette-presets.d.ts +14 -1
  270. package/dist/theme/palette-presets.js +231 -3
  271. package/dist/theme/palette-presets.js.map +1 -1
  272. package/dist/theme/palette-store.js +1 -0
  273. package/dist/theme/palette-store.js.map +1 -1
  274. package/dist/theme/theme-store.js +1 -0
  275. package/dist/theme/theme-store.js.map +1 -1
  276. package/dist/tour/tour.d.ts +2 -1
  277. package/dist/tour/tour.js +15 -9
  278. package/dist/tour/tour.js.map +1 -1
  279. package/dist/tour.d.ts +2 -0
  280. package/dist/tour.js +3 -0
  281. package/dist/tour.js.map +1 -0
  282. package/dist/wizard/stepper-nav.js +10 -8
  283. package/dist/wizard/stepper-nav.js.map +1 -1
  284. package/dist/wizard/types.d.ts +18 -2
  285. package/dist/wizard/types.js +4 -1
  286. package/dist/wizard/types.js.map +1 -1
  287. package/dist/wizard/use-wizard.js +12 -4
  288. package/dist/wizard/use-wizard.js.map +1 -1
  289. package/dist/wizard/validation.js +1 -0
  290. package/dist/wizard/validation.js.map +1 -1
  291. package/dist/wizard/wizard-context.js +1 -0
  292. package/dist/wizard/wizard-context.js.map +1 -1
  293. package/dist/wizard/wizard-step.js +1 -0
  294. package/dist/wizard/wizard-step.js.map +1 -1
  295. package/dist/wizard/wizard-summary.js +5 -3
  296. package/dist/wizard/wizard-summary.js.map +1 -1
  297. package/dist/wizard.d.ts +8 -0
  298. package/dist/wizard.js +9 -0
  299. package/dist/wizard.js.map +1 -0
  300. package/package.json +66 -13
  301. package/src/chart.ts +22 -0
  302. package/src/components/account-settings.tsx +275 -0
  303. package/src/components/alert-banner.tsx +75 -0
  304. package/src/components/amount-input.tsx +471 -0
  305. package/src/components/calculator.tsx +252 -0
  306. package/src/components/chart-zoom.tsx +499 -0
  307. package/src/components/chart.tsx +363 -0
  308. package/src/components/checkbox.tsx +222 -0
  309. package/src/components/chip.tsx +570 -0
  310. package/src/components/choice-parts.ts +33 -0
  311. package/src/components/combobox-core.tsx +540 -0
  312. package/src/components/combobox.tsx +1026 -0
  313. package/src/components/currency-select.tsx +269 -0
  314. package/src/components/data-table-filter-popover.tsx +252 -0
  315. package/src/components/data-table-filters.ts +176 -0
  316. package/src/components/data-table-labels.ts +190 -0
  317. package/src/components/data-table-pagination.tsx +126 -0
  318. package/src/components/data-table-sort.ts +70 -0
  319. package/src/components/data-table.tsx +1740 -0
  320. package/src/components/date-picker.tsx +631 -0
  321. package/src/components/dropdown.tsx +341 -0
  322. package/src/components/entity-combobox.tsx +215 -0
  323. package/src/components/facing-pair.ts +86 -0
  324. package/src/components/field-sync.tsx +472 -0
  325. package/src/components/file-dropzone.tsx +181 -0
  326. package/src/components/full-bleed-dialog.tsx +179 -0
  327. package/src/components/grouped-picker.tsx +157 -0
  328. package/src/components/hover-menu.tsx +183 -0
  329. package/src/components/mini-calendar.tsx +554 -0
  330. package/src/components/modal.tsx +287 -0
  331. package/src/components/month-picker.tsx +549 -0
  332. package/src/components/multi-entity-combobox.tsx +226 -0
  333. package/src/components/multi-select.tsx +303 -0
  334. package/src/components/number-field.tsx +225 -0
  335. package/src/components/number-input.tsx +211 -0
  336. package/src/components/numpad-sheet.tsx +264 -0
  337. package/src/components/page-contents.tsx +289 -0
  338. package/src/components/password-strength.tsx +258 -0
  339. package/src/components/picker-sheet.tsx +251 -0
  340. package/src/components/popover.tsx +195 -0
  341. package/src/components/search-field.tsx +146 -0
  342. package/src/components/series-chart-labels.ts +26 -0
  343. package/src/components/series-chart.tsx +481 -0
  344. package/src/components/settings-fields.tsx +68 -0
  345. package/src/components/signature-pad.tsx +630 -0
  346. package/src/components/slider.tsx +313 -0
  347. package/src/components/sparkline.tsx +329 -0
  348. package/src/components/stat-tile.tsx +448 -0
  349. package/src/components/swipeable-row.tsx +271 -0
  350. package/src/components/switch.tsx +170 -0
  351. package/src/components/time-input.tsx +107 -0
  352. package/src/components/toggle-group.tsx +153 -0
  353. package/src/components/toggle-legend.tsx +229 -0
  354. package/src/components/tooltip.tsx +477 -0
  355. package/src/components/treemap.tsx +390 -0
  356. package/src/components/ui.tsx +1284 -0
  357. package/src/components/use-mobile-reveal.ts +54 -0
  358. package/src/components/use-table-state.ts +295 -0
  359. package/src/components/user-avatar.tsx +61 -0
  360. package/src/components/wizard-stepper.tsx +37 -0
  361. package/src/data-table.ts +19 -0
  362. package/src/feedback/feedback-attachment.tsx +246 -0
  363. package/src/feedback/feedback-dialog.tsx +209 -0
  364. package/src/feedback/feedback-inbox.tsx +615 -0
  365. package/src/feedback.ts +8 -0
  366. package/src/hooks/use-anchored-panel.ts +169 -0
  367. package/src/hooks/use-anchored-rect.ts +78 -0
  368. package/src/hooks/use-announce.ts +85 -0
  369. package/src/hooks/use-body-scroll-lock.ts +94 -0
  370. package/src/hooks/use-close-transition.ts +99 -0
  371. package/src/hooks/use-dismiss.ts +77 -0
  372. package/src/hooks/use-focus-trap.ts +160 -0
  373. package/src/hooks/use-media-query.ts +23 -0
  374. package/src/hooks/use-overlay-history.ts +345 -0
  375. package/src/hooks/use-row-swipe.ts +212 -0
  376. package/src/i18n/defaults.ts +68 -0
  377. package/src/i18n/kit-labels.tsx +447 -0
  378. package/src/index.ts +169 -0
  379. package/src/lib/calc.ts +309 -0
  380. package/src/lib/cn.ts +5 -0
  381. package/src/lib/dates.ts +187 -0
  382. package/src/lib/logger.ts +73 -0
  383. package/src/lib/safe-storage.ts +37 -0
  384. package/src/search/command-palette.tsx +342 -0
  385. package/src/search.ts +3 -0
  386. package/src/shell/app-shell.tsx +772 -0
  387. package/src/shell/option-switcher-menu.tsx +72 -0
  388. package/src/shell/role-switcher.tsx +46 -0
  389. package/src/shell/top-bar.tsx +39 -0
  390. package/src/shell/topbar-action-menu.tsx +91 -0
  391. package/src/shell/topbar-controls.tsx +229 -0
  392. package/src/shell.ts +10 -0
  393. package/src/theme/chart-palette.ts +145 -0
  394. package/src/theme/color.ts +266 -0
  395. package/src/theme/palette-derive.ts +681 -0
  396. package/src/theme/palette-presets.ts +760 -0
  397. package/src/theme/palette-store.ts +94 -0
  398. package/src/theme/theme-store.ts +145 -0
  399. package/src/tour/tour.tsx +586 -0
  400. package/src/tour.ts +3 -0
  401. package/src/vite-env.d.ts +26 -0
  402. package/src/wizard/stepper-nav.tsx +221 -0
  403. package/src/wizard/types.ts +178 -0
  404. package/src/wizard/use-wizard.ts +345 -0
  405. package/src/wizard/validation.ts +37 -0
  406. package/src/wizard/wizard-context.tsx +29 -0
  407. package/src/wizard/wizard-step.tsx +14 -0
  408. package/src/wizard/wizard-summary.tsx +69 -0
  409. package/src/wizard.ts +14 -0
  410. package/tokens.css +222 -20
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { Fragment as Fragment2, useMemo, useRef, useState } from "react";
3
+ import { Fragment as Fragment2, useEffect, useMemo, useRef, useState } from "react";
3
4
  import { createPortal } from "react-dom";
4
5
  import {
5
6
  ArrowDown,
@@ -29,7 +30,9 @@ import { useOverlayHistory } from "../hooks/use-overlay-history.js";
29
30
  import { FullBleedDialog } from "./full-bleed-dialog.js";
30
31
  import { Popover } from "./popover.js";
31
32
  import { useMediaQuery } from "../hooks/use-media-query.js";
33
+ import { useAnnounce } from "../hooks/use-announce.js";
32
34
  import { resolveDataTableLabels } from "./data-table-labels.js";
35
+ import { useKitLabelOverrides, useKitLocale } from "../i18n/kit-labels.js";
33
36
  import { Tooltip } from "./tooltip.js";
34
37
  function cleanAttrs(attrs) {
35
38
  if (!attrs) return void 0;
@@ -37,6 +40,9 @@ function cleanAttrs(attrs) {
37
40
  for (const [k, v] of Object.entries(attrs)) if (v !== void 0) out[k] = v;
38
41
  return out;
39
42
  }
43
+ function columnLabel(col) {
44
+ return typeof col.header === "string" ? col.header : col.key;
45
+ }
40
46
  const isPlainLeftClick = (e) => e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;
41
47
  function RowLink({
42
48
  href,
@@ -92,7 +98,7 @@ function DataTable({
92
98
  onSortsChange,
93
99
  selection,
94
100
  labels: labelsProp,
95
- locale,
101
+ locale: localeProp,
96
102
  storageKeyPrefix = DEFAULT_PERSIST_PREFIX,
97
103
  mobileExpandAsDialog = false,
98
104
  mobileGroupBy,
@@ -102,8 +108,20 @@ function DataTable({
102
108
  leadingRow
103
109
  }) {
104
110
  const isServer = !!serverPagination;
105
- const labels = resolveDataTableLabels(labelsProp);
111
+ const labelOverrides = useKitLabelOverrides("dataTable");
112
+ const labels = useMemo(
113
+ () => resolveDataTableLabels(
114
+ labelOverrides || labelsProp ? {
115
+ ...labelOverrides,
116
+ ...labelsProp,
117
+ presets: { ...labelOverrides?.presets, ...labelsProp?.presets }
118
+ } : void 0
119
+ ),
120
+ [labelOverrides, labelsProp]
121
+ );
122
+ const locale = useKitLocale(localeProp);
106
123
  const [, setSearchParams] = useSearchParams();
124
+ const { announce, regionProps } = useAnnounce();
107
125
  const {
108
126
  sorts,
109
127
  filters,
@@ -130,6 +148,12 @@ function DataTable({
130
148
  sortsProp,
131
149
  filtersProp
132
150
  });
151
+ const columnSig = columns.map((c) => c.key).join("\0");
152
+ const selectOptionsSig = columns.map((c) => {
153
+ const f = resolveFilter(c);
154
+ if (!f || f.type !== "select" || !f.options) return "";
155
+ return `${c.key}:${f.options.map((o) => `${o.value}=${o.label ?? ""}`).join(",")}`;
156
+ }).join("\0");
133
157
  const selectOptionsByKey = useMemo(() => {
134
158
  const map = {};
135
159
  for (const col of columns) {
@@ -147,17 +171,17 @@ function DataTable({
147
171
  map[col.key] = Array.from(seen).sort().map((v) => ({ value: v, label: v }));
148
172
  }
149
173
  return map;
150
- }, [columns, rows]);
174
+ }, [columnSig, selectOptionsSig, rows]);
151
175
  const filtered = useMemo(() => {
152
176
  if (isServer) return rows;
153
177
  let result = rows;
154
178
  for (const col of columns) {
155
179
  const state = filters[col.key];
156
180
  if (!state || !isFilterActive(state)) continue;
157
- result = result.filter((row) => rowMatches(col, row, state));
181
+ result = result.filter((row) => rowMatches(col, row, state, locale));
158
182
  }
159
183
  return result;
160
- }, [rows, columns, filters, isServer]);
184
+ }, [rows, columnSig, filters, isServer, locale]);
161
185
  const sorted = useMemo(() => {
162
186
  if (isServer) return filtered;
163
187
  const chain = sorts.map((s) => {
@@ -179,7 +203,7 @@ function DataTable({
179
203
  return 0;
180
204
  });
181
205
  return copy;
182
- }, [filtered, sorts, columns, isServer]);
206
+ }, [filtered, sorts, columnSig, isServer]);
183
207
  const unpaged = !isServer && !paginated;
184
208
  const effectivePageSize = isServer ? serverPagination.pageSize : unpaged || pageSize === Infinity ? sorted.length || 1 : pageSize;
185
209
  const paginationTotal = isServer ? serverPagination.total : sorted.length;
@@ -191,6 +215,12 @@ function DataTable({
191
215
  const next = nextSorts(sorts, key, additive);
192
216
  if (onSortsChange) onSortsChange(next);
193
217
  else setInternalSorts(next);
218
+ const col = columns.find((c) => c.key === key);
219
+ const name = col ? columnLabel(col) : key;
220
+ const entry = next.find((s) => s.key === key);
221
+ announce(
222
+ !entry ? labels.sortCleared(name) : entry.dir === "asc" ? labels.sortedAscending(name) : labels.sortedDescending(name)
223
+ );
194
224
  };
195
225
  const setFilterValue = (key, value) => {
196
226
  if (onFiltersChange) {
@@ -230,32 +260,97 @@ function DataTable({
230
260
  });
231
261
  setPage(0);
232
262
  };
263
+ const filterKey = useMemo(() => JSON.stringify(filters), [filters]);
264
+ const announcedFilterKey = useRef(filterKey);
265
+ useEffect(() => {
266
+ if (announcedFilterKey.current === filterKey) return;
267
+ announcedFilterKey.current = filterKey;
268
+ if (isServer) return;
269
+ announce(labels.filterResults(filtered.length, rows.length));
270
+ }, [filterKey, filtered.length, rows.length, isServer, announce, labels]);
271
+ const goToPage = (p) => {
272
+ if (isServer) serverPagination.onPageChange(p);
273
+ else setPage(p);
274
+ announce(labels.pageChanged(p + 1, totalPages));
275
+ };
233
276
  const visibleColumns = useMemo(
234
277
  () => columns.filter((c) => !hiddenCols.has(c.key)),
235
278
  [columns, hiddenCols]
236
279
  );
237
280
  const linkColumn = rowHref ? visibleColumns.find((c) => c.mobilePrimary && !c.noRowLink) ?? visibleColumns.find((c) => !c.noRowLink) : void 0;
281
+ const resizing = useRef(null);
282
+ const columnCells = (key) => {
283
+ const th = headRefs.get(key);
284
+ if (!th) return [];
285
+ const table = th.closest("table");
286
+ if (!table) return [th];
287
+ return [
288
+ th,
289
+ ...Array.from(table.querySelectorAll("tbody [data-col]")).filter(
290
+ (el) => el.dataset.col === key
291
+ )
292
+ ];
293
+ };
294
+ const applyLiveWidth = (cells, width) => {
295
+ const px = width == null ? "" : `${width}px`;
296
+ for (const el of cells) {
297
+ el.style.width = px;
298
+ el.style.minWidth = px;
299
+ el.style.maxWidth = px;
300
+ }
301
+ };
302
+ const releaseResizeChrome = (handle, pointerId) => {
303
+ document.body.style.userSelect = "";
304
+ document.body.style.cursor = "";
305
+ if (handle.hasPointerCapture?.(pointerId)) handle.releasePointerCapture?.(pointerId);
306
+ };
238
307
  const startResize = (e, key) => {
308
+ if (e.button !== 0) return;
239
309
  e.preventDefault();
240
310
  e.stopPropagation();
241
311
  const th = headRefs.get(key);
242
312
  const startWidth = th?.getBoundingClientRect().width ?? 100;
243
- const startX = e.clientX;
244
- const onMove = (ev) => {
245
- const next = Math.max(40, Math.round(startWidth + (ev.clientX - startX)));
246
- setWidths((w) => ({ ...w, [key]: next }));
247
- };
248
- const onUp = () => {
249
- window.removeEventListener("mousemove", onMove);
250
- window.removeEventListener("mouseup", onUp);
251
- document.body.style.userSelect = "";
252
- document.body.style.cursor = "";
313
+ resizing.current = {
314
+ key,
315
+ pointerId: e.pointerId,
316
+ startX: e.clientX,
317
+ startWidth,
318
+ hadWidth: widths[key],
319
+ cells: columnCells(key),
320
+ width: startWidth,
321
+ moved: false
253
322
  };
323
+ e.currentTarget.setPointerCapture?.(e.pointerId);
254
324
  document.body.style.userSelect = "none";
255
325
  document.body.style.cursor = "col-resize";
256
- window.addEventListener("mousemove", onMove);
257
- window.addEventListener("mouseup", onUp);
258
326
  };
327
+ const moveResize = (e) => {
328
+ const drag = resizing.current;
329
+ if (!drag || drag.pointerId !== e.pointerId) return;
330
+ drag.width = Math.max(40, Math.round(drag.startWidth + (e.clientX - drag.startX)));
331
+ drag.moved = true;
332
+ applyLiveWidth(drag.cells, drag.width);
333
+ };
334
+ const finishResize = (e, commit) => {
335
+ const drag = resizing.current;
336
+ releaseResizeChrome(e.currentTarget, e.pointerId);
337
+ if (!drag || drag.pointerId !== e.pointerId) return;
338
+ resizing.current = null;
339
+ if (commit && drag.moved) {
340
+ setWidths((w) => ({ ...w, [drag.key]: drag.width }));
341
+ return;
342
+ }
343
+ applyLiveWidth(drag.cells, drag.hadWidth);
344
+ };
345
+ useEffect(
346
+ () => () => {
347
+ if (!resizing.current) return;
348
+ resizing.current = null;
349
+ document.body.style.userSelect = "";
350
+ document.body.style.cursor = "";
351
+ },
352
+ []
353
+ );
259
354
  const autoSizeAll = () => {
260
355
  setWidths({});
261
356
  requestAnimationFrame(() => {
@@ -272,7 +367,7 @@ function DataTable({
272
367
  const visibleCount = visibleColumns.length;
273
368
  const totalCount = columns.length;
274
369
  const totalColSpan = visibleCount + (selection ? 1 : 0);
275
- const columnsCountLabel = `${labels.columns} (${visibleCount}/${totalCount})`;
370
+ const columnsCountLabel = labels.columnsCount(visibleCount, totalCount);
276
371
  const isMdUp = useMediaQuery("(min-width: 768px)", true);
277
372
  const mobileColumns = visibleColumns.filter((c) => !c.mobileHidden);
278
373
  const mobilePrimaryCol = mobileColumns.find((c) => c.mobilePrimary) ?? mobileColumns[0] ?? null;
@@ -289,11 +384,16 @@ function DataTable({
289
384
  const canSelect = (row) => !!selection && (selection.isSelectable?.(row) ?? true);
290
385
  const selectRange = (toIndex) => {
291
386
  if (!selection || selectionAnchor.current === null) return false;
292
- const [lo, hi] = [selectionAnchor.current, toIndex].sort((a, b) => a - b);
387
+ const fromIndex = slice.findIndex((r) => rowKey(r) === selectionAnchor.current);
388
+ if (fromIndex < 0) return false;
389
+ const [lo, hi] = [fromIndex, toIndex].sort((a, b) => a - b);
390
+ const range = [];
293
391
  for (let i = lo; i <= hi; i++) {
294
392
  const r = slice[i];
295
- if (r && canSelect(r)) selection.onToggle(r, true);
393
+ if (r && canSelect(r)) range.push(r);
296
394
  }
395
+ if (selection.onToggleMany) selection.onToggleMany(range, true);
396
+ else for (const r of range) selection.onToggle(r, true);
297
397
  return true;
298
398
  };
299
399
  const mobileDialogRow = mobileExpandAsDialog && !isMdUp ? mobileSlice.find((r) => isExpanded?.(r)) : void 0;
@@ -320,24 +420,24 @@ function DataTable({
320
420
  // on every row of a long list, so anything larger becomes the list's personality
321
421
  // rather than feedback. `transition-transform` alone, so the existing background
322
422
  // flip stays instant.
323
- interactive && "cursor-pointer transition-transform duration-100 active:scale-[0.995] active:bg-slate-50 dark:active:bg-slate-800/40 motion-reduce:transition-none motion-reduce:active:scale-100"
423
+ interactive && "cursor-pointer transition-transform duration-100 active:scale-[0.995] active:bg-[var(--bg-active)] motion-reduce:transition-none motion-reduce:active:scale-100"
324
424
  );
325
425
  const cardInner = /* @__PURE__ */ jsxs(Fragment, { children: [
326
426
  /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col gap-2", children: mobileCard ? mobileCard(row) : /* @__PURE__ */ jsxs(Fragment, { children: [
327
427
  mobilePrimaryCol && /* @__PURE__ */ jsx("div", { className: "font-medium", children: mobilePrimaryCol.cell(row) }),
328
428
  mobileSecondaryColumns.length > 0 && /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-sm", children: mobileSecondaryColumns.map((col) => /* @__PURE__ */ jsxs(Fragment2, { children: [
329
- /* @__PURE__ */ jsx("dt", { className: "text-xs uppercase tracking-wide text-slate-500 dark:text-slate-400 self-center", children: col.header }),
330
- /* @__PURE__ */ jsx("dd", { className: "min-w-0 text-slate-700 dark:text-slate-200 self-center", children: col.cell(row) })
429
+ /* @__PURE__ */ jsx("dt", { className: "text-xs uppercase tracking-wide text-[var(--text-muted)] self-center", children: col.header }),
430
+ /* @__PURE__ */ jsx("dd", { className: "min-w-0 text-[var(--text-secondary)] self-center", children: col.cell(row) })
331
431
  ] }, col.key)) })
332
432
  ] }) }),
333
433
  opensDetail && // `aria-hidden`: the row already announces itself as a button with
334
434
  // `aria-expanded`, so the icon would only add a second, wordless stop.
335
- (mobileExpandAsDialog ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-4 shrink-0 text-slate-400" }) : /* @__PURE__ */ jsx(
435
+ (mobileExpandAsDialog ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-4 shrink-0 text-[var(--text-placeholder)]" }) : /* @__PURE__ */ jsx(
336
436
  ChevronDown,
337
437
  {
338
438
  "aria-hidden": true,
339
439
  className: cn(
340
- "size-4 shrink-0 text-slate-400 transition-transform",
440
+ "size-4 shrink-0 text-[var(--text-placeholder)] transition-transform",
341
441
  expanded && "rotate-180"
342
442
  )
343
443
  }
@@ -381,7 +481,7 @@ function DataTable({
381
481
  );
382
482
  return /* @__PURE__ */ jsxs("li", { className: cn(tint), ...cleanAttrs(rowAttributes?.(row)), children: [
383
483
  swipeEnabled ? /* @__PURE__ */ jsx(SwipeableRow, { enabled: true, left: swipe.left, right: swipe.right, children: body }) : body,
384
- expansion && !mobileExpandAsDialog && /* @__PURE__ */ jsx("div", { className: "px-4 py-3 bg-slate-50/60 dark:bg-slate-800/20 border-t border-slate-100 dark:border-slate-800", children: expansion })
484
+ expansion && !mobileExpandAsDialog && /* @__PURE__ */ jsx("div", { className: "px-4 py-3 bg-[var(--bg-surface-2)] border-t border-[var(--border)]", children: expansion })
385
485
  ] }, rowKey(row));
386
486
  };
387
487
  const mobileGroups = mobileGroupBy ? mobileSlice.reduce((acc, row) => {
@@ -392,6 +492,7 @@ function DataTable({
392
492
  return acc;
393
493
  }, []) : null;
394
494
  return /* @__PURE__ */ jsxs(Card, { flush: true, className: cn("overflow-clip", fillHeight && "md:flex md:flex-1 md:flex-col md:min-h-0"), children: [
495
+ /* @__PURE__ */ jsx("span", { ...regionProps }),
395
496
  !isMdUp && /* @__PURE__ */ jsxs("div", { children: [
396
497
  (!isServer || onFiltersChange) && /* @__PURE__ */ jsx(
397
498
  MobileFilters,
@@ -408,17 +509,17 @@ function DataTable({
408
509
  locale
409
510
  }
410
511
  ),
411
- /* @__PURE__ */ jsxs("ul", { className: "divide-y divide-slate-100 dark:divide-slate-800", children: [
512
+ /* @__PURE__ */ jsxs("ul", { className: "divide-y divide-[var(--border)]", children: [
412
513
  mobileGroups ? mobileGroups.map((g) => /* @__PURE__ */ jsxs(Fragment2, { children: [
413
- /* @__PURE__ */ jsx("li", { className: "sticky top-0 z-10 bg-slate-50/95 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-slate-500 backdrop-blur dark:bg-slate-800/80 dark:text-slate-400", children: mobileGroupLabel ? mobileGroupLabel(g.key) : g.key }),
514
+ /* @__PURE__ */ jsx("li", { className: "sticky top-0 z-10 bg-[var(--bg-surface-2)] px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-[var(--text-muted)] backdrop-blur", children: mobileGroupLabel ? mobileGroupLabel(g.key) : g.key }),
414
515
  g.rows.map(renderMobileRow)
415
516
  ] }, `hb-group:${g.key}`)) : mobileSlice.map(renderMobileRow),
416
- mobileSlice.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-4 py-6 text-center text-sm text-slate-500 dark:text-slate-400", children: empty ?? "\u2014" }),
517
+ mobileSlice.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-4 py-6 text-center text-sm text-[var(--text-muted)]", children: empty ?? "\u2014" }),
417
518
  canRevealMoreMobile && /* @__PURE__ */ jsx(
418
519
  "li",
419
520
  {
420
521
  ref: loadMoreRef,
421
- className: "px-4 py-4 text-center text-xs text-slate-400 dark:text-slate-500",
522
+ className: "px-4 py-4 text-center text-xs text-[var(--text-placeholder)]",
422
523
  children: labels.loading
423
524
  }
424
525
  )
@@ -430,9 +531,10 @@ function DataTable({
430
531
  totalPages,
431
532
  pageSize: paginationPageSize,
432
533
  total: paginationTotal,
433
- onPage: serverPagination.onPageChange,
534
+ onPage: goToPage,
434
535
  onPageSize: (n) => serverPagination.onPageSizeChange?.(n),
435
- labels
536
+ labels,
537
+ locale
436
538
  }
437
539
  ),
438
540
  /* @__PURE__ */ jsx(
@@ -453,21 +555,28 @@ function DataTable({
453
555
  {
454
556
  className: cn("overflow-auto [scrollbar-gutter:stable]", fillHeight && "flex-1 min-h-0"),
455
557
  style: fillHeight ? void 0 : { maxHeight: maxBodyHeight },
456
- children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
457
- /* @__PURE__ */ jsx("thead", { className: "bg-slate-50 dark:bg-slate-800/40 text-slate-600 dark:text-slate-400", children: /* @__PURE__ */ jsxs("tr", { className: "text-left", children: [
458
- selection && /* @__PURE__ */ jsx("th", { className: "sticky top-0 z-10 w-10 bg-slate-50 px-3 py-2 align-middle dark:bg-slate-800/95 backdrop-blur-sm", children: /* @__PURE__ */ jsx(
459
- "input",
558
+ children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", "aria-label": labels.table, children: [
559
+ /* @__PURE__ */ jsx("thead", { className: "bg-[var(--bg-surface-2)] text-[var(--text-secondary)]", children: /* @__PURE__ */ jsxs("tr", { className: "text-left", children: [
560
+ selection && /* @__PURE__ */ jsx(
561
+ "th",
460
562
  {
461
- type: "checkbox",
462
- className: "size-4 align-middle accent-indigo-600",
463
- checked: selection.allSelected,
464
- ref: (el) => {
465
- if (el) el.indeterminate = selection.someSelected && !selection.allSelected;
466
- },
467
- onChange: (e) => selection.onToggleAll(e.target.checked),
468
- "aria-label": labels.selectAllRows
563
+ scope: "col",
564
+ className: "sticky top-0 z-10 w-10 bg-[var(--bg-surface-2)] px-3 py-2 align-middle backdrop-blur-sm",
565
+ children: /* @__PURE__ */ jsx(
566
+ "input",
567
+ {
568
+ type: "checkbox",
569
+ className: "size-4 align-middle accent-indigo-600",
570
+ checked: selection.allSelected,
571
+ ref: (el) => {
572
+ if (el) el.indeterminate = selection.someSelected && !selection.allSelected;
573
+ },
574
+ onChange: (e) => selection.onToggleAll(e.target.checked),
575
+ "aria-label": labels.selectAllRows
576
+ }
577
+ )
469
578
  }
470
- ) }),
579
+ ),
471
580
  visibleColumns.map((col) => {
472
581
  const sortable = (!isServer || !!onSortsChange) && !!col.sortBy;
473
582
  const filter = !isServer || onFiltersChange ? resolveFilter(col) : null;
@@ -485,14 +594,15 @@ function DataTable({
485
594
  if (el) headRefs.set(col.key, el);
486
595
  else headRefs.delete(col.key);
487
596
  },
488
- "aria-sort": sortIdx === 0 ? sorts[0].dir === "asc" ? "ascending" : "descending" : void 0,
597
+ scope: "col",
598
+ "aria-sort": sortable ? sortIdx === 0 ? sorts[0].dir === "asc" ? "ascending" : "descending" : "none" : void 0,
489
599
  style: width ? { width, minWidth: width, maxWidth: width } : void 0,
490
600
  className: cn(
491
601
  "relative px-3 py-2 font-medium align-middle whitespace-nowrap",
492
602
  // Keep the header visible while the user scrolls the page.
493
603
  // Each <th> carries its own bg so the row doesn't render
494
604
  // transparent over the data rows underneath.
495
- "sticky top-0 z-10 bg-slate-50 dark:bg-slate-800/95 backdrop-blur-sm",
605
+ "sticky top-0 z-10 bg-[var(--bg-surface-2)] backdrop-blur-sm",
496
606
  col.headClassName
497
607
  ),
498
608
  children: [
@@ -512,7 +622,7 @@ function DataTable({
512
622
  disabled: !sortable,
513
623
  className: cn(
514
624
  "flex items-center gap-1 text-left",
515
- sortable && "hover:text-slate-900 dark:hover:text-slate-200"
625
+ sortable && "hover:text-[var(--text-primary)]"
516
626
  ),
517
627
  children: [
518
628
  /* @__PURE__ */ jsx("span", { children: col.header }),
@@ -525,6 +635,7 @@ function DataTable({
525
635
  Popover,
526
636
  {
527
637
  width: filter.type === "date" ? 420 : void 0,
638
+ labels: { panel: labels.filter },
528
639
  trigger: ({ toggle, ref }) => /* @__PURE__ */ jsx(
529
640
  "button",
530
641
  {
@@ -534,7 +645,7 @@ function DataTable({
534
645
  "aria-label": labels.filter,
535
646
  className: cn(
536
647
  "rounded p-1 transition-colors",
537
- filterActive ? "bg-indigo-100 text-indigo-700 dark:bg-indigo-500/20 dark:text-indigo-300" : "text-slate-400 hover:text-slate-700 hover:bg-slate-100 dark:text-slate-500 dark:hover:text-slate-200 dark:hover:bg-slate-800"
648
+ filterActive ? "bg-[var(--brand-bg)] text-[var(--brand-muted)]" : "text-[var(--text-placeholder)] hover:text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]"
538
649
  ),
539
650
  children: /* @__PURE__ */ jsx(Filter, { className: "size-3" })
540
651
  }
@@ -561,7 +672,10 @@ function DataTable({
561
672
  {
562
673
  role: "separator",
563
674
  "aria-orientation": "vertical",
564
- onMouseDown: (e) => startResize(e, col.key),
675
+ onPointerDown: (e) => startResize(e, col.key),
676
+ onPointerMove: moveResize,
677
+ onPointerUp: (e) => finishResize(e, true),
678
+ onPointerCancel: (e) => finishResize(e, false),
565
679
  onDoubleClick: (e) => {
566
680
  e.preventDefault();
567
681
  setWidths((w) => {
@@ -570,7 +684,7 @@ function DataTable({
570
684
  return next;
571
685
  });
572
686
  },
573
- className: "absolute right-0 top-0 z-10 h-full w-1.5 -translate-x-1/2 cursor-col-resize select-none hover:bg-indigo-300/60 dark:hover:bg-indigo-500/40"
687
+ className: "absolute right-0 top-0 z-10 h-full w-1.5 -translate-x-1/2 cursor-col-resize select-none touch-none hover:bg-[var(--brand-bg-hover)]"
574
688
  }
575
689
  )
576
690
  ]
@@ -580,7 +694,7 @@ function DataTable({
580
694
  })
581
695
  ] }) }),
582
696
  /* @__PURE__ */ jsxs("tbody", { children: [
583
- leadingRow && /* @__PURE__ */ jsx("tr", { className: "border-t border-slate-100 dark:border-slate-800", children: /* @__PURE__ */ jsx("td", { colSpan: totalColSpan, className: "p-0", children: leadingRow }) }),
697
+ leadingRow && /* @__PURE__ */ jsx("tr", { className: "border-t border-[var(--border)]", children: /* @__PURE__ */ jsx("td", { colSpan: totalColSpan, className: "p-0", children: leadingRow }) }),
584
698
  slice.map((row, rowIndex) => {
585
699
  const expanded = isExpanded?.(row) ?? false;
586
700
  const expansion = expanded ? expandedRow?.(row) : null;
@@ -592,8 +706,8 @@ function DataTable({
592
706
  {
593
707
  ...cleanAttrs(rowAttributes?.(row)),
594
708
  className: cn(
595
- "border-t border-slate-100 dark:border-slate-800",
596
- rowInteractive && "cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800/40",
709
+ "border-t border-[var(--border)]",
710
+ rowInteractive && "cursor-pointer hover:bg-[var(--bg-hover)]",
597
711
  rowClassName?.(row)
598
712
  ),
599
713
  onClick: rowInteractive ? (e) => {
@@ -601,12 +715,12 @@ function DataTable({
601
715
  if (e.shiftKey) {
602
716
  window.getSelection?.()?.removeAllRanges();
603
717
  if (selectRange(rowIndex)) return;
604
- selectionAnchor.current = rowIndex;
718
+ selectionAnchor.current = rowKey(row);
605
719
  selection.onToggle(row, !selection.isSelected(row));
606
720
  return;
607
721
  }
608
722
  if (e.metaKey || e.ctrlKey) {
609
- selectionAnchor.current = rowIndex;
723
+ selectionAnchor.current = rowKey(row);
610
724
  selection.onToggle(row, !selection.isSelected(row));
611
725
  return;
612
726
  }
@@ -629,7 +743,7 @@ function DataTable({
629
743
  if (e.shiftKey && selectRange(rowIndex)) e.preventDefault();
630
744
  },
631
745
  onChange: (e) => {
632
- selectionAnchor.current = rowIndex;
746
+ selectionAnchor.current = rowKey(row);
633
747
  selection.onToggle(row, e.target.checked);
634
748
  },
635
749
  "aria-label": labels.selectRow
@@ -642,6 +756,7 @@ function DataTable({
642
756
  return /* @__PURE__ */ jsx(
643
757
  "td",
644
758
  {
759
+ "data-col": col.key,
645
760
  style: width ? { width, minWidth: width, maxWidth: width } : void 0,
646
761
  className: cn("px-3 py-2 align-top", width && "overflow-hidden text-ellipsis", col.className),
647
762
  children: col === linkColumn && href ? (
@@ -657,14 +772,14 @@ function DataTable({
657
772
  ]
658
773
  }
659
774
  ),
660
- expansion && /* @__PURE__ */ jsx("tr", { className: "bg-slate-50/60 dark:bg-slate-800/20 border-t border-slate-100 dark:border-slate-800", children: /* @__PURE__ */ jsx("td", { colSpan: totalColSpan, className: "p-0", children: /* @__PURE__ */ jsx("div", { className: "w-0 min-w-full px-3 py-3", children: expansion }) }) })
775
+ expansion && /* @__PURE__ */ jsx("tr", { className: "bg-[var(--bg-surface-2)] border-t border-[var(--border)]", children: /* @__PURE__ */ jsx("td", { colSpan: totalColSpan, className: "p-0", children: /* @__PURE__ */ jsx("div", { className: "w-0 min-w-full px-3 py-3", children: expansion }) }) })
661
776
  ] }, rowKey(row));
662
777
  }),
663
778
  slice.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
664
779
  "td",
665
780
  {
666
781
  colSpan: totalColSpan,
667
- className: "px-3 py-4 text-center text-slate-500 dark:text-slate-400",
782
+ className: "px-3 py-4 text-center text-[var(--text-muted)]",
668
783
  children: empty ?? "\u2014"
669
784
  }
670
785
  ) })
@@ -679,12 +794,13 @@ function DataTable({
679
794
  totalPages,
680
795
  pageSize: paginationPageSize,
681
796
  total: paginationTotal,
682
- onPage: isServer ? serverPagination.onPageChange : setPage,
797
+ onPage: goToPage,
683
798
  onPageSize: isServer ? (n) => serverPagination.onPageSizeChange?.(n) : (n) => {
684
799
  setPageSize(n);
685
800
  setPage(0);
686
801
  },
687
- labels
802
+ labels,
803
+ locale
688
804
  }
689
805
  )
690
806
  ] }),
@@ -698,14 +814,14 @@ function DataTable({
698
814
  tabIndex: showSettings ? -1 : 0,
699
815
  className: cn(
700
816
  "group flex shrink-0 items-start justify-center overflow-hidden pt-3 transition-[width] duration-200 ease-out",
701
- "border-l border-slate-100 dark:border-slate-800",
702
- "hover:bg-slate-50 dark:hover:bg-slate-800/40",
817
+ "border-l border-[var(--border)]",
818
+ "hover:bg-[var(--bg-hover)]",
703
819
  showSettings ? "w-0 border-l-0" : "w-8 cursor-pointer"
704
820
  ),
705
821
  children: /* @__PURE__ */ jsx(
706
822
  "span",
707
823
  {
708
- className: "whitespace-nowrap text-xs font-medium tracking-wide text-slate-500 group-hover:text-slate-700 dark:text-slate-400 dark:group-hover:text-slate-200",
824
+ className: "whitespace-nowrap text-xs font-medium tracking-wide text-[var(--text-muted)] group-hover:text-[var(--text-secondary)]",
709
825
  style: { writingMode: "vertical-rl", transform: "rotate(180deg)" },
710
826
  children: columnsCountLabel
711
827
  }
@@ -719,16 +835,16 @@ function DataTable({
719
835
  "shrink-0 overflow-hidden transition-[width] duration-200 ease-out",
720
836
  showSettings ? "w-56" : "w-0"
721
837
  ),
722
- children: /* @__PURE__ */ jsxs("div", { className: "flex w-56 flex-col border-l border-slate-100 p-2 dark:border-slate-800", children: [
838
+ children: /* @__PURE__ */ jsxs("div", { className: "flex w-56 flex-col border-l border-[var(--border)] p-2", children: [
723
839
  /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between gap-1", children: [
724
- /* @__PURE__ */ jsx("div", { className: "text-xs font-medium uppercase tracking-wide text-slate-500 dark:text-slate-400", children: columnsCountLabel }),
840
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium uppercase tracking-wide text-[var(--text-muted)]", children: columnsCountLabel }),
725
841
  /* @__PURE__ */ jsx(Tooltip, { label: labels.close, portal: true, children: /* @__PURE__ */ jsx(
726
842
  "button",
727
843
  {
728
844
  type: "button",
729
845
  onClick: () => setShowSettings(false),
730
846
  "aria-label": labels.close,
731
- className: "rounded p-0.5 text-slate-400 hover:bg-slate-100 hover:text-slate-700 dark:text-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-200",
847
+ className: "rounded p-0.5 text-[var(--text-placeholder)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]",
732
848
  children: /* @__PURE__ */ jsx(X, { className: "size-4" })
733
849
  }
734
850
  ) })
@@ -738,17 +854,17 @@ function DataTable({
738
854
  {
739
855
  type: "button",
740
856
  onClick: autoSizeAll,
741
- className: "mb-2 rounded border border-slate-200 px-2 py-1 text-xs font-medium text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800",
857
+ className: "mb-2 rounded border border-[var(--border)] px-2 py-1 text-xs font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]",
742
858
  children: labels.autoSize
743
859
  }
744
860
  ),
745
861
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: columns.map((col) => {
746
862
  const checked = !hiddenCols.has(col.key);
747
- const headerLabel = typeof col.header === "string" ? col.header : col.key;
863
+ const headerLabel = columnLabel(col);
748
864
  return /* @__PURE__ */ jsxs(
749
865
  "label",
750
866
  {
751
- className: "inline-flex cursor-pointer items-center gap-1.5 rounded px-1 py-0.5 text-xs hover:bg-slate-100 dark:hover:bg-slate-800",
867
+ className: "inline-flex cursor-pointer items-center gap-1.5 rounded px-1 py-0.5 text-xs hover:bg-[var(--bg-hover)]",
752
868
  children: [
753
869
  /* @__PURE__ */ jsx(
754
870
  "input",
@@ -804,17 +920,17 @@ function MobileFilters({
804
920
  const s = filters[col.key];
805
921
  return s && isFilterActive(s);
806
922
  }).length;
807
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-slate-100 px-4 py-2 dark:border-slate-800", children: [
923
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-[var(--border)] px-4 py-2", children: [
808
924
  /* @__PURE__ */ jsxs(
809
925
  "button",
810
926
  {
811
927
  type: "button",
812
928
  onClick: () => setOpen(true),
813
- className: "inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-800",
929
+ className: "inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]",
814
930
  children: [
815
931
  /* @__PURE__ */ jsx(Filter, { className: "size-4" }),
816
932
  /* @__PURE__ */ jsx("span", { children: labels.filters }),
817
- activeCount > 0 && /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-4 items-center justify-center rounded-full bg-sky-100 px-1 text-[11px] font-semibold text-sky-700 dark:bg-sky-500/20 dark:text-sky-300", children: activeCount })
933
+ activeCount > 0 && /* @__PURE__ */ jsx("span", { className: "inline-flex min-w-4 items-center justify-center rounded-full bg-[var(--info-bg)] px-1 text-[11px] font-semibold text-[var(--info)]", children: activeCount })
818
934
  ]
819
935
  }
820
936
  ),
@@ -823,7 +939,7 @@ function MobileFilters({
823
939
  {
824
940
  type: "button",
825
941
  onClick: onClearAll,
826
- className: "text-xs text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200",
942
+ className: "text-xs text-[var(--text-muted)] hover:text-[var(--text-secondary)]",
827
943
  children: labels.clearAll
828
944
  }
829
945
  ),
@@ -835,8 +951,8 @@ function MobileFilters({
835
951
  role: "dialog",
836
952
  "aria-modal": "true",
837
953
  ...backdropClose,
838
- children: /* @__PURE__ */ jsxs("div", { className: "flex max-h-[85vh] w-full flex-col overflow-hidden rounded-t-2xl bg-white shadow-xl dark:bg-slate-900", children: [
839
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-slate-100 px-4 py-3 dark:border-slate-800", children: [
954
+ children: /* @__PURE__ */ jsxs("div", { className: "flex max-h-[85vh] w-full flex-col overflow-hidden rounded-t-2xl bg-[var(--bg-surface)] shadow-xl", children: [
955
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-[var(--border)] px-4 py-3", children: [
840
956
  /* @__PURE__ */ jsx("div", { className: "font-medium", children: labels.filters }),
841
957
  /* @__PURE__ */ jsx(
842
958
  "button",
@@ -844,12 +960,12 @@ function MobileFilters({
844
960
  type: "button",
845
961
  onClick: () => setOpen(false),
846
962
  "aria-label": labels.close,
847
- className: "-mr-1 rounded p-1.5 text-slate-500 hover:bg-slate-100 hover:text-slate-700 dark:hover:bg-slate-800 dark:hover:text-slate-200",
963
+ className: "-mr-1 rounded p-1.5 text-[var(--text-muted)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]",
848
964
  children: /* @__PURE__ */ jsx(X, { className: "size-5" })
849
965
  }
850
966
  )
851
967
  ] }),
852
- /* @__PURE__ */ jsx("div", { className: "flex-1 divide-y divide-slate-100 overflow-y-auto overscroll-contain dark:divide-slate-800", children: filterable.map(({ col, filter }) => {
968
+ /* @__PURE__ */ jsx("div", { className: "flex-1 divide-y divide-[var(--border)] overflow-y-auto overscroll-contain", children: filterable.map(({ col, filter }) => {
853
969
  const state = filters[col.key];
854
970
  const active = !!state && isFilterActive(state);
855
971
  const isItemOpen = expanded === col.key;
@@ -862,7 +978,7 @@ function MobileFilters({
862
978
  "aria-expanded": isItemOpen,
863
979
  className: "flex w-full items-center justify-between gap-2 px-4 py-3 text-left",
864
980
  children: [
865
- /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-sm font-medium text-slate-700 dark:text-slate-200", children: [
981
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-sm font-medium text-[var(--text-secondary)]", children: [
866
982
  col.header,
867
983
  active && /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-brand" })
868
984
  ] }),
@@ -870,7 +986,7 @@ function MobileFilters({
870
986
  ChevronDown,
871
987
  {
872
988
  className: cn(
873
- "size-4 shrink-0 text-slate-400 transition-transform",
989
+ "size-4 shrink-0 text-[var(--text-placeholder)] transition-transform",
874
990
  isItemOpen && "rotate-180"
875
991
  )
876
992
  }
@@ -892,14 +1008,14 @@ function MobileFilters({
892
1008
  ) })
893
1009
  ] }, col.key);
894
1010
  }) }),
895
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-slate-100 px-4 py-3 dark:border-slate-800", children: [
1011
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-[var(--border)] px-4 py-3", children: [
896
1012
  /* @__PURE__ */ jsx(
897
1013
  "button",
898
1014
  {
899
1015
  type: "button",
900
1016
  onClick: onClearAll,
901
1017
  disabled: activeCount === 0,
902
- className: "text-sm text-slate-500 hover:text-slate-700 disabled:opacity-40 dark:text-slate-400 dark:hover:text-slate-200",
1018
+ className: "text-sm text-[var(--text-muted)] hover:text-[var(--text-secondary)] disabled:opacity-40",
903
1019
  children: labels.clearAll
904
1020
  }
905
1021
  ),
@@ -908,7 +1024,7 @@ function MobileFilters({
908
1024
  {
909
1025
  type: "button",
910
1026
  onClick: () => setOpen(false),
911
- className: "rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white dark:bg-slate-100 dark:text-slate-900",
1027
+ className: "rounded-md bg-[var(--bg-inverse)] px-4 py-2 text-sm font-medium text-[var(--text-inverse)]",
912
1028
  children: labels.done
913
1029
  }
914
1030
  )