@eifi1/ui-kit 0.51.3 → 0.51.5

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 (780) hide show
  1. package/README.md +6 -6
  2. package/dist/account/account-settings-labels.js.map +1 -1
  3. package/dist/account/account-settings.js +11 -9
  4. package/dist/account/account-settings.js.map +1 -1
  5. package/dist/account/delete-account-setting.js +56 -65
  6. package/dist/account/delete-account-setting.js.map +1 -1
  7. package/dist/account/email-change-setting-labels.js.map +1 -1
  8. package/dist/account/email-change-setting.js.map +1 -1
  9. package/dist/account/passkeys-setting.js.map +1 -1
  10. package/dist/account/sessions-setting.js.map +1 -1
  11. package/dist/admin/admin-action-confirm.js +1 -3
  12. package/dist/admin/admin-action-confirm.js.map +1 -1
  13. package/dist/admin/admin-action-log.js.map +1 -1
  14. package/dist/admin/admin-area-labels.js +4 -1
  15. package/dist/admin/admin-area-labels.js.map +1 -1
  16. package/dist/admin/admin-overview.js +19 -11
  17. package/dist/admin/admin-overview.js.map +1 -1
  18. package/dist/admin/admin-sections.js.map +1 -1
  19. package/dist/admin/admin-tool-links.d.ts +1 -1
  20. package/dist/admin/admin-tool-links.js +7 -1
  21. package/dist/admin/admin-tool-links.js.map +1 -1
  22. package/dist/admin/invitations-panel.js +2 -13
  23. package/dist/admin/invitations-panel.js.map +1 -1
  24. package/dist/admin/mail-test-card.js.map +1 -1
  25. package/dist/admin/reviewer-scope-editor.js +4 -11
  26. package/dist/admin/reviewer-scope-editor.js.map +1 -1
  27. package/dist/admin/role-select.js.map +1 -1
  28. package/dist/admin/user-roster.js +1 -9
  29. package/dist/admin/user-roster.js.map +1 -1
  30. package/dist/auth/accept-invitation.js.map +1 -1
  31. package/dist/auth/auth-errors.js.map +1 -1
  32. package/dist/auth/forgot-password-form.js +23 -31
  33. package/dist/auth/forgot-password-form.js.map +1 -1
  34. package/dist/auth/register-form.js.map +1 -1
  35. package/dist/auth/reset-password-form.js.map +1 -1
  36. package/dist/auth/sign-in-form.js +13 -5
  37. package/dist/auth/sign-in-form.js.map +1 -1
  38. package/dist/auth/verify-email.js +1 -8
  39. package/dist/auth/verify-email.js.map +1 -1
  40. package/dist/billing/billing-banner.js.map +1 -1
  41. package/dist/billing/billing-labels.js.map +1 -1
  42. package/dist/billing/checkout-processing.js.map +1 -1
  43. package/dist/billing/plan-card.js +91 -85
  44. package/dist/billing/plan-card.js.map +1 -1
  45. package/dist/billing/plan-limit-toast.js.map +1 -1
  46. package/dist/billing/plan-limit.js.map +1 -1
  47. package/dist/billing/plan-price.js.map +1 -1
  48. package/dist/billing/plan-switch.js.map +1 -1
  49. package/dist/billing/subscription-actions.js.map +1 -1
  50. package/dist/bin/eifi1-pay-page.mjs +6 -1
  51. package/dist/components/account-chips.js.map +1 -1
  52. package/dist/components/alert-banner.js +1 -5
  53. package/dist/components/alert-banner.js.map +1 -1
  54. package/dist/components/amount-input.js +29 -12
  55. package/dist/components/amount-input.js.map +1 -1
  56. package/dist/components/authed-image.js.map +1 -1
  57. package/dist/components/autocomplete.js.map +1 -1
  58. package/dist/components/bulk-action-bar.js +1 -4
  59. package/dist/components/bulk-action-bar.js.map +1 -1
  60. package/dist/components/button-group.js.map +1 -1
  61. package/dist/components/button-look.js.map +1 -1
  62. package/dist/components/button.js +1 -7
  63. package/dist/components/button.js.map +1 -1
  64. package/dist/components/calculator.js +5 -5
  65. package/dist/components/calculator.js.map +1 -1
  66. package/dist/components/calendar-heatmap.js +4 -10
  67. package/dist/components/calendar-heatmap.js.map +1 -1
  68. package/dist/components/card.js +1 -8
  69. package/dist/components/card.js.map +1 -1
  70. package/dist/components/chart-zoom-core.js +3 -17
  71. package/dist/components/chart-zoom-core.js.map +1 -1
  72. package/dist/components/chart.d.ts +1 -1
  73. package/dist/components/chart.js +4 -22
  74. package/dist/components/chart.js.map +1 -1
  75. package/dist/components/checkbox-group.js +1 -4
  76. package/dist/components/checkbox-group.js.map +1 -1
  77. package/dist/components/chip-input.js +4 -1
  78. package/dist/components/chip-input.js.map +1 -1
  79. package/dist/components/chip.js +10 -5
  80. package/dist/components/chip.js.map +1 -1
  81. package/dist/components/choice-card.js +58 -74
  82. package/dist/components/choice-card.js.map +1 -1
  83. package/dist/components/column-mapper-labels.js.map +1 -1
  84. package/dist/components/column-mapper.js +167 -227
  85. package/dist/components/column-mapper.js.map +1 -1
  86. package/dist/components/combobox-core.js +5 -9
  87. package/dist/components/combobox-core.js.map +1 -1
  88. package/dist/components/combobox.js +1 -4
  89. package/dist/components/combobox.js.map +1 -1
  90. package/dist/components/confirm-dialog.js.map +1 -1
  91. package/dist/components/copy-button.js.map +1 -1
  92. package/dist/components/country-select.d.ts +5 -4
  93. package/dist/components/country-select.js +3 -19
  94. package/dist/components/country-select.js.map +1 -1
  95. package/dist/components/currency-option-list.js +13 -11
  96. package/dist/components/currency-option-list.js.map +1 -1
  97. package/dist/components/currency-select.js +1 -6
  98. package/dist/components/currency-select.js.map +1 -1
  99. package/dist/components/danger-confirm.js.map +1 -1
  100. package/dist/components/data-table-cells.js.map +1 -1
  101. package/dist/components/data-table-column-settings.js.map +1 -1
  102. package/dist/components/data-table-filter-popover.js +2 -18
  103. package/dist/components/data-table-filter-popover.js.map +1 -1
  104. package/dist/components/data-table-filters.js.map +1 -1
  105. package/dist/components/data-table-fit.js +7 -5
  106. package/dist/components/data-table-fit.js.map +1 -1
  107. package/dist/components/data-table-groups.js +3 -1
  108. package/dist/components/data-table-groups.js.map +1 -1
  109. package/dist/components/data-table-head.js +49 -57
  110. package/dist/components/data-table-head.js.map +1 -1
  111. package/dist/components/data-table-mobile.js +31 -44
  112. package/dist/components/data-table-mobile.js.map +1 -1
  113. package/dist/components/data-table-pagination.js.map +1 -1
  114. package/dist/components/data-table-row-actions.js +19 -16
  115. package/dist/components/data-table-row-actions.js.map +1 -1
  116. package/dist/components/data-table-row.js.map +1 -1
  117. package/dist/components/data-table-shared.js.map +1 -1
  118. package/dist/components/data-table-sort.js.map +1 -1
  119. package/dist/components/data-table-virtual.js +4 -1
  120. package/dist/components/data-table-virtual.js.map +1 -1
  121. package/dist/components/data-table.d.ts +8 -0
  122. package/dist/components/data-table.js +30 -39
  123. package/dist/components/data-table.js.map +1 -1
  124. package/dist/components/date-picker.js +1 -6
  125. package/dist/components/date-picker.js.map +1 -1
  126. package/dist/components/date-range-picker.js.map +1 -1
  127. package/dist/components/description-list.js +10 -10
  128. package/dist/components/description-list.js.map +1 -1
  129. package/dist/components/dialog-frame.js +9 -2
  130. package/dist/components/dialog-frame.js.map +1 -1
  131. package/dist/components/disclosure.js +17 -27
  132. package/dist/components/disclosure.js.map +1 -1
  133. package/dist/components/dropdown.js +25 -35
  134. package/dist/components/dropdown.js.map +1 -1
  135. package/dist/components/empty-state.js.map +1 -1
  136. package/dist/components/entity-combobox.js.map +1 -1
  137. package/dist/components/error-boundary.js.map +1 -1
  138. package/dist/components/field-base.js +5 -5
  139. package/dist/components/field-base.js.map +1 -1
  140. package/dist/components/field-parts.d.ts +1 -1
  141. package/dist/components/field-parts.js +10 -14
  142. package/dist/components/field-parts.js.map +1 -1
  143. package/dist/components/field-sync.js +8 -10
  144. package/dist/components/field-sync.js.map +1 -1
  145. package/dist/components/file-button.js.map +1 -1
  146. package/dist/components/file-dropzone.js.map +1 -1
  147. package/dist/components/floating-panel.js +4 -1
  148. package/dist/components/floating-panel.js.map +1 -1
  149. package/dist/components/focus-ring.js.map +1 -1
  150. package/dist/components/form-actions.js.map +1 -1
  151. package/dist/components/grouped-picker.js +11 -12
  152. package/dist/components/grouped-picker.js.map +1 -1
  153. package/dist/components/hover-menu.js +1 -4
  154. package/dist/components/hover-menu.js.map +1 -1
  155. package/dist/components/iban-input-labels.js.map +1 -1
  156. package/dist/components/icon-button.js +4 -1
  157. package/dist/components/icon-button.js.map +1 -1
  158. package/dist/components/icon-picker.js +6 -10
  159. package/dist/components/icon-picker.js.map +1 -1
  160. package/dist/components/image-grid.js +41 -50
  161. package/dist/components/image-grid.js.map +1 -1
  162. package/dist/components/inline-edit-field.js.map +1 -1
  163. package/dist/components/inline-entity-combobox.js +6 -12
  164. package/dist/components/inline-entity-combobox.js.map +1 -1
  165. package/dist/components/input.js +14 -2
  166. package/dist/components/input.js.map +1 -1
  167. package/dist/components/jump-calendar.js +1 -7
  168. package/dist/components/jump-calendar.js.map +1 -1
  169. package/dist/components/legal-labels.js +8 -2
  170. package/dist/components/legal-labels.js.map +1 -1
  171. package/dist/components/legal-page.d.ts +18 -1
  172. package/dist/components/legal-page.js +27 -2
  173. package/dist/components/legal-page.js.map +1 -1
  174. package/dist/components/legal.d.ts +40 -5
  175. package/dist/components/legal.js +41 -5
  176. package/dist/components/legal.js.map +1 -1
  177. package/dist/components/lightbox.js.map +1 -1
  178. package/dist/components/line-items.js +26 -36
  179. package/dist/components/line-items.js.map +1 -1
  180. package/dist/components/list-labels.js +3 -1
  181. package/dist/components/list-labels.js.map +1 -1
  182. package/dist/components/list.d.ts +18 -1
  183. package/dist/components/list.js +54 -13
  184. package/dist/components/list.js.map +1 -1
  185. package/dist/components/measured-grid.js +29 -53
  186. package/dist/components/measured-grid.js.map +1 -1
  187. package/dist/components/menu-item.js.map +1 -1
  188. package/dist/components/mini-calendar.js +13 -31
  189. package/dist/components/mini-calendar.js.map +1 -1
  190. package/dist/components/money-field.js.map +1 -1
  191. package/dist/components/month-picker.js +10 -21
  192. package/dist/components/month-picker.js.map +1 -1
  193. package/dist/components/multi-entity-combobox.js +3 -16
  194. package/dist/components/multi-entity-combobox.js.map +1 -1
  195. package/dist/components/multi-select.js.map +1 -1
  196. package/dist/components/nav-pills.js +10 -1
  197. package/dist/components/nav-pills.js.map +1 -1
  198. package/dist/components/number-field.js.map +1 -1
  199. package/dist/components/number-input.js +1 -7
  200. package/dist/components/number-input.js.map +1 -1
  201. package/dist/components/numpad-sheet.js +1 -4
  202. package/dist/components/numpad-sheet.js.map +1 -1
  203. package/dist/components/one-time-code-input.js +1 -7
  204. package/dist/components/one-time-code-input.js.map +1 -1
  205. package/dist/components/page-contents.js +13 -22
  206. package/dist/components/page-contents.js.map +1 -1
  207. package/dist/components/page-header.js +1 -11
  208. package/dist/components/page-header.js.map +1 -1
  209. package/dist/components/password-strength-labels.js.map +1 -1
  210. package/dist/components/password-strength.js +2 -8
  211. package/dist/components/password-strength.js.map +1 -1
  212. package/dist/components/phone-input.js +42 -57
  213. package/dist/components/phone-input.js.map +1 -1
  214. package/dist/components/picker-sheet.js.map +1 -1
  215. package/dist/components/pie-chart.js +1 -8
  216. package/dist/components/pie-chart.js.map +1 -1
  217. package/dist/components/popover.js.map +1 -1
  218. package/dist/components/progress-bar.js +16 -9
  219. package/dist/components/progress-bar.js.map +1 -1
  220. package/dist/components/qr-code.js +1 -8
  221. package/dist/components/qr-code.js.map +1 -1
  222. package/dist/components/row-actions.js +5 -1
  223. package/dist/components/row-actions.js.map +1 -1
  224. package/dist/components/search-field.js.map +1 -1
  225. package/dist/components/select.js +28 -38
  226. package/dist/components/select.js.map +1 -1
  227. package/dist/components/separator.js +1 -5
  228. package/dist/components/separator.js.map +1 -1
  229. package/dist/components/series-chart-axes.js +4 -1
  230. package/dist/components/series-chart-axes.js.map +1 -1
  231. package/dist/components/series-chart-budget.js.map +1 -1
  232. package/dist/components/series-chart-ticks.js.map +1 -1
  233. package/dist/components/series-chart.js +29 -45
  234. package/dist/components/series-chart.js.map +1 -1
  235. package/dist/components/settings-fields.js +21 -17
  236. package/dist/components/settings-fields.js.map +1 -1
  237. package/dist/components/share-card.js +4 -9
  238. package/dist/components/share-card.js.map +1 -1
  239. package/dist/components/sign-chip.js.map +1 -1
  240. package/dist/components/signature-pad.js +4 -13
  241. package/dist/components/signature-pad.js.map +1 -1
  242. package/dist/components/signed-amount.js +12 -5
  243. package/dist/components/signed-amount.js.map +1 -1
  244. package/dist/components/skeleton.js +2 -17
  245. package/dist/components/skeleton.js.map +1 -1
  246. package/dist/components/slider.js +13 -36
  247. package/dist/components/slider.js.map +1 -1
  248. package/dist/components/sparkline.js.map +1 -1
  249. package/dist/components/stat-tile.js +14 -10
  250. package/dist/components/stat-tile.js.map +1 -1
  251. package/dist/components/swatch-picker.js +14 -4
  252. package/dist/components/swatch-picker.js.map +1 -1
  253. package/dist/components/swipeable-row.d.ts +1 -1
  254. package/dist/components/swipeable-row.js +1 -8
  255. package/dist/components/swipeable-row.js.map +1 -1
  256. package/dist/components/table-skeleton.js +4 -1
  257. package/dist/components/table-skeleton.js.map +1 -1
  258. package/dist/components/table.js +12 -9
  259. package/dist/components/table.js.map +1 -1
  260. package/dist/components/tabs.js +5 -24
  261. package/dist/components/tabs.js.map +1 -1
  262. package/dist/components/text-link.js.map +1 -1
  263. package/dist/components/text.js.map +1 -1
  264. package/dist/components/tile-radio.js +1 -7
  265. package/dist/components/tile-radio.js.map +1 -1
  266. package/dist/components/time-input.js.map +1 -1
  267. package/dist/components/toast.js.map +1 -1
  268. package/dist/components/toggle-group.js +6 -1
  269. package/dist/components/toggle-group.js.map +1 -1
  270. package/dist/components/toggle-legend.js +2 -11
  271. package/dist/components/toggle-legend.js.map +1 -1
  272. package/dist/components/tooltip.js +2 -22
  273. package/dist/components/tooltip.js.map +1 -1
  274. package/dist/components/translation-review-editor.js +1 -4
  275. package/dist/components/translation-review-editor.js.map +1 -1
  276. package/dist/components/translation-review-parts.d.ts +1 -1
  277. package/dist/components/translation-review-parts.js +7 -1
  278. package/dist/components/translation-review-parts.js.map +1 -1
  279. package/dist/components/translation-review.js +18 -7
  280. package/dist/components/translation-review.js.map +1 -1
  281. package/dist/components/tree-view.js +14 -10
  282. package/dist/components/tree-view.js.map +1 -1
  283. package/dist/components/treemap.js +1 -13
  284. package/dist/components/treemap.js.map +1 -1
  285. package/dist/components/trigger-aria.js.map +1 -1
  286. package/dist/components/use-table-state.js +14 -11
  287. package/dist/components/use-table-state.js.map +1 -1
  288. package/dist/components/user-avatar.js +3 -26
  289. package/dist/components/user-avatar.js.map +1 -1
  290. package/dist/demo/demo-start.js +8 -4
  291. package/dist/demo/demo-start.js.map +1 -1
  292. package/dist/eslint/index.js +1 -1
  293. package/dist/feedback/feedback-attachment-labels.js.map +1 -1
  294. package/dist/feedback/feedback-attachment.js +1 -8
  295. package/dist/feedback/feedback-attachment.js.map +1 -1
  296. package/dist/feedback/feedback-capture.d.ts +1 -1
  297. package/dist/feedback/feedback-capture.js +3 -1
  298. package/dist/feedback/feedback-capture.js.map +1 -1
  299. package/dist/feedback/feedback-comment-thread.js +27 -13
  300. package/dist/feedback/feedback-comment-thread.js.map +1 -1
  301. package/dist/feedback/feedback-context.js +1 -4
  302. package/dist/feedback/feedback-context.js.map +1 -1
  303. package/dist/feedback/feedback-dialog.js.map +1 -1
  304. package/dist/feedback/feedback-inbox.js.map +1 -1
  305. package/dist/feedback/feedback-public-list.js +7 -1
  306. package/dist/feedback/feedback-public-list.js.map +1 -1
  307. package/dist/feedback/feedback-record.js +1 -5
  308. package/dist/feedback/feedback-record.js.map +1 -1
  309. package/dist/feedback/feedback-replies.js +25 -10
  310. package/dist/feedback/feedback-replies.js.map +1 -1
  311. package/dist/feedback/feedback-row-detail.js.map +1 -1
  312. package/dist/feedback/feedback-status-undo.js.map +1 -1
  313. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  314. package/dist/feedback/feedback-table.d.ts +3 -1
  315. package/dist/feedback/feedback-table.js +22 -5
  316. package/dist/feedback/feedback-table.js.map +1 -1
  317. package/dist/feedback/feedback-thread.js +2 -13
  318. package/dist/feedback/feedback-thread.js.map +1 -1
  319. package/dist/feedback/feedback-vocabulary.js.map +1 -1
  320. package/dist/feedback/feedback-vote-button.js.map +1 -1
  321. package/dist/hooks/use-anchored-rect.js.map +1 -1
  322. package/dist/hooks/use-document-title.js.map +1 -1
  323. package/dist/hooks/use-file-drop.js.map +1 -1
  324. package/dist/hooks/use-file-picker-labels.js.map +1 -1
  325. package/dist/hooks/use-file-picker.js.map +1 -1
  326. package/dist/hooks/use-focus-trap.js.map +1 -1
  327. package/dist/hooks/use-overlay-history.js +10 -5
  328. package/dist/hooks/use-overlay-history.js.map +1 -1
  329. package/dist/hooks/use-row-swipe.d.ts +1 -1
  330. package/dist/hooks/use-row-swipe.js +1 -6
  331. package/dist/hooks/use-row-swipe.js.map +1 -1
  332. package/dist/i18n/defaults.js +1 -4
  333. package/dist/i18n/defaults.js.map +1 -1
  334. package/dist/i18n/german.js +15 -4
  335. package/dist/i18n/german.js.map +1 -1
  336. package/dist/i18n/kit-labels.js +2 -8
  337. package/dist/i18n/kit-labels.js.map +1 -1
  338. package/dist/i18n/languages.js.map +1 -1
  339. package/dist/i18n/locales/en.js +19 -4
  340. package/dist/i18n/locales/en.js.map +2 -2
  341. package/dist/i18n/locales/es.js +15 -4
  342. package/dist/i18n/locales/es.js.map +1 -1
  343. package/dist/i18n/locales/fr.js +15 -4
  344. package/dist/i18n/locales/fr.js.map +1 -1
  345. package/dist/i18n/locales/hu.js +15 -4
  346. package/dist/i18n/locales/hu.js.map +1 -1
  347. package/dist/i18n/locales/it.js +15 -4
  348. package/dist/i18n/locales/it.js.map +1 -1
  349. package/dist/i18n/locales/zh.js +11 -3
  350. package/dist/i18n/locales/zh.js.map +1 -1
  351. package/dist/i18n/plurals.js.map +1 -1
  352. package/dist/i18n/review.js +15 -7
  353. package/dist/i18n/review.js.map +1 -1
  354. package/dist/i18n/shared-labels.js.map +1 -1
  355. package/dist/index.d.ts +17 -17
  356. package/dist/index.js +40 -23
  357. package/dist/index.js.map +1 -1
  358. package/dist/landing/access.js +1 -4
  359. package/dist/landing/access.js.map +1 -1
  360. package/dist/landing/landing-sections.js +35 -38
  361. package/dist/landing/landing-sections.js.map +1 -1
  362. package/dist/landing/page-seo.js.map +1 -1
  363. package/dist/lib/calc.js.map +1 -1
  364. package/dist/lib/clipboard-minus.js.map +1 -1
  365. package/dist/lib/dates.js.map +1 -1
  366. package/dist/lib/decimal-marks.js.map +1 -1
  367. package/dist/lib/device-settings.js +2 -1
  368. package/dist/lib/device-settings.js.map +1 -1
  369. package/dist/lib/direction.js.map +1 -1
  370. package/dist/lib/iban.js.map +1 -1
  371. package/dist/lib/logger.js +1 -5
  372. package/dist/lib/logger.js.map +1 -1
  373. package/dist/lib/person-name.js.map +1 -1
  374. package/dist/lib/phone.js.map +1 -1
  375. package/dist/lib/qr-encode.js +344 -8
  376. package/dist/lib/qr-encode.js.map +1 -1
  377. package/dist/lib/session-refresh.js.map +1 -1
  378. package/dist/lib/table-text.js +15 -3
  379. package/dist/lib/table-text.js.map +1 -1
  380. package/dist/lib/text-match.d.ts +20 -0
  381. package/dist/lib/text-match.js +11 -1
  382. package/dist/lib/text-match.js.map +1 -1
  383. package/dist/lib/translation-review.js.map +1 -1
  384. package/dist/notifications/notification-inbox.js +63 -44
  385. package/dist/notifications/notification-inbox.js.map +1 -1
  386. package/dist/notifications/notification-parts.js.map +1 -1
  387. package/dist/notifications/notification-types-setting.js.map +1 -1
  388. package/dist/notifications/notifications-labels.js.map +1 -1
  389. package/dist/notifications/push-device-setting.js +6 -1
  390. package/dist/notifications/push-device-setting.js.map +1 -1
  391. package/dist/notifications/push-devices-setting.js.map +1 -1
  392. package/dist/notifications/push-worker.js.map +1 -1
  393. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  394. package/dist/notifications/use-push-device.js +4 -1
  395. package/dist/notifications/use-push-device.js.map +1 -1
  396. package/dist/offline/pwa-update-prompt.d.ts +1 -1
  397. package/dist/offline/pwa-update-prompt.js +7 -1
  398. package/dist/offline/pwa-update-prompt.js.map +1 -1
  399. package/dist/offline/query-persistence.js.map +1 -1
  400. package/dist/offline.d.ts +1 -1
  401. package/dist/offline.js +6 -1
  402. package/dist/offline.js.map +1 -1
  403. package/dist/pay/pay.css +8 -1
  404. package/dist/rhf/fields.d.ts +1 -2
  405. package/dist/rhf/fields.js +1 -10
  406. package/dist/rhf/fields.js.map +1 -1
  407. package/dist/rhf/form-core.js +1 -4
  408. package/dist/rhf/form-core.js.map +1 -1
  409. package/dist/rhf/line-items.js.map +1 -1
  410. package/dist/rhf/use-rhf-wizard-step.js.map +1 -1
  411. package/dist/search/command-palette.js +71 -62
  412. package/dist/search/command-palette.js.map +1 -1
  413. package/dist/search/global-search.js +34 -5
  414. package/dist/search/global-search.js.map +1 -1
  415. package/dist/search/search-index.js.map +1 -1
  416. package/dist/settings/device-reset-setting.js +1 -6
  417. package/dist/settings/device-reset-setting.js.map +1 -1
  418. package/dist/settings/settings-heading.js.map +1 -1
  419. package/dist/settings/settings-layout.js +9 -20
  420. package/dist/settings/settings-layout.js.map +1 -1
  421. package/dist/settings/use-settings-focus.d.ts +7 -0
  422. package/dist/settings/use-settings-focus.js +2 -0
  423. package/dist/settings/use-settings-focus.js.map +1 -1
  424. package/dist/settings/use-settings-route.js.map +1 -1
  425. package/dist/shell/app-shell.js +62 -31
  426. package/dist/shell/app-shell.js.map +1 -1
  427. package/dist/shell/auth-layout.js +1 -10
  428. package/dist/shell/auth-layout.js.map +1 -1
  429. package/dist/shell/dev-menu.d.ts +5 -0
  430. package/dist/shell/dev-menu.js +14 -7
  431. package/dist/shell/dev-menu.js.map +1 -1
  432. package/dist/shell/option-switcher-menu.js.map +1 -1
  433. package/dist/shell/sync-status-indicator.js +7 -6
  434. package/dist/shell/sync-status-indicator.js.map +1 -1
  435. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  436. package/dist/shell/topbar-action-menu.d.ts +14 -1
  437. package/dist/shell/topbar-action-menu.js +85 -34
  438. package/dist/shell/topbar-action-menu.js.map +1 -1
  439. package/dist/shell/topbar-controls.js +1 -10
  440. package/dist/shell/topbar-controls.js.map +1 -1
  441. package/dist/shell/tour-menu.js +9 -1
  442. package/dist/shell/tour-menu.js.map +1 -1
  443. package/dist/shell.d.ts +1 -1
  444. package/dist/shell.js +2 -1
  445. package/dist/shell.js.map +1 -1
  446. package/dist/sync/db.js.map +1 -1
  447. package/dist/sync/engine.js +24 -6
  448. package/dist/sync/engine.js.map +1 -1
  449. package/dist/sync.d.ts +2 -2
  450. package/dist/sync.js +7 -1
  451. package/dist/sync.js.map +1 -1
  452. package/dist/testing/css-variables.js.map +1 -1
  453. package/dist/testing/index.d.ts +1 -1
  454. package/dist/testing/index.js +1 -3
  455. package/dist/testing/index.js.map +1 -1
  456. package/dist/testing/react.js.map +1 -1
  457. package/dist/testing/viewport.js +7 -4
  458. package/dist/testing/viewport.js.map +1 -1
  459. package/dist/theme/contrast-tokens.js +13 -2
  460. package/dist/theme/contrast-tokens.js.map +1 -1
  461. package/dist/theme/palette-derive.d.ts +1 -1
  462. package/dist/theme/palette-derive.js +18 -29
  463. package/dist/theme/palette-derive.js.map +1 -1
  464. package/dist/theme/palette-presets.js.map +1 -1
  465. package/dist/theme/palette-store.js.map +1 -1
  466. package/dist/theme/text-size.js.map +1 -1
  467. package/dist/theme/theme-store.js +1 -3
  468. package/dist/theme/theme-store.js.map +1 -1
  469. package/dist/tour/tour-catalogue.js.map +1 -1
  470. package/dist/tour/tour-dock.js +5 -1
  471. package/dist/tour/tour-dock.js.map +1 -1
  472. package/dist/tour/tour-engine.js +1 -4
  473. package/dist/tour/tour-engine.js.map +1 -1
  474. package/dist/tour/tour.js +21 -12
  475. package/dist/tour/tour.js.map +1 -1
  476. package/dist/tour/use-tour-progress.js.map +1 -1
  477. package/dist/tour/use-tour-url-sync.js.map +1 -1
  478. package/dist/wizard/stepper-nav.js +3 -24
  479. package/dist/wizard/stepper-nav.js.map +1 -1
  480. package/dist/wizard/types.js.map +1 -1
  481. package/dist/wizard/use-wizard.js +24 -28
  482. package/dist/wizard/use-wizard.js.map +1 -1
  483. package/dist/wizard/validation.js.map +1 -1
  484. package/dist/wizard/wizard-context.js.map +1 -1
  485. package/dist/wizard/wizard-step.d.ts +1 -1
  486. package/dist/wizard/wizard-step.js +1 -8
  487. package/dist/wizard/wizard-step.js.map +1 -1
  488. package/dist/wizard/wizard-summary.js.map +1 -1
  489. package/package.json +5 -2
  490. package/src/account/account-settings-labels.ts +1 -2
  491. package/src/account/account-settings.tsx +11 -17
  492. package/src/account/delete-account-setting.tsx +1 -6
  493. package/src/account/email-change-setting-labels.ts +1 -2
  494. package/src/account/email-change-setting.tsx +3 -1
  495. package/src/account/passkeys-setting.tsx +1 -3
  496. package/src/account/sessions-setting.tsx +4 -2
  497. package/src/admin/admin-action-confirm.tsx +4 -7
  498. package/src/admin/admin-action-log.tsx +29 -29
  499. package/src/admin/admin-area-labels.ts +4 -1
  500. package/src/admin/admin-overview.tsx +8 -2
  501. package/src/admin/admin-sections.tsx +3 -1
  502. package/src/admin/admin-tool-links.tsx +7 -1
  503. package/src/admin/invitations-panel.tsx +5 -11
  504. package/src/admin/mail-test-card.tsx +1 -2
  505. package/src/admin/reviewer-scope-editor.tsx +4 -9
  506. package/src/admin/role-select.tsx +4 -2
  507. package/src/admin/user-roster.tsx +2 -11
  508. package/src/auth/accept-invitation.tsx +1 -7
  509. package/src/auth/auth-errors.ts +1 -6
  510. package/src/auth/forgot-password-form.tsx +2 -7
  511. package/src/auth/register-form.tsx +7 -8
  512. package/src/auth/reset-password-form.tsx +2 -5
  513. package/src/auth/sign-in-form.tsx +15 -14
  514. package/src/auth/verify-email.tsx +2 -7
  515. package/src/billing/billing-banner.tsx +3 -7
  516. package/src/billing/billing-labels.ts +6 -4
  517. package/src/billing/checkout-processing.ts +0 -1
  518. package/src/billing/plan-card.tsx +9 -8
  519. package/src/billing/plan-limit-toast.tsx +1 -2
  520. package/src/billing/plan-limit.ts +1 -2
  521. package/src/billing/plan-price.ts +1 -4
  522. package/src/billing/plan-switch.tsx +1 -2
  523. package/src/billing/subscription-actions.tsx +5 -2
  524. package/src/components/account-chips.tsx +1 -7
  525. package/src/components/alert-banner.tsx +2 -8
  526. package/src/components/amount-input.tsx +206 -178
  527. package/src/components/authed-image.tsx +7 -4
  528. package/src/components/autocomplete.tsx +7 -9
  529. package/src/components/bulk-action-bar.tsx +2 -7
  530. package/src/components/button-group.tsx +1 -2
  531. package/src/components/button-look.ts +6 -17
  532. package/src/components/button.tsx +1 -4
  533. package/src/components/calculator.tsx +6 -9
  534. package/src/components/calendar-heatmap.tsx +5 -10
  535. package/src/components/card.tsx +9 -13
  536. package/src/components/chart-zoom-core.tsx +6 -33
  537. package/src/components/chart.tsx +8 -31
  538. package/src/components/checkbox-group.tsx +1 -4
  539. package/src/components/chip-input.tsx +6 -6
  540. package/src/components/chip.tsx +14 -26
  541. package/src/components/choice-card.tsx +4 -18
  542. package/src/components/column-mapper-labels.ts +3 -10
  543. package/src/components/column-mapper.tsx +33 -122
  544. package/src/components/combobox-core.tsx +17 -47
  545. package/src/components/combobox.tsx +2 -6
  546. package/src/components/confirm-dialog.tsx +1 -3
  547. package/src/components/copy-button.tsx +2 -4
  548. package/src/components/country-select.tsx +9 -21
  549. package/src/components/currency-option-list.tsx +16 -18
  550. package/src/components/currency-select.tsx +2 -7
  551. package/src/components/danger-confirm.tsx +8 -9
  552. package/src/components/data-table-cells.tsx +1 -2
  553. package/src/components/data-table-column-settings.tsx +1 -3
  554. package/src/components/data-table-filter-popover.tsx +5 -19
  555. package/src/components/data-table-filters.ts +1 -6
  556. package/src/components/data-table-fit.ts +7 -7
  557. package/src/components/data-table-groups.tsx +3 -1
  558. package/src/components/data-table-head.tsx +32 -46
  559. package/src/components/data-table-mobile.tsx +99 -108
  560. package/src/components/data-table-pagination.tsx +2 -6
  561. package/src/components/data-table-row-actions.tsx +25 -24
  562. package/src/components/data-table-row.tsx +16 -17
  563. package/src/components/data-table-shared.tsx +10 -16
  564. package/src/components/data-table-sort.ts +1 -2
  565. package/src/components/data-table-virtual.ts +9 -4
  566. package/src/components/data-table.tsx +497 -501
  567. package/src/components/date-picker.tsx +1 -7
  568. package/src/components/date-range-picker.tsx +3 -13
  569. package/src/components/description-list.tsx +7 -13
  570. package/src/components/dialog-frame.tsx +12 -3
  571. package/src/components/disclosure.tsx +8 -12
  572. package/src/components/dropdown.tsx +3 -11
  573. package/src/components/empty-state.tsx +1 -3
  574. package/src/components/entity-combobox.tsx +2 -6
  575. package/src/components/error-boundary.tsx +7 -7
  576. package/src/components/field-base.tsx +8 -14
  577. package/src/components/field-parts.tsx +12 -23
  578. package/src/components/field-sync.tsx +7 -11
  579. package/src/components/file-button.tsx +7 -3
  580. package/src/components/file-dropzone.tsx +7 -12
  581. package/src/components/floating-panel.tsx +44 -51
  582. package/src/components/focus-ring.ts +1 -2
  583. package/src/components/form-actions.tsx +1 -4
  584. package/src/components/grouped-picker.tsx +21 -16
  585. package/src/components/hover-menu.tsx +1 -4
  586. package/src/components/iban-input-labels.ts +1 -2
  587. package/src/components/icon-button.tsx +46 -48
  588. package/src/components/icon-picker.tsx +9 -20
  589. package/src/components/image-grid.tsx +1 -6
  590. package/src/components/inline-edit-field.tsx +1 -5
  591. package/src/components/inline-entity-combobox.tsx +11 -25
  592. package/src/components/input.tsx +14 -2
  593. package/src/components/jump-calendar.tsx +2 -6
  594. package/src/components/legal-labels.ts +8 -3
  595. package/src/components/legal-page.tsx +56 -6
  596. package/src/components/legal.tsx +83 -10
  597. package/src/components/lightbox.tsx +1 -3
  598. package/src/components/line-items.tsx +7 -15
  599. package/src/components/list-labels.ts +2 -0
  600. package/src/components/list.tsx +81 -27
  601. package/src/components/measured-grid.tsx +8 -30
  602. package/src/components/menu-item.tsx +1 -3
  603. package/src/components/mini-calendar.tsx +129 -159
  604. package/src/components/money-field.tsx +4 -2
  605. package/src/components/month-picker.tsx +14 -21
  606. package/src/components/multi-entity-combobox.tsx +6 -26
  607. package/src/components/multi-select.tsx +5 -9
  608. package/src/components/nav-pills.tsx +10 -2
  609. package/src/components/number-field.tsx +18 -15
  610. package/src/components/number-input.tsx +3 -19
  611. package/src/components/numpad-sheet.tsx +9 -13
  612. package/src/components/one-time-code-input.tsx +6 -11
  613. package/src/components/page-contents.tsx +2 -9
  614. package/src/components/page-header.tsx +5 -10
  615. package/src/components/password-strength-labels.ts +1 -2
  616. package/src/components/password-strength.tsx +6 -9
  617. package/src/components/phone-input.tsx +2 -13
  618. package/src/components/picker-sheet.tsx +2 -5
  619. package/src/components/pie-chart.tsx +6 -12
  620. package/src/components/popover.tsx +2 -1
  621. package/src/components/progress-bar.tsx +16 -25
  622. package/src/components/qr-code.tsx +2 -9
  623. package/src/components/row-actions.tsx +9 -1
  624. package/src/components/search-field.tsx +4 -5
  625. package/src/components/select.tsx +2 -10
  626. package/src/components/separator.tsx +1 -5
  627. package/src/components/series-chart-axes.ts +5 -5
  628. package/src/components/series-chart-budget.ts +1 -4
  629. package/src/components/series-chart-ticks.ts +1 -4
  630. package/src/components/series-chart.tsx +43 -83
  631. package/src/components/settings-fields.tsx +20 -15
  632. package/src/components/share-card.tsx +6 -14
  633. package/src/components/sign-chip.tsx +16 -16
  634. package/src/components/signature-pad.tsx +21 -13
  635. package/src/components/signed-amount.tsx +6 -14
  636. package/src/components/skeleton.tsx +2 -13
  637. package/src/components/slider.tsx +9 -20
  638. package/src/components/sparkline.tsx +2 -13
  639. package/src/components/stat-tile.tsx +13 -24
  640. package/src/components/swatch-picker.tsx +8 -3
  641. package/src/components/swipeable-row.tsx +2 -11
  642. package/src/components/table-skeleton.tsx +4 -1
  643. package/src/components/table.tsx +12 -8
  644. package/src/components/tabs.tsx +24 -39
  645. package/src/components/text-link.tsx +6 -6
  646. package/src/components/text.tsx +1 -2
  647. package/src/components/tile-radio.tsx +6 -19
  648. package/src/components/time-input.tsx +4 -5
  649. package/src/components/toast.tsx +3 -12
  650. package/src/components/toggle-group.tsx +9 -9
  651. package/src/components/toggle-legend.tsx +4 -16
  652. package/src/components/tooltip.tsx +9 -48
  653. package/src/components/translation-review-editor.tsx +4 -4
  654. package/src/components/translation-review-parts.tsx +7 -1
  655. package/src/components/translation-review.tsx +15 -16
  656. package/src/components/tree-view.tsx +17 -20
  657. package/src/components/treemap.tsx +3 -15
  658. package/src/components/trigger-aria.ts +1 -4
  659. package/src/components/use-table-state.ts +16 -17
  660. package/src/components/user-avatar.tsx +4 -21
  661. package/src/demo/demo-start.tsx +8 -4
  662. package/src/feedback/feedback-attachment-labels.ts +2 -1
  663. package/src/feedback/feedback-attachment.tsx +16 -29
  664. package/src/feedback/feedback-capture.ts +3 -1
  665. package/src/feedback/feedback-comment-thread.tsx +9 -6
  666. package/src/feedback/feedback-context.tsx +1 -4
  667. package/src/feedback/feedback-dialog.tsx +3 -4
  668. package/src/feedback/feedback-inbox.tsx +3 -9
  669. package/src/feedback/feedback-public-list.tsx +7 -1
  670. package/src/feedback/feedback-record.ts +6 -14
  671. package/src/feedback/feedback-replies.tsx +10 -5
  672. package/src/feedback/feedback-row-detail.tsx +2 -5
  673. package/src/feedback/feedback-status-undo.ts +1 -4
  674. package/src/feedback/feedback-submit-dialog.tsx +4 -4
  675. package/src/feedback/feedback-table.tsx +29 -9
  676. package/src/feedback/feedback-thread.tsx +4 -16
  677. package/src/feedback/feedback-vocabulary.ts +72 -82
  678. package/src/feedback/feedback-vote-button.tsx +9 -8
  679. package/src/hooks/use-anchored-rect.ts +1 -4
  680. package/src/hooks/use-document-title.ts +3 -1
  681. package/src/hooks/use-file-drop.ts +1 -3
  682. package/src/hooks/use-file-picker-labels.ts +1 -2
  683. package/src/hooks/use-file-picker.tsx +1 -5
  684. package/src/hooks/use-focus-trap.ts +1 -2
  685. package/src/hooks/use-overlay-history.ts +10 -5
  686. package/src/hooks/use-row-swipe.ts +1 -6
  687. package/src/i18n/defaults.ts +1 -4
  688. package/src/i18n/german.ts +42 -50
  689. package/src/i18n/kit-labels.tsx +5 -20
  690. package/src/i18n/languages.ts +2 -8
  691. package/src/i18n/locales/en.ts +15 -31
  692. package/src/i18n/locales/es.ts +44 -50
  693. package/src/i18n/locales/fr.ts +43 -52
  694. package/src/i18n/locales/hu.ts +35 -38
  695. package/src/i18n/locales/it.ts +44 -53
  696. package/src/i18n/locales/zh.ts +23 -33
  697. package/src/i18n/plurals.ts +4 -1
  698. package/src/i18n/review.ts +20 -7
  699. package/src/i18n/shared-labels.ts +1 -2
  700. package/src/index.ts +107 -32
  701. package/src/landing/access.ts +2 -7
  702. package/src/landing/landing-sections.tsx +14 -15
  703. package/src/landing/page-seo.ts +1 -3
  704. package/src/lib/calc.ts +4 -1
  705. package/src/lib/clipboard-minus.ts +4 -1
  706. package/src/lib/dates.ts +2 -10
  707. package/src/lib/decimal-marks.ts +1 -3
  708. package/src/lib/device-settings.ts +2 -1
  709. package/src/lib/direction.ts +1 -3
  710. package/src/lib/iban.ts +89 -9
  711. package/src/lib/logger.ts +1 -5
  712. package/src/lib/person-name.ts +1 -3
  713. package/src/lib/phone.ts +5 -8
  714. package/src/lib/qr-encode.ts +32 -8
  715. package/src/lib/session-refresh.ts +5 -6
  716. package/src/lib/table-text.ts +24 -6
  717. package/src/lib/text-match.ts +43 -1
  718. package/src/lib/translation-review.ts +1 -3
  719. package/src/notifications/notification-inbox.tsx +17 -4
  720. package/src/notifications/notification-parts.tsx +1 -2
  721. package/src/notifications/notification-types-setting.tsx +19 -18
  722. package/src/notifications/notifications-labels.ts +1 -2
  723. package/src/notifications/push-device-setting.tsx +7 -1
  724. package/src/notifications/push-devices-setting.tsx +7 -3
  725. package/src/notifications/push-worker.ts +10 -2
  726. package/src/notifications/quiet-hours-setting.tsx +4 -1
  727. package/src/notifications/use-push-device.ts +4 -1
  728. package/src/offline/pwa-update-prompt.tsx +7 -1
  729. package/src/offline/query-persistence.ts +9 -6
  730. package/src/offline.ts +6 -1
  731. package/src/rhf/fields.tsx +50 -19
  732. package/src/rhf/form-core.tsx +2 -6
  733. package/src/rhf/line-items.tsx +5 -7
  734. package/src/rhf/use-rhf-wizard-step.ts +3 -12
  735. package/src/search/command-palette.tsx +15 -23
  736. package/src/search/global-search.tsx +38 -8
  737. package/src/search/search-index.ts +5 -1
  738. package/src/settings/device-reset-setting.tsx +5 -8
  739. package/src/settings/settings-heading.tsx +3 -1
  740. package/src/settings/settings-layout.tsx +6 -13
  741. package/src/settings/use-settings-focus.ts +8 -0
  742. package/src/settings/use-settings-route.ts +4 -3
  743. package/src/shell/app-shell.tsx +48 -24
  744. package/src/shell/auth-layout.tsx +1 -6
  745. package/src/shell/dev-menu.tsx +18 -6
  746. package/src/shell/option-switcher-menu.tsx +1 -3
  747. package/src/shell/sync-status-indicator.tsx +14 -12
  748. package/src/shell/top-bar-parts-labels.ts +1 -3
  749. package/src/shell/topbar-action-menu.tsx +130 -45
  750. package/src/shell/topbar-controls.tsx +5 -19
  751. package/src/shell/tour-menu.tsx +9 -1
  752. package/src/shell.ts +1 -1
  753. package/src/sync/db.ts +5 -1
  754. package/src/sync/engine.ts +44 -12
  755. package/src/sync.ts +16 -2
  756. package/src/testing/css-variables.ts +1 -2
  757. package/src/testing/index.ts +1 -6
  758. package/src/testing/react.ts +1 -2
  759. package/src/testing/viewport.ts +9 -9
  760. package/src/theme/contrast-tokens.ts +13 -2
  761. package/src/theme/palette-derive.ts +24 -50
  762. package/src/theme/palette-presets.ts +0 -1
  763. package/src/theme/palette-store.ts +1 -4
  764. package/src/theme/text-size.ts +1 -1
  765. package/src/theme/theme-store.ts +2 -6
  766. package/src/tour/tour-catalogue.tsx +4 -2
  767. package/src/tour/tour-dock.ts +5 -1
  768. package/src/tour/tour-engine.ts +2 -6
  769. package/src/tour/tour.tsx +28 -12
  770. package/src/tour/use-tour-progress.ts +8 -2
  771. package/src/tour/use-tour-url-sync.ts +3 -1
  772. package/src/vite-env.d.ts +1 -4
  773. package/src/wizard/stepper-nav.tsx +10 -35
  774. package/src/wizard/types.ts +1 -4
  775. package/src/wizard/use-wizard.ts +28 -43
  776. package/src/wizard/validation.ts +1 -5
  777. package/src/wizard/wizard-context.tsx +2 -6
  778. package/src/wizard/wizard-step.tsx +1 -8
  779. package/src/wizard/wizard-summary.tsx +2 -6
  780. package/tokens.css +393 -152
@@ -29,7 +29,13 @@ import {
29
29
  type RowGroup,
30
30
  } from "./data-table-groups";
31
31
  export type { DataTableGroupBy, DataTableLoadMore } from "./data-table-groups";
32
- import { VIRTUAL_SELECT_COL, rowNavTarget, useRowWindow, type DataTableVirtualize, type VirtualGroup } from "./data-table-virtual";
32
+ import {
33
+ VIRTUAL_SELECT_COL,
34
+ rowNavTarget,
35
+ useRowWindow,
36
+ type DataTableVirtualize,
37
+ type VirtualGroup,
38
+ } from "./data-table-virtual";
33
39
  export type { DataTableVirtualize } from "./data-table-virtual";
34
40
  import { ColumnSettingsPanel } from "./data-table-column-settings";
35
41
  import { useLargeText } from "../hooks/use-large-text";
@@ -46,7 +52,12 @@ import { FullBleedDialog } from "./full-bleed-dialog";
46
52
  import { usePhoneLayout } from "../hooks/use-breakpoint";
47
53
  import { useAnnounce } from "../hooks/use-announce";
48
54
  import { DEFAULT_DATA_TABLE_LABELS, type DataTableLabels } from "./data-table-labels";
49
- import { useKitLabelOverrides, useKitLocale, useKitTableStorageKeyPrefix, type LabelOverride } from "../i18n/kit-labels";
55
+ import {
56
+ useKitLabelOverrides,
57
+ useKitLocale,
58
+ useKitTableStorageKeyPrefix,
59
+ type LabelOverride,
60
+ } from "../i18n/kit-labels";
50
61
  import { useEdgeFade } from "../lib/strip-fade";
51
62
  import { dirOf, type Direction } from "../lib/direction";
52
63
 
@@ -184,6 +195,14 @@ export interface DataTableColumn<T> {
184
195
  * broken in two to make room for it.
185
196
  */
186
197
  grow?: boolean;
198
+ /**
199
+ * The least this `grow` column keeps, in rem (0.51.4; default 10): the floor below which
200
+ * the table leaves out `fitPriority` columns, and once none is left, scrolls sideways.
201
+ * Lower it for a column whose first words carry it — the feedback inbox's Subject, 8,
202
+ * so the inbox at 768px with a sidebar keeps Subject, Status and the row actions
203
+ * without scrolling (Kurvenschmiede). In rem, so Large text asks for more.
204
+ */
205
+ growMin?: number;
187
206
  /**
188
207
  * Leave this column out while the TABLE is too narrow for it (0.48, keksdose live
189
208
  * #451) — measured on the table's own scroller, so a sidebar, the window and Large
@@ -901,8 +920,7 @@ export interface DataTableDesktopSwipeActions<T> {
901
920
  * its borders, and a collapsed border belongs to the TABLE, not the cell, so it stays
902
921
  * behind at the bottom of the rows while the sticky cell rides over them.
903
922
  */
904
- const FOOTER_CELL =
905
- "sticky bottom-0 z-10 bg-surface-2 shadow-[inset_0_2px_0_var(--border-strong)]";
923
+ const FOOTER_CELL = "sticky bottom-0 z-10 bg-surface-2 shadow-[inset_0_2px_0_var(--border-strong)]";
906
924
 
907
925
  // ---------- Phone sort control (keksdose K10) ----------
908
926
 
@@ -946,8 +964,6 @@ const NO_VIRTUAL_OPTIONS: DataTableVirtualize = {};
946
964
 
947
965
  // ---------- Main DataTable ----------
948
966
 
949
-
950
-
951
967
  import { DEFAULT_PERSIST_PREFIX, useTableState, type TableUrlSync } from "./use-table-state";
952
968
  import { useMobileReveal } from "./use-mobile-reveal";
953
969
  import { GROW_CELL_CLASS, GROW_PEER_CELL_CLASS, useColumnFit } from "./data-table-fit";
@@ -1277,7 +1293,7 @@ export function DataTable<T>({
1277
1293
  // "clear all"). Only touches keys the table actually exposes as filters.
1278
1294
  const clearAllFilters = () => {
1279
1295
  const keys = columns
1280
- .filter((col) => ((!serverRows || onFiltersChange) ? resolveFilter(col) : null))
1296
+ .filter((col) => (!serverRows || onFiltersChange ? resolveFilter(col) : null))
1281
1297
  .map((col) => col.key);
1282
1298
  if (!keys.length) return;
1283
1299
  if (onFiltersChange) {
@@ -1540,8 +1556,7 @@ export function DataTable<T>({
1540
1556
  // and screen reader's way — enters the mode: every card shows its box and a tap
1541
1557
  // toggles it. The mode lasts while anything is selected, so emptying the selection
1542
1558
  // (the bulk bar's Clear, the last box unticked, Cancel) leaves it, as kk's does.
1543
- const anySelected =
1544
- !!selection && (selection.someSelected || (selection.allSelected && slice.length > 0));
1559
+ const anySelected = !!selection && (selection.someSelected || (selection.allSelected && slice.length > 0));
1545
1560
  const [phoneSelectMode, setPhoneSelectMode] = useState(false);
1546
1561
  const [hadSelection, setHadSelection] = useState(anySelected);
1547
1562
  if (anySelected !== hadSelection) {
@@ -1700,7 +1715,12 @@ export function DataTable<T>({
1700
1715
  continue;
1701
1716
  }
1702
1717
  g1.children.forEach((g2, j) => {
1703
- virtualGroups.push({ start: g2.start, end: g2.start + g2.rows.length, bands: j === 0 ? BAND_1_2 : BAND_2, first });
1718
+ virtualGroups.push({
1719
+ start: g2.start,
1720
+ end: g2.start + g2.rows.length,
1721
+ bands: j === 0 ? BAND_1_2 : BAND_2,
1722
+ first,
1723
+ });
1704
1724
  virtualBands.push({ g1, g2 });
1705
1725
  });
1706
1726
  }
@@ -1791,266 +1811,247 @@ export function DataTable<T>({
1791
1811
  data-table-toolbar=""
1792
1812
  className={cn(
1793
1813
  "flex flex-wrap items-center gap-2",
1794
- frame
1795
- ? cn("border-b border-subtle", compact ? "px-2 py-1.5" : "px-3 py-2")
1796
- : "pb-3",
1814
+ frame ? cn("border-b border-subtle", compact ? "px-2 py-1.5" : "px-3 py-2") : "pb-3",
1797
1815
  )}
1798
1816
  >
1799
1817
  {toolbar}
1800
1818
  </div>
1801
1819
  )}
1802
1820
  {!isMdUp && (
1803
- <div ref={mobileRootRef} className={cn(fillHeight && "flex min-h-0 flex-1 flex-col")}>
1804
- {/* Mobile filter access (feedback #299): the per-column filter popovers
1821
+ <div ref={mobileRootRef} className={cn(fillHeight && "flex min-h-0 flex-1 flex-col")}>
1822
+ {/* Mobile filter access (feedback #299): the per-column filter popovers
1805
1823
  live in the desktop header, which the card list doesn't render — so
1806
1824
  expose the same filters through a bottom sheet here. */}
1807
- {(!serverRows || onFiltersChange) && (
1808
- <MobileFilters
1809
- columns={columns}
1810
- filters={filters}
1811
- selectOptionsByKey={selectOptionsByKey}
1812
- isServer={serverRows}
1813
- hasFilterCallback={!!onFiltersChange}
1814
- onSetFilter={setFilterValue}
1815
- onClearFilter={clearFilter}
1816
- onClearAll={clearAllFilters}
1817
- labels={labels}
1818
- locale={locale}
1819
- />
1820
- )}
1821
- {mobileSort && (
1822
- <MobileSort
1823
- columns={visibleColumns.filter((c) => (!serverRows || !!onSortsChange) && !!c.sortBy)}
1824
- sorts={sorts}
1825
- sortCycle={sortCycle}
1826
- compact={compact}
1827
- labels={labels}
1828
- onPick={(key) => {
1829
- if (key === null) {
1830
- if (sorts.length > 0) commitSorts([], sorts[0].key);
1831
- return;
1832
- }
1833
- if (sorts[0]?.key === key) return;
1834
- // A newly picked column starts where its header's first click would.
1835
- const col = columns.find((c) => c.key === key);
1836
- commitSorts([{ key, dir: col?.firstSort ?? "asc" }], key);
1837
- }}
1838
- onFlip={() => {
1839
- if (sorts.length === 0) return;
1840
- commitSorts(
1841
- sorts.map((s, i) => (i === 0 ? { ...s, dir: flipDir(s.dir) } : s)),
1842
- sorts[0].key,
1843
- );
1844
- }}
1845
- />
1846
- )}
1847
- {selection && (
1848
- <MobileSelectBar
1849
- active={phoneSelecting}
1850
- allSelected={selection.allSelected}
1851
- someSelected={selection.someSelected}
1852
- compact={compact}
1853
- labels={labels}
1854
- onEnter={() => setPhoneSelectMode(true)}
1855
- onToggleAll={selection.onToggleAll}
1856
- onCancel={() => {
1857
- setPhoneSelectMode(false);
1858
- if (anySelected) selection.onToggleAll(false);
1859
- }}
1860
- />
1861
- )}
1862
- <ul
1863
- ref={phoneListRef}
1864
- className={cn(
1865
- "divide-y divide-subtle",
1866
- // Under `fillHeight` the list takes the room its parent gives it, and in a
1867
- // BOUNDED parent it is the scroller, as the table body is on a wide screen:
1868
- // the filter button stays above it and a server pager below. Only then —
1869
- // see `phoneListScrolls` (live #420). The endless-scroll sentinel still
1870
- // fires in here — an IntersectionObserver on the viewport sees through the
1871
- // clipping ancestor.
1872
- fillHeight && "min-h-0 flex-1",
1873
- fillHeight && phoneListScrolls && "overflow-y-auto overscroll-contain",
1874
- // Same busy treatment as the desktop body; see `isLoading` below.
1875
- isLoading && mobileSlice.length > 0 && "opacity-60 transition-opacity",
1876
- )}
1877
- aria-busy={isLoading || undefined}
1878
- >
1879
- {mobileGroups
1880
- ? mobileGroups.map((g) => (
1881
- <Fragment key={`hb-group:${g.key}`}>
1882
- <li className="sticky top-0 z-10 flex flex-wrap items-baseline justify-between gap-x-3 bg-surface-2 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-muted backdrop-blur">
1883
- <span className="min-w-0">
1884
- {mobileGroupLabel
1885
- ? mobileGroupLabel(g.key)
1886
- : mobileLevel?.label
1887
- ? mobileLevel.label(g.key, g.rows)
1888
- : g.key}
1889
- </span>
1890
- {mobileLevel?.end && <span className="ms-auto tabular-nums">{mobileLevel.end(g.key, g.rows)}</span>}
1891
- </li>
1892
- {g.rows.map(renderMobileRow)}
1893
- </Fragment>
1894
- ))
1895
- : mobileSlice.map(renderMobileRow)}
1896
- {mobileSlice.length === 0 && (
1897
- <li
1898
- className={cn(
1899
- "text-center text-muted",
1900
- compact ? "px-3 py-3 text-xs" : "px-4 py-6 text-sm",
1901
- )}
1902
- >
1903
- {isLoading ? <LoadingText label={labels.loading} /> : (empty ?? labels.empty)}
1904
- </li>
1905
- )}
1906
- {/* Endless-scroll sentinel: observed by IntersectionObserver to pull in
1907
- the next chunk as it nears the viewport (feedback #232). */}
1908
- {canRevealMoreMobile && (
1909
- <li
1910
- ref={loadMoreRef}
1911
- className="px-4 py-4 text-center text-xs text-placeholder"
1912
- >
1913
- {/* Isolated for the reason spelled out on LoadingText. */}
1914
- <bdi>{labels.loading}</bdi>
1915
- </li>
1825
+ {(!serverRows || onFiltersChange) && (
1826
+ <MobileFilters
1827
+ columns={columns}
1828
+ filters={filters}
1829
+ selectOptionsByKey={selectOptionsByKey}
1830
+ isServer={serverRows}
1831
+ hasFilterCallback={!!onFiltersChange}
1832
+ onSetFilter={setFilterValue}
1833
+ onClearFilter={clearFilter}
1834
+ onClearAll={clearAllFilters}
1835
+ labels={labels}
1836
+ locale={locale}
1837
+ />
1916
1838
  )}
1917
- {/* The owner's next slice (0.48), once every row held is revealed. */}
1918
- {loadMore && !canRevealMoreMobile && (
1919
- <DataTableLoadMoreFooter
1920
- as="li"
1921
- loadMore={loadMore}
1922
- rowCount={sorted.length}
1839
+ {mobileSort && (
1840
+ <MobileSort
1841
+ columns={visibleColumns.filter((c) => (!serverRows || !!onSortsChange) && !!c.sortBy)}
1842
+ sorts={sorts}
1843
+ sortCycle={sortCycle}
1844
+ compact={compact}
1923
1845
  labels={labels}
1846
+ onPick={(key) => {
1847
+ if (key === null) {
1848
+ if (sorts.length > 0) commitSorts([], sorts[0].key);
1849
+ return;
1850
+ }
1851
+ if (sorts[0]?.key === key) return;
1852
+ // A newly picked column starts where its header's first click would.
1853
+ const col = columns.find((c) => c.key === key);
1854
+ commitSorts([{ key, dir: col?.firstSort ?? "asc" }], key);
1855
+ }}
1856
+ onFlip={() => {
1857
+ if (sorts.length === 0) return;
1858
+ commitSorts(
1859
+ sorts.map((s, i) => (i === 0 ? { ...s, dir: flipDir(s.dir) } : s)),
1860
+ sorts[0].key,
1861
+ );
1862
+ }}
1863
+ />
1864
+ )}
1865
+ {selection && (
1866
+ <MobileSelectBar
1867
+ active={phoneSelecting}
1868
+ allSelected={selection.allSelected}
1869
+ someSelected={selection.someSelected}
1924
1870
  compact={compact}
1871
+ labels={labels}
1872
+ onEnter={() => setPhoneSelectMode(true)}
1873
+ onToggleAll={selection.onToggleAll}
1874
+ onCancel={() => {
1875
+ setPhoneSelectMode(false);
1876
+ if (anySelected) selection.onToggleAll(false);
1877
+ }}
1925
1878
  />
1926
1879
  )}
1927
- </ul>
1928
- {/* The phone's totals: a summary card after the list rather than one more
1880
+ <ul
1881
+ ref={phoneListRef}
1882
+ className={cn(
1883
+ "divide-y divide-subtle",
1884
+ // Under `fillHeight` the list takes the room its parent gives it, and in a
1885
+ // BOUNDED parent it is the scroller, as the table body is on a wide screen:
1886
+ // the filter button stays above it and a server pager below. Only then —
1887
+ // see `phoneListScrolls` (live #420). The endless-scroll sentinel still
1888
+ // fires in here — an IntersectionObserver on the viewport sees through the
1889
+ // clipping ancestor.
1890
+ fillHeight && "min-h-0 flex-1",
1891
+ fillHeight && phoneListScrolls && "overflow-y-auto overscroll-contain",
1892
+ // Same busy treatment as the desktop body; see `isLoading` below.
1893
+ isLoading && mobileSlice.length > 0 && "opacity-60 transition-opacity",
1894
+ )}
1895
+ aria-busy={isLoading || undefined}
1896
+ >
1897
+ {mobileGroups
1898
+ ? mobileGroups.map((g) => (
1899
+ <Fragment key={`hb-group:${g.key}`}>
1900
+ <li className="sticky top-0 z-10 flex flex-wrap items-baseline justify-between gap-x-3 bg-surface-2 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-muted backdrop-blur">
1901
+ <span className="min-w-0">
1902
+ {mobileGroupLabel
1903
+ ? mobileGroupLabel(g.key)
1904
+ : mobileLevel?.label
1905
+ ? mobileLevel.label(g.key, g.rows)
1906
+ : g.key}
1907
+ </span>
1908
+ {mobileLevel?.end && (
1909
+ <span className="ms-auto tabular-nums">{mobileLevel.end(g.key, g.rows)}</span>
1910
+ )}
1911
+ </li>
1912
+ {g.rows.map(renderMobileRow)}
1913
+ </Fragment>
1914
+ ))
1915
+ : mobileSlice.map(renderMobileRow)}
1916
+ {mobileSlice.length === 0 && (
1917
+ <li className={cn("text-center text-muted", compact ? "px-3 py-3 text-xs" : "px-4 py-6 text-sm")}>
1918
+ {isLoading ? <LoadingText label={labels.loading} /> : (empty ?? labels.empty)}
1919
+ </li>
1920
+ )}
1921
+ {/* Endless-scroll sentinel: observed by IntersectionObserver to pull in
1922
+ the next chunk as it nears the viewport (feedback #232). */}
1923
+ {canRevealMoreMobile && (
1924
+ <li ref={loadMoreRef} className="px-4 py-4 text-center text-xs text-placeholder">
1925
+ {/* Isolated for the reason spelled out on LoadingText. */}
1926
+ <bdi>{labels.loading}</bdi>
1927
+ </li>
1928
+ )}
1929
+ {/* The owner's next slice (0.48), once every row held is revealed. */}
1930
+ {loadMore && !canRevealMoreMobile && (
1931
+ <DataTableLoadMoreFooter
1932
+ as="li"
1933
+ loadMore={loadMore}
1934
+ rowCount={sorted.length}
1935
+ labels={labels}
1936
+ compact={compact}
1937
+ />
1938
+ )}
1939
+ </ul>
1940
+ {/* The phone's totals: a summary card after the list rather than one more
1929
1941
  `<li>` in it. The list reveals rows in chunks as it is scrolled, so a last
1930
1942
  item would sit mid-list until the end was reached; outside it, and under
1931
1943
  `fillHeight` outside the scroller too, the totals stay in view the way the
1932
1944
  sticky `<tfoot>` keeps them in view on a wide screen. Named by
1933
1945
  `footerLabel` so it is announced as what it is, not as a stray list of
1934
1946
  numbers; `mobileHidden` columns stay hidden here as on the cards. */}
1935
- {showFooter && mobileColumns.some((c) => c.footer) && (
1936
- <section
1937
- data-table-footer=""
1938
- aria-labelledby={footerLabel != null ? footerHeadingId : undefined}
1939
- className={cn(
1940
- "border-t-2 border-strong bg-surface-2",
1941
- compact ? "px-3 py-2" : "px-4 py-3",
1942
- isLoading && "opacity-60 transition-opacity",
1943
- )}
1944
- >
1945
- {footerLabel != null && (
1946
- <div id={footerHeadingId} className={cn("font-semibold", compact ? "mb-1 text-sm" : "mb-2")}>
1947
- {footerLabel}
1948
- </div>
1949
- )}
1950
- <dl
1947
+ {showFooter && mobileColumns.some((c) => c.footer) && (
1948
+ <section
1949
+ data-table-footer=""
1950
+ aria-labelledby={footerLabel != null ? footerHeadingId : undefined}
1951
1951
  className={cn(
1952
- "grid grid-cols-[auto_1fr] gap-x-3",
1953
- compact ? "gap-y-0.5 text-xs" : "gap-y-1 text-sm",
1952
+ "border-t-2 border-strong bg-surface-2",
1953
+ compact ? "px-3 py-2" : "px-4 py-3",
1954
+ isLoading && "opacity-60 transition-opacity",
1954
1955
  )}
1955
1956
  >
1956
- {mobileColumns
1957
- .filter((c) => c.footer)
1958
- .map((col) => (
1959
- <Fragment key={col.key}>
1960
- <dt className="self-center text-xs uppercase tracking-wide text-muted">
1961
- {col.header}
1962
- </dt>
1963
- <dd className="min-w-0 self-center font-semibold text-primary">
1964
- {footerValue(col)}
1965
- </dd>
1966
- </Fragment>
1967
- ))}
1968
- </dl>
1969
- </section>
1970
- )}
1971
- {/* Client-side mobile lists scroll endlessly (sentinel above); only
1957
+ {footerLabel != null && (
1958
+ <div id={footerHeadingId} className={cn("font-semibold", compact ? "mb-1 text-sm" : "mb-2")}>
1959
+ {footerLabel}
1960
+ </div>
1961
+ )}
1962
+ <dl
1963
+ className={cn("grid grid-cols-[auto_1fr] gap-x-3", compact ? "gap-y-0.5 text-xs" : "gap-y-1 text-sm")}
1964
+ >
1965
+ {mobileColumns
1966
+ .filter((c) => c.footer)
1967
+ .map((col) => (
1968
+ <Fragment key={col.key}>
1969
+ <dt className="self-center text-xs uppercase tracking-wide text-muted">{col.header}</dt>
1970
+ <dd className="min-w-0 self-center font-semibold text-primary">{footerValue(col)}</dd>
1971
+ </Fragment>
1972
+ ))}
1973
+ </dl>
1974
+ </section>
1975
+ )}
1976
+ {/* Client-side mobile lists scroll endlessly (sentinel above); only
1972
1977
  server-paginated tables keep the pager here. */}
1973
- {isServer && !loadMore && (
1974
- <Pagination
1975
- page={safePage}
1976
- totalPages={totalPages}
1977
- pageSize={paginationPageSize}
1978
- total={paginationTotal}
1979
- onPage={goToPage}
1980
- onPageSize={serverPagination!.onPageSizeChange}
1981
- labels={labels}
1982
- locale={locale}
1983
- density={density}
1984
- />
1985
- )}
1986
- {/* The row's own first column is this dialog's title — the same cell the card
1978
+ {isServer && !loadMore && (
1979
+ <Pagination
1980
+ page={safePage}
1981
+ totalPages={totalPages}
1982
+ pageSize={paginationPageSize}
1983
+ total={paginationTotal}
1984
+ onPage={goToPage}
1985
+ onPageSize={serverPagination!.onPageSizeChange}
1986
+ labels={labels}
1987
+ locale={locale}
1988
+ density={density}
1989
+ />
1990
+ )}
1991
+ {/* The row's own first column is this dialog's title — the same cell the card
1987
1992
  behind it shows, so the panel names the row it opened from. */}
1988
- <FullBleedDialog
1989
- open={dialogOpen}
1990
- onClose={closeDialog}
1991
- closeLabel={labels.close}
1992
- header={mobileDialogRow ? mobilePrimaryCol?.cell(mobileDialogRow) : null}
1993
- backCloses={mobileDialogBackCloses}
1994
- >
1995
- {mobileDialogContent}
1996
- </FullBleedDialog>
1997
- </div>
1993
+ <FullBleedDialog
1994
+ open={dialogOpen}
1995
+ onClose={closeDialog}
1996
+ closeLabel={labels.close}
1997
+ header={mobileDialogRow ? mobilePrimaryCol?.cell(mobileDialogRow) : null}
1998
+ backCloses={mobileDialogBackCloses}
1999
+ >
2000
+ {mobileDialogContent}
2001
+ </FullBleedDialog>
2002
+ </div>
1998
2003
  )}
1999
2004
  {isMdUp && (
2000
- <div className={cn("flex", fillHeight && "flex-1")}>
2001
- {/* Under `fillHeight` neither wrapper is `min-h-0`: a flex item's automatic
2005
+ <div className={cn("flex", fillHeight && "flex-1")}>
2006
+ {/* Under `fillHeight` neither wrapper is `min-h-0`: a flex item's automatic
2002
2007
  minimum is its content's, and the content's height counts the body at its
2003
2008
  basis (`basis-48`, below), not at its rows — so the floor carries up. */}
2004
- <div className={cn("relative min-w-0 flex-1", fillHeight && "flex flex-col")}>
2005
- {/* scrollbar-gutter:stable reserves the vertical-scrollbar space up
2009
+ <div className={cn("relative min-w-0 flex-1", fillHeight && "flex flex-col")}>
2010
+ {/* scrollbar-gutter:stable reserves the vertical-scrollbar space up
2006
2011
  front. Expanding a row adds height, which can bring the scrollbar
2007
2012
  in, which narrows the content box — and in an `auto` table layout
2008
2013
  that re-computes every column width. Reserving the gutter is the
2009
2014
  other half of the `w-0 min-w-full` fix on the expansion cell below
2010
2015
  (feedback #104: "expanding an item resizes the columns"). */}
2011
- <div
2012
- ref={desktopScroller}
2013
- // The scroller: marked for the Tooltip's auto-portal (see the root above).
2014
- data-clips=""
2015
- // Under `fillHeight` the body grows into the room from a 12rem basis (0.40,
2016
- // §1.3): about five rows is its floor. A window too short for the page's
2017
- // header and that much body scrolls `<main>` instead (keksdose's review).
2018
- className={cn("overflow-auto [scrollbar-gutter:stable]", fillHeight && "min-h-0 grow basis-48")}
2019
- // `edgeFade`: the mask, `data-overflow` and the focus handling; nothing
2020
- // while off. The height bound is merged over the mask, not replaced by it.
2021
- {...edgeFadeProps}
2022
- style={
2023
- fillHeight
2024
- ? edgeFadeProps.style
2025
- : { ...edgeFadeProps.style, maxHeight: maxBodyHeight }
2026
- }
2027
- >
2028
- {/* A table with no name is "table" in a screen reader's list of tables, and
2016
+ <div
2017
+ ref={desktopScroller}
2018
+ // The scroller: marked for the Tooltip's auto-portal (see the root above).
2019
+ data-clips=""
2020
+ // Under `fillHeight` the body grows into the room from a 12rem basis (0.40,
2021
+ // §1.3): about five rows is its floor. A window too short for the page's
2022
+ // header and that much body scrolls `<main>` instead (keksdose's review).
2023
+ className={cn("overflow-auto [scrollbar-gutter:stable]", fillHeight && "min-h-0 grow basis-48")}
2024
+ // `edgeFade`: the mask, `data-overflow` and the focus handling; nothing
2025
+ // while off. The height bound is merged over the mask, not replaced by it.
2026
+ {...edgeFadeProps}
2027
+ style={fillHeight ? edgeFadeProps.style : { ...edgeFadeProps.style, maxHeight: maxBodyHeight }}
2028
+ >
2029
+ {/* A table with no name is "table" in a screen reader's list of tables, and
2029
2030
  an app renders several. `labels.table` is how a call site says which. */}
2030
- {/* `aria-busy` while a server page is in flight: a reader holds off announcing
2031
+ {/* `aria-busy` while a server page is in flight: a reader holds off announcing
2031
2032
  the rows that are about to be replaced, and the dimmed body says the same
2032
2033
  to the eye. The pager stays live — see `ServerPagination.isLoading`. */}
2033
- <table
2034
- ref={tableRef}
2035
- className={cn("w-full", compact ? "text-xs" : "text-sm")}
2036
- data-fit-grow={growDrawn ? "" : undefined}
2037
- aria-label={labels.table}
2038
- aria-busy={isLoading || undefined}
2039
- // `virtualize` (0.48.2): every row counted, rendered or not.
2040
- aria-rowcount={rowWindow?.rowCount}
2041
- data-virtualized={rowWindow ? "" : undefined}
2042
- >
2043
- {/* The locked column widths (0.48.2, `virtualize`): rows coming and going no
2034
+ <table
2035
+ ref={tableRef}
2036
+ className={cn("w-full", compact ? "text-xs" : "text-sm")}
2037
+ data-fit-grow={growDrawn ? "" : undefined}
2038
+ aria-label={labels.table}
2039
+ aria-busy={isLoading || undefined}
2040
+ // `virtualize` (0.48.2): every row counted, rendered or not.
2041
+ aria-rowcount={rowWindow?.rowCount}
2042
+ data-virtualized={rowWindow ? "" : undefined}
2043
+ >
2044
+ {/* The locked column widths (0.48.2, `virtualize`): rows coming and going no
2044
2045
  longer move the columns. */}
2045
- {rowWindow && (
2046
- <colgroup>
2047
- {virtualColKeys.map((key) => {
2048
- const w = rowWindow.colWidths?.[key];
2049
- return <col key={key} style={w !== undefined ? { width: w } : undefined} />;
2050
- })}
2051
- </colgroup>
2052
- )}
2053
- {/* Sticky header. position:sticky pins to the nearest scroll-container
2046
+ {rowWindow && (
2047
+ <colgroup>
2048
+ {virtualColKeys.map((key) => {
2049
+ const w = rowWindow.colWidths?.[key];
2050
+ return <col key={key} style={w !== undefined ? { width: w } : undefined} />;
2051
+ })}
2052
+ </colgroup>
2053
+ )}
2054
+ {/* Sticky header. position:sticky pins to the nearest scroll-container
2054
2055
  ancestor — so the header can only stick to THIS wrapper, never the
2055
2056
  page. For that to actually hold the header in place, the wrapper
2056
2057
  must be the thing that scrolls vertically: hence overflow-auto +
@@ -2059,288 +2060,283 @@ export function DataTable<T>({
2059
2060
  header then stays put as you scroll the rows. position:sticky on
2060
2061
  <thead> isn't reliable across browsers, so we put it on each <th>
2061
2062
  (see DataTableHead, data-table-head.tsx). */}
2062
- <DataTableHead
2063
- visibleColumns={visibleColumns}
2064
- selection={selection}
2065
- compact={compact}
2066
- labels={labels}
2067
- locale={locale}
2068
- isServer={serverRows}
2069
- hasSortCallback={!!onSortsChange}
2070
- hasFilterCallback={!!onFiltersChange}
2071
- sorts={sorts}
2072
- filters={filters}
2073
- selectOptionsByKey={selectOptionsByKey}
2074
- multiSort={multiSort}
2075
- resizable={resizable}
2076
- widths={widths}
2077
- setWidths={setWidths}
2078
- headRefs={headRefs}
2079
- toggleSort={toggleSort}
2080
- setFilterValue={setFilterValue}
2081
- clearFilter={clearFilter}
2082
- startResize={startResize}
2083
- moveResize={moveResize}
2084
- finishResize={finishResize}
2085
- ariaRowIndex={rowWindow ? 1 : undefined}
2086
- lockedWidths={rowWindow?.colWidths}
2087
- selectionLockKey={VIRTUAL_SELECT_COL}
2088
- />
2089
- {(() => {
2090
- const bodyClass = cn(isLoading && slice.length > 0 && "opacity-60 transition-opacity");
2091
- const leading = leadingRow ? (
2092
- <DataTableLeadingRow
2093
- colSpan={totalColSpan}
2094
- sticky={leadingRowSticky}
2095
- ariaRowIndex={rowWindow ? 2 : undefined}
2096
- >
2097
- {leadingRow}
2098
- </DataTableLeadingRow>
2099
- ) : null;
2100
- // One memoised row each (0.48.2, K-052-2; data-table-row.tsx): the table
2101
- // derives each row's own inputs here, as primitives, so a tick re-renders
2102
- // only the rows whose inputs changed.
2103
- const renderRow = (row: T, rowIndex: number) => {
2104
- const expanded = isExpanded?.(row) ?? false;
2105
- const key = rowKey(row);
2106
- return (
2107
- <DataTableRow<T>
2108
- key={key}
2109
- row={row}
2110
- rowIndex={rowIndex}
2111
- rowKey={key}
2112
- ctx={rowCtx}
2113
- columns={visibleColumns}
2114
- widths={widths}
2115
- growDrawn={growDrawn}
2116
- linkColumn={linkColumn}
2117
- href={rowHref?.(row)}
2118
- selectionColumn={!!selection}
2119
- selectable={canSelect(row)}
2120
- selected={!!selection && selection.isSelected(row)}
2121
- expanded={expanded}
2122
- expansion={expanded ? expandedRow?.(row) : null}
2123
- disclosure={rowsFocusable && !!expandedRow}
2124
- detailId={`${detailIdBase}-${rowIndex}`}
2125
- rowsFocusable={rowsFocusable}
2126
- rowInteractive={!!onRowClick || !!selection}
2127
- tabbable={key === tabRowKey}
2128
- className={rowClassName?.(row)}
2129
- attrs={rowAttributes?.(row)}
2063
+ <DataTableHead
2064
+ visibleColumns={visibleColumns}
2065
+ selection={selection}
2130
2066
  compact={compact}
2131
- totalColSpan={totalColSpan}
2132
- rowDetailsLabel={labels.rowDetails}
2133
- selectRowLabel={labels.selectRow}
2134
- ariaRowIndex={rowWindow?.ariaRow(rowIndex)}
2067
+ labels={labels}
2068
+ locale={locale}
2069
+ isServer={serverRows}
2070
+ hasSortCallback={!!onSortsChange}
2071
+ hasFilterCallback={!!onFiltersChange}
2072
+ sorts={sorts}
2073
+ filters={filters}
2074
+ selectOptionsByKey={selectOptionsByKey}
2075
+ multiSort={multiSort}
2076
+ resizable={resizable}
2077
+ widths={widths}
2078
+ setWidths={setWidths}
2079
+ headRefs={headRefs}
2080
+ toggleSort={toggleSort}
2081
+ setFilterValue={setFilterValue}
2082
+ clearFilter={clearFilter}
2083
+ startResize={startResize}
2084
+ moveResize={moveResize}
2085
+ finishResize={finishResize}
2086
+ ariaRowIndex={rowWindow ? 1 : undefined}
2087
+ lockedWidths={rowWindow?.colWidths}
2088
+ selectionLockKey={VIRTUAL_SELECT_COL}
2135
2089
  />
2136
- );
2137
- };
2138
- const emptyRow =
2139
- slice.length === 0 ? (
2140
- <tr>
2141
- <td
2142
- colSpan={totalColSpan}
2143
- className={cn("text-center text-muted", compact ? "px-2 py-2" : "px-3 py-4")}
2144
- >
2145
- {/* Nothing is not the same as not-yet: "no results" while the first
2090
+ {(() => {
2091
+ const bodyClass = cn(isLoading && slice.length > 0 && "opacity-60 transition-opacity");
2092
+ const leading = leadingRow ? (
2093
+ <DataTableLeadingRow
2094
+ colSpan={totalColSpan}
2095
+ sticky={leadingRowSticky}
2096
+ ariaRowIndex={rowWindow ? 2 : undefined}
2097
+ >
2098
+ {leadingRow}
2099
+ </DataTableLeadingRow>
2100
+ ) : null;
2101
+ // One memoised row each (0.48.2, K-052-2; data-table-row.tsx): the table
2102
+ // derives each row's own inputs here, as primitives, so a tick re-renders
2103
+ // only the rows whose inputs changed.
2104
+ const renderRow = (row: T, rowIndex: number) => {
2105
+ const expanded = isExpanded?.(row) ?? false;
2106
+ const key = rowKey(row);
2107
+ return (
2108
+ <DataTableRow<T>
2109
+ key={key}
2110
+ row={row}
2111
+ rowIndex={rowIndex}
2112
+ rowKey={key}
2113
+ ctx={rowCtx}
2114
+ columns={visibleColumns}
2115
+ widths={widths}
2116
+ growDrawn={growDrawn}
2117
+ linkColumn={linkColumn}
2118
+ href={rowHref?.(row)}
2119
+ selectionColumn={!!selection}
2120
+ selectable={canSelect(row)}
2121
+ selected={!!selection && selection.isSelected(row)}
2122
+ expanded={expanded}
2123
+ expansion={expanded ? expandedRow?.(row) : null}
2124
+ disclosure={rowsFocusable && !!expandedRow}
2125
+ detailId={`${detailIdBase}-${rowIndex}`}
2126
+ rowsFocusable={rowsFocusable}
2127
+ rowInteractive={!!onRowClick || !!selection}
2128
+ tabbable={key === tabRowKey}
2129
+ className={rowClassName?.(row)}
2130
+ attrs={rowAttributes?.(row)}
2131
+ compact={compact}
2132
+ totalColSpan={totalColSpan}
2133
+ rowDetailsLabel={labels.rowDetails}
2134
+ selectRowLabel={labels.selectRow}
2135
+ ariaRowIndex={rowWindow?.ariaRow(rowIndex)}
2136
+ />
2137
+ );
2138
+ };
2139
+ const emptyRow =
2140
+ slice.length === 0 ? (
2141
+ <tr>
2142
+ <td
2143
+ colSpan={totalColSpan}
2144
+ className={cn("text-center text-muted", compact ? "px-2 py-2" : "px-3 py-4")}
2145
+ >
2146
+ {/* Nothing is not the same as not-yet: "no results" while the first
2146
2147
  page is still in flight is a claim the table cannot make. */}
2147
- {isLoading ? <LoadingText label={labels.loading} /> : (empty ?? labels.empty)}
2148
- </td>
2149
- </tr>
2150
- ) : null;
2151
- const band = (
2152
- level: 1 | 2,
2153
- def: DataTableGroupBy<T>,
2154
- g: { key: string; rows: T[] },
2155
- ariaRowIndex?: number,
2156
- ) => (
2157
- <DataTableGroupBand
2158
- level={level}
2159
- colSpan={totalColSpan}
2160
- top={level === 1 ? bandTops[0] : bandTops[1]}
2161
- compact={compact}
2162
- label={def.label ? def.label(g.key, g.rows) : g.key}
2163
- end={def.end?.(g.key, g.rows)}
2164
- ariaRowIndex={ariaRowIndex}
2165
- />
2166
- );
2167
- if (rowWindow) {
2168
- // Windowed (0.48.2): each group's own `<tbody>` with its bands and the
2169
- // rendered rows, spacer rows between; one spacer `<tbody>` per run of groups
2170
- // with nothing rendered. Spacers are hidden from the accessibility tree.
2171
- const spacer = (key: string, height: number) => (
2172
- <tr key={key} aria-hidden="true" data-vt-spacer="">
2173
- <td colSpan={totalColSpan} style={{ height, padding: 0, border: 0 }} />
2174
- </tr>
2175
- );
2176
- return (
2177
- <>
2178
- {leading && <tbody className={bodyClass}>{leading}</tbody>}
2179
- {rowWindow.bodies.map((b) => {
2180
- if (b.kind === "spacer")
2181
- return (
2182
- <tbody key={b.key} data-vt-body="" aria-hidden="true">
2183
- {spacer("s", b.height)}
2184
- </tbody>
2185
- );
2186
- const g = virtualGroups[b.group];
2187
- const vb = virtualBands[b.group];
2148
+ {isLoading ? <LoadingText label={labels.loading} /> : (empty ?? labels.empty)}
2149
+ </td>
2150
+ </tr>
2151
+ ) : null;
2152
+ const band = (
2153
+ level: 1 | 2,
2154
+ def: DataTableGroupBy<T>,
2155
+ g: { key: string; rows: T[] },
2156
+ ariaRowIndex?: number,
2157
+ ) => (
2158
+ <DataTableGroupBand
2159
+ level={level}
2160
+ colSpan={totalColSpan}
2161
+ top={level === 1 ? bandTops[0] : bandTops[1]}
2162
+ compact={compact}
2163
+ label={def.label ? def.label(g.key, g.rows) : g.key}
2164
+ end={def.end?.(g.key, g.rows)}
2165
+ ariaRowIndex={ariaRowIndex}
2166
+ />
2167
+ );
2168
+ if (rowWindow) {
2169
+ // Windowed (0.48.2): each group's own `<tbody>` with its bands and the
2170
+ // rendered rows, spacer rows between; one spacer `<tbody>` per run of groups
2171
+ // with nothing rendered. Spacers are hidden from the accessibility tree.
2172
+ const spacer = (key: string, height: number) => (
2173
+ <tr key={key} aria-hidden="true" data-vt-spacer="">
2174
+ <td colSpan={totalColSpan} style={{ height, padding: 0, border: 0 }} />
2175
+ </tr>
2176
+ );
2188
2177
  return (
2189
- <tbody
2190
- key={vb ? `vg:${vb.g1.key}:${vb.g2?.key ?? ""}:${g.start}` : "vg"}
2191
- data-vt-body=""
2192
- className={bodyClass}
2193
- >
2194
- {vb && g.bands.includes(1) && band(1, levels[0], vb.g1, rowWindow.ariaBand(b.group, 1))}
2195
- {vb?.g2 && band(2, levels[1], vb.g2, rowWindow.ariaBand(b.group, 2))}
2196
- {b.items.map((it) =>
2197
- it.kind === "gap" ? spacer(it.key, it.height) : renderRow(slice[it.index], it.index),
2198
- )}
2199
- </tbody>
2178
+ <>
2179
+ {leading && <tbody className={bodyClass}>{leading}</tbody>}
2180
+ {rowWindow.bodies.map((b) => {
2181
+ if (b.kind === "spacer")
2182
+ return (
2183
+ <tbody key={b.key} data-vt-body="" aria-hidden="true">
2184
+ {spacer("s", b.height)}
2185
+ </tbody>
2186
+ );
2187
+ const g = virtualGroups[b.group];
2188
+ const vb = virtualBands[b.group];
2189
+ return (
2190
+ <tbody
2191
+ key={vb ? `vg:${vb.g1.key}:${vb.g2?.key ?? ""}:${g.start}` : "vg"}
2192
+ data-vt-body=""
2193
+ className={bodyClass}
2194
+ >
2195
+ {vb && g.bands.includes(1) && band(1, levels[0], vb.g1, rowWindow.ariaBand(b.group, 1))}
2196
+ {vb?.g2 && band(2, levels[1], vb.g2, rowWindow.ariaBand(b.group, 2))}
2197
+ {b.items.map((it) =>
2198
+ it.kind === "gap" ? spacer(it.key, it.height) : renderRow(slice[it.index], it.index),
2199
+ )}
2200
+ </tbody>
2201
+ );
2202
+ })}
2203
+ </>
2200
2204
  );
2201
- })}
2202
- </>
2203
- );
2204
- }
2205
- if (!desktopGroups) {
2206
- return (
2207
- <tbody className={bodyClass}>
2208
- {leading}
2209
- {slice.map(renderRow)}
2210
- {emptyRow}
2211
- </tbody>
2212
- );
2213
- }
2214
- // Grouped (0.48, keksdose dev #605): one `<tbody>` per innermost group, its
2215
- // band the row header; the leading row (and the empty state) in their own
2216
- // before the first group.
2217
- const rowsOf = (g: { rows: T[]; start: number }) => g.rows.map((r, i) => renderRow(r, g.start + i));
2218
- return (
2219
- <>
2220
- {(leading || emptyRow) && (
2221
- <tbody className={bodyClass}>
2222
- {leading}
2223
- {emptyRow}
2224
- </tbody>
2225
- )}
2226
- {desktopGroups.map((g1) =>
2227
- g1.children ? (
2228
- g1.children.map((g2, j) => (
2229
- <tbody key={`g:${g1.key}:${g2.key}:${g2.start}`} className={bodyClass}>
2230
- {j === 0 && band(1, levels[0], g1)}
2231
- {band(2, levels[1], g2)}
2232
- {rowsOf(g2)}
2205
+ }
2206
+ if (!desktopGroups) {
2207
+ return (
2208
+ <tbody className={bodyClass}>
2209
+ {leading}
2210
+ {slice.map(renderRow)}
2211
+ {emptyRow}
2233
2212
  </tbody>
2234
- ))
2235
- ) : (
2236
- <tbody key={`g:${g1.key}:${g1.start}`} className={bodyClass}>
2237
- {band(1, levels[0], g1)}
2238
- {rowsOf(g1)}
2239
- </tbody>
2240
- ),
2241
- )}
2242
- </>
2243
- );
2244
- })()}
2245
- {showFooter && (
2246
- // Sticky to the scroller's bottom edge for the same reason the header is
2247
- // sticky to its top: the body scrolls inside a bounded wrapper, and a
2248
- // total that scrolls away with the last row is a total nobody sees on a
2249
- // 25-row page. Each cell carries its own background and its own `sticky`,
2250
- // as the header's do — `position: sticky` on a `<tfoot>` is not reliable.
2251
- <tfoot
2252
- data-table-footer=""
2253
- className={cn(
2254
- "font-semibold text-primary",
2255
- isLoading && "opacity-60 transition-opacity",
2256
- )}
2257
- >
2258
- <tr aria-rowindex={rowWindow?.rowCount}>
2259
- {/* The selection column has nothing to total: an empty cell keeps the
2260
- values under their own headers. */}
2261
- {selection && (
2262
- <td
2263
- className={cn(
2264
- FOOTER_CELL,
2265
- compact ? "w-8 px-2 py-1" : "w-10 px-3 py-2",
2266
- )}
2267
- />
2268
- )}
2269
- {visibleColumns.map((col) => {
2270
- const width = widths[col.key];
2271
- const pinned = width ? { width, minWidth: width, maxWidth: width } : undefined;
2272
- const isLabel = col === footerLabelCol;
2273
- const Cell = isLabel ? "th" : "td";
2213
+ );
2214
+ }
2215
+ // Grouped (0.48, keksdose dev #605): one `<tbody>` per innermost group, its
2216
+ // band the row header; the leading row (and the empty state) in their own
2217
+ // before the first group.
2218
+ const rowsOf = (g: { rows: T[]; start: number }) => g.rows.map((r, i) => renderRow(r, g.start + i));
2274
2219
  return (
2275
- <Cell
2276
- key={col.key}
2277
- data-col={col.key}
2278
- scope={isLabel ? "row" : undefined}
2279
- style={pinned}
2280
- className={cn(
2281
- FOOTER_CELL,
2282
- "align-top",
2283
- compact ? "px-2 py-1" : "px-3 py-2",
2284
- width && "overflow-hidden text-ellipsis",
2285
- // A `<th>` centres by default; the label reads from the start
2286
- // like the cells above it, unless the column says otherwise.
2287
- isLabel && "text-start",
2288
- col.grow ? GROW_CELL_CLASS : growDrawn && GROW_PEER_CELL_CLASS,
2289
- logicalAlign(col.className),
2220
+ <>
2221
+ {(leading || emptyRow) && (
2222
+ <tbody className={bodyClass}>
2223
+ {leading}
2224
+ {emptyRow}
2225
+ </tbody>
2290
2226
  )}
2291
- >
2292
- {col.footer ? footerValue(col) : isLabel ? footerLabel : null}
2293
- </Cell>
2227
+ {desktopGroups.map((g1) =>
2228
+ g1.children ? (
2229
+ g1.children.map((g2, j) => (
2230
+ <tbody key={`g:${g1.key}:${g2.key}:${g2.start}`} className={bodyClass}>
2231
+ {j === 0 && band(1, levels[0], g1)}
2232
+ {band(2, levels[1], g2)}
2233
+ {rowsOf(g2)}
2234
+ </tbody>
2235
+ ))
2236
+ ) : (
2237
+ <tbody key={`g:${g1.key}:${g1.start}`} className={bodyClass}>
2238
+ {band(1, levels[0], g1)}
2239
+ {rowsOf(g1)}
2240
+ </tbody>
2241
+ ),
2242
+ )}
2243
+ </>
2294
2244
  );
2295
- })}
2296
- </tr>
2297
- </tfoot>
2298
- )}
2299
- </table>
2300
- {/* In the scroller, after the rows (0.48): it comes into view as the last row
2245
+ })()}
2246
+ {showFooter && (
2247
+ // Sticky to the scroller's bottom edge for the same reason the header is
2248
+ // sticky to its top: the body scrolls inside a bounded wrapper, and a
2249
+ // total that scrolls away with the last row is a total nobody sees on a
2250
+ // 25-row page. Each cell carries its own background and its own `sticky`,
2251
+ // as the header's do — `position: sticky` on a `<tfoot>` is not reliable.
2252
+ <tfoot
2253
+ data-table-footer=""
2254
+ className={cn("font-semibold text-primary", isLoading && "opacity-60 transition-opacity")}
2255
+ >
2256
+ <tr aria-rowindex={rowWindow?.rowCount}>
2257
+ {/* The selection column has nothing to total: an empty cell keeps the
2258
+ values under their own headers. */}
2259
+ {selection && <td className={cn(FOOTER_CELL, compact ? "w-8 px-2 py-1" : "w-10 px-3 py-2")} />}
2260
+ {visibleColumns.map((col) => {
2261
+ const width = widths[col.key];
2262
+ const pinned = width ? { width, minWidth: width, maxWidth: width } : undefined;
2263
+ const isLabel = col === footerLabelCol;
2264
+ const Cell = isLabel ? "th" : "td";
2265
+ return (
2266
+ <Cell
2267
+ key={col.key}
2268
+ data-col={col.key}
2269
+ scope={isLabel ? "row" : undefined}
2270
+ style={pinned}
2271
+ className={cn(
2272
+ FOOTER_CELL,
2273
+ "align-top",
2274
+ compact ? "px-2 py-1" : "px-3 py-2",
2275
+ width && "overflow-hidden text-ellipsis",
2276
+ // A `<th>` centres by default; the label reads from the start
2277
+ // like the cells above it, unless the column says otherwise.
2278
+ isLabel && "text-start",
2279
+ col.grow ? GROW_CELL_CLASS : growDrawn && GROW_PEER_CELL_CLASS,
2280
+ logicalAlign(col.className),
2281
+ )}
2282
+ >
2283
+ {col.footer ? footerValue(col) : isLabel ? footerLabel : null}
2284
+ </Cell>
2285
+ );
2286
+ })}
2287
+ </tr>
2288
+ </tfoot>
2289
+ )}
2290
+ </table>
2291
+ {/* In the scroller, after the rows (0.48): it comes into view as the last row
2301
2292
  does, under `fillHeight` too, where the body is the scroller. */}
2302
- {loadMore && (
2303
- <DataTableLoadMoreFooter loadMore={loadMore} rowCount={sorted.length} labels={labels} compact={compact} />
2304
- )}
2305
- </div>
2306
- {!unpaged && !loadMore && (
2307
- <Pagination
2308
- page={safePage}
2309
- totalPages={totalPages}
2310
- pageSize={paginationPageSize}
2311
- total={paginationTotal}
2312
- onPage={goToPage}
2313
- onPageSize={
2314
- isServer
2315
- ? serverPagination!.onPageSizeChange
2316
- : (n) => {
2317
- // To the owner when it holds the page size, as `commitSorts` does.
2318
- if (onPageSizeChange) onPageSizeChange(n);
2319
- else setPageSize(n);
2320
- setPage(0);
2321
- }
2322
- }
2293
+ {loadMore && (
2294
+ <DataTableLoadMoreFooter
2295
+ loadMore={loadMore}
2296
+ rowCount={sorted.length}
2297
+ labels={labels}
2298
+ compact={compact}
2299
+ />
2300
+ )}
2301
+ </div>
2302
+ {!unpaged && !loadMore && (
2303
+ <Pagination
2304
+ page={safePage}
2305
+ totalPages={totalPages}
2306
+ pageSize={paginationPageSize}
2307
+ total={paginationTotal}
2308
+ onPage={goToPage}
2309
+ onPageSize={
2310
+ isServer
2311
+ ? serverPagination!.onPageSizeChange
2312
+ : (n) => {
2313
+ // To the owner when it holds the page size, as `commitSorts` does.
2314
+ if (onPageSizeChange) onPageSizeChange(n);
2315
+ else setPageSize(n);
2316
+ setPage(0);
2317
+ }
2318
+ }
2319
+ labels={labels}
2320
+ locale={locale}
2321
+ density={density}
2322
+ />
2323
+ )}
2324
+ </div>
2325
+ {columnSettings && (
2326
+ <ColumnSettingsPanel
2327
+ columns={columns}
2328
+ hiddenCols={hiddenCols}
2329
+ setHiddenCols={setHiddenCols}
2330
+ autoHidden={autoHidden}
2331
+ keepColumn={keepColumn}
2332
+ showSettings={showSettings}
2333
+ setShowSettings={setShowSettings}
2334
+ columnsCountLabel={columnsCountLabel}
2323
2335
  labels={labels}
2324
- locale={locale}
2325
- density={density}
2336
+ autoSizeAll={autoSizeAll}
2326
2337
  />
2327
2338
  )}
2328
2339
  </div>
2329
- {columnSettings && (
2330
- <ColumnSettingsPanel
2331
- columns={columns}
2332
- hiddenCols={hiddenCols}
2333
- setHiddenCols={setHiddenCols}
2334
- autoHidden={autoHidden}
2335
- keepColumn={keepColumn}
2336
- showSettings={showSettings}
2337
- setShowSettings={setShowSettings}
2338
- columnsCountLabel={columnsCountLabel}
2339
- labels={labels}
2340
- autoSizeAll={autoSizeAll}
2341
- />
2342
- )}
2343
- </div>
2344
2340
  )}
2345
2341
  </Root>
2346
2342
  );