@eifi1/ui-kit 0.54.0 → 0.56.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 (847) hide show
  1. package/README.md +90 -76
  2. package/dist/admin/plan-change.js +2 -2
  3. package/dist/admin/plan-change.js.map +1 -1
  4. package/dist/admin/user-roster.d.ts +6 -0
  5. package/dist/admin/user-roster.js +4 -0
  6. package/dist/admin/user-roster.js.map +1 -1
  7. package/dist/billing/billing-labels.d.ts +26 -0
  8. package/dist/billing/billing-labels.js +9 -0
  9. package/dist/billing/billing-labels.js.map +1 -1
  10. package/dist/billing/subscription-standing.d.ts +61 -0
  11. package/dist/billing/subscription-standing.js +51 -0
  12. package/dist/billing/subscription-standing.js.map +1 -0
  13. package/dist/billing/usage-meter.d.ts +52 -0
  14. package/dist/billing/usage-meter.js +52 -0
  15. package/dist/billing/usage-meter.js.map +1 -0
  16. package/dist/chart.d.ts +1 -0
  17. package/dist/chart.js +4 -0
  18. package/dist/chart.js.map +1 -1
  19. package/dist/components/alert-banner.js +2 -3
  20. package/dist/components/alert-banner.js.map +1 -1
  21. package/dist/components/amount-input.js +3 -15
  22. package/dist/components/amount-input.js.map +1 -1
  23. package/dist/components/autocomplete.js +2 -2
  24. package/dist/components/autocomplete.js.map +1 -1
  25. package/dist/components/bulk-action-bar.js +2 -1
  26. package/dist/components/bulk-action-bar.js.map +1 -1
  27. package/dist/components/button.d.ts +35 -1
  28. package/dist/components/button.js +6 -9
  29. package/dist/components/button.js.map +1 -1
  30. package/dist/components/calendar-heatmap.js +2 -2
  31. package/dist/components/calendar-heatmap.js.map +1 -1
  32. package/dist/components/camera-button.d.ts +89 -0
  33. package/dist/components/camera-button.js +122 -0
  34. package/dist/components/camera-button.js.map +1 -0
  35. package/dist/components/camera-capture.d.ts +66 -0
  36. package/dist/components/camera-capture.js +190 -0
  37. package/dist/components/camera-capture.js.map +1 -0
  38. package/dist/components/camera-labels.d.ts +20 -0
  39. package/dist/components/camera-labels.js +15 -0
  40. package/dist/components/camera-labels.js.map +1 -0
  41. package/dist/components/chart-edge.d.ts +9 -0
  42. package/dist/components/chart-edge.js +14 -3
  43. package/dist/components/chart-edge.js.map +1 -1
  44. package/dist/components/chart-zoom-core.js +34 -29
  45. package/dist/components/chart-zoom-core.js.map +1 -1
  46. package/dist/components/checkbox-group.js +1 -1
  47. package/dist/components/checkbox-group.js.map +1 -1
  48. package/dist/components/combobox-core.js +3 -2
  49. package/dist/components/combobox-core.js.map +1 -1
  50. package/dist/components/combobox.js +2 -2
  51. package/dist/components/combobox.js.map +1 -1
  52. package/dist/components/consent-again-notice-labels.d.ts +25 -0
  53. package/dist/components/consent-again-notice-labels.js +15 -0
  54. package/dist/components/consent-again-notice-labels.js.map +1 -0
  55. package/dist/components/consent-again-notice.d.ts +85 -0
  56. package/dist/components/consent-again-notice.js +94 -0
  57. package/dist/components/consent-again-notice.js.map +1 -0
  58. package/dist/components/country-select.js +2 -7
  59. package/dist/components/country-select.js.map +1 -1
  60. package/dist/components/currency-select.js +2 -2
  61. package/dist/components/currency-select.js.map +1 -1
  62. package/dist/components/danger-confirm.js +2 -2
  63. package/dist/components/danger-confirm.js.map +1 -1
  64. package/dist/components/data-table-column-settings.js +2 -2
  65. package/dist/components/data-table-column-settings.js.map +1 -1
  66. package/dist/components/data-table-fit.js.map +1 -1
  67. package/dist/components/data-table-virtual.js +13 -3
  68. package/dist/components/data-table-virtual.js.map +1 -1
  69. package/dist/components/date-field.js +2 -2
  70. package/dist/components/date-field.js.map +1 -1
  71. package/dist/components/date-picker.js +2 -2
  72. package/dist/components/date-picker.js.map +1 -1
  73. package/dist/components/date-range-picker.js +2 -6
  74. package/dist/components/date-range-picker.js.map +1 -1
  75. package/dist/components/dialog-frame.d.ts +3 -1
  76. package/dist/components/dialog-frame.js.map +1 -1
  77. package/dist/components/dropdown.js +7 -3
  78. package/dist/components/dropdown.js.map +1 -1
  79. package/dist/components/entity-combobox.js +2 -2
  80. package/dist/components/entity-combobox.js.map +1 -1
  81. package/dist/components/field-parts.d.ts +108 -6
  82. package/dist/components/field-parts.js +59 -6
  83. package/dist/components/field-parts.js.map +1 -1
  84. package/dist/components/field-suggestion-labels.d.ts +2 -0
  85. package/dist/components/field-suggestion-labels.js +10 -0
  86. package/dist/components/field-suggestion-labels.js.map +1 -0
  87. package/dist/components/field.js +1 -1
  88. package/dist/components/field.js.map +1 -1
  89. package/dist/components/file-button.d.ts +1 -1
  90. package/dist/components/file-button.js.map +1 -1
  91. package/dist/components/floating-panel.d.ts +7 -6
  92. package/dist/components/floating-panel.js +3 -17
  93. package/dist/components/floating-panel.js.map +1 -1
  94. package/dist/components/form-actions.d.ts +3 -2
  95. package/dist/components/form-actions.js.map +1 -1
  96. package/dist/components/hover-menu.js +3 -2
  97. package/dist/components/hover-menu.js.map +1 -1
  98. package/dist/components/icon-button.d.ts +23 -5
  99. package/dist/components/icon-button.js +7 -8
  100. package/dist/components/icon-button.js.map +1 -1
  101. package/dist/components/inline-confirm.js +2 -1
  102. package/dist/components/inline-confirm.js.map +1 -1
  103. package/dist/components/inline-entity-combobox.js +2 -2
  104. package/dist/components/inline-entity-combobox.js.map +1 -1
  105. package/dist/components/input.js +2 -2
  106. package/dist/components/input.js.map +1 -1
  107. package/dist/components/jump-calendar.js +3 -3
  108. package/dist/components/jump-calendar.js.map +1 -1
  109. package/dist/components/legal.d.ts +13 -1
  110. package/dist/components/legal.js +12 -0
  111. package/dist/components/legal.js.map +1 -1
  112. package/dist/components/legended-series-chart.d.ts +83 -0
  113. package/dist/components/legended-series-chart.js +77 -0
  114. package/dist/components/legended-series-chart.js.map +1 -0
  115. package/dist/components/lightbox.js +2 -1
  116. package/dist/components/lightbox.js.map +1 -1
  117. package/dist/components/mini-calendar.js +13 -5
  118. package/dist/components/mini-calendar.js.map +1 -1
  119. package/dist/components/modal.d.ts +23 -2
  120. package/dist/components/modal.js +24 -6
  121. package/dist/components/modal.js.map +1 -1
  122. package/dist/components/month-picker.d.ts +1 -1
  123. package/dist/components/month-picker.js +6 -6
  124. package/dist/components/month-picker.js.map +1 -1
  125. package/dist/components/multi-entity-combobox.js +2 -2
  126. package/dist/components/multi-entity-combobox.js.map +1 -1
  127. package/dist/components/multi-select.js +2 -6
  128. package/dist/components/multi-select.js.map +1 -1
  129. package/dist/components/number-input.js +2 -2
  130. package/dist/components/number-input.js.map +1 -1
  131. package/dist/components/page-header-layout.d.ts +18 -0
  132. package/dist/components/page-header-layout.js +23 -0
  133. package/dist/components/page-header-layout.js.map +1 -0
  134. package/dist/components/page-header-skeleton.d.ts +41 -0
  135. package/dist/components/page-header-skeleton.js +52 -0
  136. package/dist/components/page-header-skeleton.js.map +1 -0
  137. package/dist/components/page-header.js +4 -17
  138. package/dist/components/page-header.js.map +1 -1
  139. package/dist/components/popover.js +7 -2
  140. package/dist/components/popover.js.map +1 -1
  141. package/dist/components/release-notes-labels.d.ts +16 -0
  142. package/dist/components/release-notes-labels.js +18 -0
  143. package/dist/components/release-notes-labels.js.map +1 -0
  144. package/dist/components/release-notes.d.ts +65 -0
  145. package/dist/components/release-notes.js +65 -0
  146. package/dist/components/release-notes.js.map +1 -0
  147. package/dist/components/select.js +2 -2
  148. package/dist/components/select.js.map +1 -1
  149. package/dist/components/series-chart-labels.d.ts +9 -0
  150. package/dist/components/series-chart-labels.js +3 -1
  151. package/dist/components/series-chart-labels.js.map +1 -1
  152. package/dist/components/series-chart.d.ts +5 -0
  153. package/dist/components/series-chart.js +89 -36
  154. package/dist/components/series-chart.js.map +1 -1
  155. package/dist/components/toggle-group.js +3 -2
  156. package/dist/components/toggle-group.js.map +1 -1
  157. package/dist/components/treemap-layout.js.map +1 -1
  158. package/dist/components/treemap.d.ts +17 -15
  159. package/dist/components/treemap.js +167 -85
  160. package/dist/components/treemap.js.map +1 -1
  161. package/dist/eslint/index.js +1 -1
  162. package/dist/eslint/role-utilities.d.ts +2 -2
  163. package/dist/eslint/role-utilities.js.map +1 -1
  164. package/dist/feedback/feedback-inbox-page.d.ts +260 -0
  165. package/dist/feedback/feedback-inbox-page.js +207 -0
  166. package/dist/feedback/feedback-inbox-page.js.map +1 -0
  167. package/dist/feedback/feedback-vocabulary.js +2 -2
  168. package/dist/feedback/feedback-vocabulary.js.map +1 -1
  169. package/dist/feedback.d.ts +1 -0
  170. package/dist/feedback.js +6 -0
  171. package/dist/feedback.js.map +1 -1
  172. package/dist/hooks/use-debounce.d.ts +32 -5
  173. package/dist/hooks/use-debounce.js +6 -5
  174. package/dist/hooks/use-debounce.js.map +1 -1
  175. package/dist/hooks/use-file-picker.d.ts +3 -1
  176. package/dist/hooks/use-file-picker.js.map +1 -1
  177. package/dist/hooks/use-focus-trap.d.ts +19 -3
  178. package/dist/hooks/use-focus-trap.js +15 -5
  179. package/dist/hooks/use-focus-trap.js.map +1 -1
  180. package/dist/hooks/use-has-camera.d.ts +36 -0
  181. package/dist/hooks/use-has-camera.js +53 -0
  182. package/dist/hooks/use-has-camera.js.map +1 -0
  183. package/dist/hooks/use-hotkey.js +1 -10
  184. package/dist/hooks/use-hotkey.js.map +1 -1
  185. package/dist/hooks/use-overlay-history.d.ts +6 -1
  186. package/dist/hooks/use-overlay-history.js +10 -2
  187. package/dist/hooks/use-overlay-history.js.map +1 -1
  188. package/dist/i18n/defaults.js +11 -1
  189. package/dist/i18n/defaults.js.map +1 -1
  190. package/dist/i18n/german.js +75 -3
  191. package/dist/i18n/german.js.map +1 -1
  192. package/dist/i18n/kit-labels.d.ts +20 -0
  193. package/dist/i18n/kit-labels.js.map +1 -1
  194. package/dist/i18n/locales/en.js +92 -4
  195. package/dist/i18n/locales/en.js.map +3 -3
  196. package/dist/i18n/locales/es.js +71 -3
  197. package/dist/i18n/locales/es.js.map +1 -1
  198. package/dist/i18n/locales/fr.js +72 -2
  199. package/dist/i18n/locales/fr.js.map +1 -1
  200. package/dist/i18n/locales/hu.js +74 -3
  201. package/dist/i18n/locales/hu.js.map +1 -1
  202. package/dist/i18n/locales/it.js +74 -3
  203. package/dist/i18n/locales/it.js.map +1 -1
  204. package/dist/i18n/locales/zh.js +71 -3
  205. package/dist/i18n/locales/zh.js.map +1 -1
  206. package/dist/i18n/review.js +22 -1
  207. package/dist/i18n/review.js.map +1 -1
  208. package/dist/index.d.ts +24 -5
  209. package/dist/index.js +35 -1
  210. package/dist/index.js.map +1 -1
  211. package/dist/landing/landing-labels.d.ts +8 -0
  212. package/dist/landing/landing-labels.js +2 -1
  213. package/dist/landing/landing-labels.js.map +1 -1
  214. package/dist/lib/changelog.d.ts +130 -0
  215. package/dist/lib/changelog.js +137 -0
  216. package/dist/lib/changelog.js.map +1 -0
  217. package/dist/lib/clipboard-minus.js +2 -2
  218. package/dist/lib/clipboard-minus.js.map +1 -1
  219. package/dist/lib/dates.d.ts +29 -3
  220. package/dist/lib/dates.js +41 -12
  221. package/dist/lib/dates.js.map +1 -1
  222. package/dist/lib/editable-content.d.ts +33 -0
  223. package/dist/lib/editable-content.js +15 -0
  224. package/dist/lib/editable-content.js.map +1 -0
  225. package/dist/lib/focus-left.d.ts +47 -1
  226. package/dist/lib/focus-left.js +11 -2
  227. package/dist/lib/focus-left.js.map +1 -1
  228. package/dist/lib/server-wake.d.ts +49 -9
  229. package/dist/lib/server-wake.js +25 -14
  230. package/dist/lib/server-wake.js.map +1 -1
  231. package/dist/lib/session-refresh.d.ts +53 -0
  232. package/dist/lib/session-refresh.js +27 -1
  233. package/dist/lib/session-refresh.js.map +1 -1
  234. package/dist/rhf/fields.js +3 -3
  235. package/dist/rhf/fields.js.map +1 -1
  236. package/dist/shell/app-shell.d.ts +25 -1
  237. package/dist/shell/app-shell.js +3 -1
  238. package/dist/shell/app-shell.js.map +1 -1
  239. package/dist/shell/dev-menu.d.ts +3 -0
  240. package/dist/shell/dev-menu.js +4 -2
  241. package/dist/shell/dev-menu.js.map +1 -1
  242. package/dist/shell/held-changes-banner-labels.d.ts +23 -0
  243. package/dist/shell/held-changes-banner-labels.js +14 -0
  244. package/dist/shell/held-changes-banner-labels.js.map +1 -0
  245. package/dist/shell/held-changes-banner.d.ts +75 -0
  246. package/dist/shell/held-changes-banner.js +106 -0
  247. package/dist/shell/held-changes-banner.js.map +1 -0
  248. package/dist/shell/sync-status-indicator.d.ts +27 -12
  249. package/dist/shell/sync-status-indicator.js +13 -4
  250. package/dist/shell/sync-status-indicator.js.map +1 -1
  251. package/dist/shell/top-bar-parts-labels.d.ts +5 -0
  252. package/dist/shell/top-bar-parts-labels.js +3 -1
  253. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  254. package/dist/shell.d.ts +2 -0
  255. package/dist/shell.js +3 -0
  256. package/dist/shell.js.map +1 -1
  257. package/dist/sync/engine.d.ts +11 -2
  258. package/dist/sync/engine.js +13 -5
  259. package/dist/sync/engine.js.map +1 -1
  260. package/dist/sync/hooks.d.ts +3 -2
  261. package/dist/sync/hooks.js +4 -2
  262. package/dist/sync/hooks.js.map +1 -1
  263. package/dist/testing/css-variables.generated.d.ts +2 -2
  264. package/dist/testing/css-variables.generated.js +1 -1
  265. package/dist/testing/css-variables.generated.js.map +1 -1
  266. package/dist/theme/chart-palette.d.ts +18 -0
  267. package/dist/theme/chart-palette.js +17 -1
  268. package/dist/theme/chart-palette.js.map +1 -1
  269. package/dist/theme/contrast-tokens.d.ts +3 -3
  270. package/dist/theme/contrast-tokens.js.map +1 -1
  271. package/dist/theme/contrast.d.ts +4 -4
  272. package/dist/theme/contrast.js.map +1 -1
  273. package/dist/tour/tour-overlay.js +2 -1
  274. package/dist/tour/tour-overlay.js.map +1 -1
  275. package/package.json +9 -12
  276. package/tokens.css +19 -54
  277. package/src/account/account-parts.ts +0 -47
  278. package/src/account/account-settings-labels.ts +0 -240
  279. package/src/account/account-settings.tsx +0 -698
  280. package/src/account/data-export-setting-labels.ts +0 -20
  281. package/src/account/data-export-setting.tsx +0 -200
  282. package/src/account/delete-account-setting-labels.ts +0 -33
  283. package/src/account/delete-account-setting.tsx +0 -342
  284. package/src/account/email-change-setting-labels.ts +0 -31
  285. package/src/account/email-change-setting.tsx +0 -443
  286. package/src/account/passkeys-setting.tsx +0 -445
  287. package/src/account/sessions-setting-labels.ts +0 -24
  288. package/src/account/sessions-setting.tsx +0 -283
  289. package/src/admin/admin-action-confirm-labels.ts +0 -19
  290. package/src/admin/admin-action-confirm.tsx +0 -509
  291. package/src/admin/admin-action-log-labels.ts +0 -83
  292. package/src/admin/admin-action-log.tsx +0 -464
  293. package/src/admin/admin-area-labels.ts +0 -114
  294. package/src/admin/admin-forbidden.tsx +0 -75
  295. package/src/admin/admin-overview.tsx +0 -258
  296. package/src/admin/admin-parts.ts +0 -68
  297. package/src/admin/admin-sections.tsx +0 -208
  298. package/src/admin/admin-tool-links.tsx +0 -90
  299. package/src/admin/invitations-panel-labels.ts +0 -31
  300. package/src/admin/invitations-panel.tsx +0 -516
  301. package/src/admin/mail-test-card-labels.ts +0 -19
  302. package/src/admin/mail-test-card.tsx +0 -189
  303. package/src/admin/plan-change-labels.ts +0 -5
  304. package/src/admin/plan-change.tsx +0 -474
  305. package/src/admin/reviewer-scope-editor-labels.ts +0 -16
  306. package/src/admin/reviewer-scope-editor.tsx +0 -224
  307. package/src/admin/role-select-labels.ts +0 -16
  308. package/src/admin/role-select.tsx +0 -282
  309. package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
  310. package/src/admin/transfer-ownership-dialog.tsx +0 -162
  311. package/src/admin/user-roster-labels.ts +0 -17
  312. package/src/admin/user-roster.tsx +0 -559
  313. package/src/auth/accept-invitation-labels.ts +0 -21
  314. package/src/auth/accept-invitation.tsx +0 -210
  315. package/src/auth/auth-errors-labels.ts +0 -23
  316. package/src/auth/auth-errors.ts +0 -439
  317. package/src/auth/complete-name-dialog-labels.ts +0 -16
  318. package/src/auth/complete-name-dialog.tsx +0 -253
  319. package/src/auth/email-tag.ts +0 -75
  320. package/src/auth/forgot-password-form-labels.ts +0 -20
  321. package/src/auth/forgot-password-form.tsx +0 -221
  322. package/src/auth/form-rules.ts +0 -40
  323. package/src/auth/new-password-fields.tsx +0 -85
  324. package/src/auth/not-found-page-labels.ts +0 -12
  325. package/src/auth/not-found-page.tsx +0 -95
  326. package/src/auth/register-form-labels.ts +0 -31
  327. package/src/auth/register-form.tsx +0 -456
  328. package/src/auth/reset-password-form-labels.ts +0 -27
  329. package/src/auth/reset-password-form.tsx +0 -341
  330. package/src/auth/sign-in-form-labels.ts +0 -44
  331. package/src/auth/sign-in-form.tsx +0 -858
  332. package/src/auth/status-parts.tsx +0 -132
  333. package/src/auth/verify-email-labels.ts +0 -26
  334. package/src/auth/verify-email.tsx +0 -445
  335. package/src/billing/billing-banner.tsx +0 -258
  336. package/src/billing/billing-labels.ts +0 -381
  337. package/src/billing/billing-lock.ts +0 -108
  338. package/src/billing/billing-overview.ts +0 -157
  339. package/src/billing/billing-standing.ts +0 -80
  340. package/src/billing/cancel-request.ts +0 -97
  341. package/src/billing/cancel-subscription.tsx +0 -98
  342. package/src/billing/checkout-processing.ts +0 -394
  343. package/src/billing/checkout-return.ts +0 -90
  344. package/src/billing/pay-page.ts +0 -330
  345. package/src/billing/plan-card.tsx +0 -562
  346. package/src/billing/plan-change-labels.ts +0 -66
  347. package/src/billing/plan-limit-notice.tsx +0 -148
  348. package/src/billing/plan-limit-toast.tsx +0 -90
  349. package/src/billing/plan-limit.ts +0 -52
  350. package/src/billing/plan-price.ts +0 -98
  351. package/src/billing/plan-switch.tsx +0 -216
  352. package/src/billing/provider-page.ts +0 -84
  353. package/src/billing/subscription-actions.tsx +0 -247
  354. package/src/billing/subscription-status-chip.tsx +0 -95
  355. package/src/chart.ts +0 -103
  356. package/src/components/account-chips-labels.ts +0 -16
  357. package/src/components/account-chips.tsx +0 -474
  358. package/src/components/alert-banner.tsx +0 -670
  359. package/src/components/amount-input.tsx +0 -816
  360. package/src/components/appearance-labels.ts +0 -63
  361. package/src/components/authed-image-labels.ts +0 -11
  362. package/src/components/authed-image.tsx +0 -209
  363. package/src/components/autocomplete.tsx +0 -645
  364. package/src/components/breadcrumbs-labels.ts +0 -10
  365. package/src/components/breadcrumbs.tsx +0 -205
  366. package/src/components/bulk-action-bar-labels.ts +0 -11
  367. package/src/components/bulk-action-bar.tsx +0 -443
  368. package/src/components/button-group.tsx +0 -223
  369. package/src/components/button-look.ts +0 -256
  370. package/src/components/button.tsx +0 -339
  371. package/src/components/calculator.tsx +0 -341
  372. package/src/components/calendar-heatmap-labels.ts +0 -15
  373. package/src/components/calendar-heatmap.tsx +0 -600
  374. package/src/components/card.tsx +0 -377
  375. package/src/components/chart-edge.ts +0 -106
  376. package/src/components/chart-figure.tsx +0 -35
  377. package/src/components/chart-height.ts +0 -30
  378. package/src/components/chart-zoom-core.tsx +0 -627
  379. package/src/components/chart-zoom.tsx +0 -22
  380. package/src/components/chart.tsx +0 -554
  381. package/src/components/checkbox-group.tsx +0 -247
  382. package/src/components/checkbox.tsx +0 -346
  383. package/src/components/chip-input.tsx +0 -370
  384. package/src/components/chip-labels.ts +0 -13
  385. package/src/components/chip.tsx +0 -843
  386. package/src/components/choice-card.tsx +0 -544
  387. package/src/components/column-mapper-labels.ts +0 -38
  388. package/src/components/column-mapper.tsx +0 -655
  389. package/src/components/combobox-core.tsx +0 -1321
  390. package/src/components/combobox-suggestions.tsx +0 -131
  391. package/src/components/combobox.tsx +0 -716
  392. package/src/components/confirm-context.ts +0 -7
  393. package/src/components/confirm-dialog-labels.ts +0 -13
  394. package/src/components/confirm-dialog.tsx +0 -341
  395. package/src/components/copy-button-labels.ts +0 -13
  396. package/src/components/copy-button.tsx +0 -192
  397. package/src/components/country-select-labels.ts +0 -11
  398. package/src/components/country-select.tsx +0 -539
  399. package/src/components/currency-option-list.tsx +0 -188
  400. package/src/components/currency-select.tsx +0 -343
  401. package/src/components/danger-confirm-labels.ts +0 -20
  402. package/src/components/danger-confirm.tsx +0 -987
  403. package/src/components/data-table-cells.tsx +0 -118
  404. package/src/components/data-table-column-settings.tsx +0 -198
  405. package/src/components/data-table-filter-popover.tsx +0 -289
  406. package/src/components/data-table-filters.ts +0 -315
  407. package/src/components/data-table-fit.ts +0 -301
  408. package/src/components/data-table-groups.tsx +0 -288
  409. package/src/components/data-table-head.tsx +0 -280
  410. package/src/components/data-table-labels.ts +0 -198
  411. package/src/components/data-table-leading-row.tsx +0 -58
  412. package/src/components/data-table-mobile.tsx +0 -1117
  413. package/src/components/data-table-pagination.tsx +0 -202
  414. package/src/components/data-table-resize.ts +0 -188
  415. package/src/components/data-table-row-actions.tsx +0 -302
  416. package/src/components/data-table-row.tsx +0 -496
  417. package/src/components/data-table-selection.ts +0 -71
  418. package/src/components/data-table-shared.tsx +0 -287
  419. package/src/components/data-table-sort.ts +0 -163
  420. package/src/components/data-table-virtual.ts +0 -576
  421. package/src/components/data-table.tsx +0 -2598
  422. package/src/components/date-field.tsx +0 -684
  423. package/src/components/date-format-setting.tsx +0 -64
  424. package/src/components/date-picker.tsx +0 -404
  425. package/src/components/date-range-picker.tsx +0 -518
  426. package/src/components/description-list-labels.ts +0 -9
  427. package/src/components/description-list.tsx +0 -386
  428. package/src/components/dialog-frame-labels.ts +0 -7
  429. package/src/components/dialog-frame.tsx +0 -284
  430. package/src/components/disclosure.tsx +0 -476
  431. package/src/components/dropdown.tsx +0 -461
  432. package/src/components/empty-state.tsx +0 -136
  433. package/src/components/entity-combobox.tsx +0 -422
  434. package/src/components/error-boundary-labels.ts +0 -20
  435. package/src/components/error-boundary.tsx +0 -675
  436. package/src/components/facing-pair.ts +0 -93
  437. package/src/components/field-base-labels.ts +0 -20
  438. package/src/components/field-base.tsx +0 -656
  439. package/src/components/field-parts.tsx +0 -825
  440. package/src/components/field-strip.tsx +0 -129
  441. package/src/components/field.tsx +0 -206
  442. package/src/components/file-button.tsx +0 -295
  443. package/src/components/file-dropzone.tsx +0 -559
  444. package/src/components/floating-panel-labels.ts +0 -10
  445. package/src/components/floating-panel.tsx +0 -828
  446. package/src/components/focus-ring.ts +0 -16
  447. package/src/components/form-actions-labels.ts +0 -11
  448. package/src/components/form-actions.tsx +0 -578
  449. package/src/components/full-bleed-dialog.tsx +0 -294
  450. package/src/components/grouped-picker.tsx +0 -184
  451. package/src/components/help-popover.tsx +0 -117
  452. package/src/components/hover-menu.tsx +0 -343
  453. package/src/components/iban-input-labels.ts +0 -14
  454. package/src/components/iban-input.tsx +0 -236
  455. package/src/components/icon-button.tsx +0 -959
  456. package/src/components/icon-picker-labels.ts +0 -13
  457. package/src/components/icon-picker.tsx +0 -232
  458. package/src/components/image-grid-labels.ts +0 -11
  459. package/src/components/image-grid.tsx +0 -202
  460. package/src/components/inline-confirm.tsx +0 -116
  461. package/src/components/inline-edit-field-labels.ts +0 -11
  462. package/src/components/inline-edit-field.tsx +0 -552
  463. package/src/components/inline-entity-combobox.tsx +0 -849
  464. package/src/components/input.tsx +0 -394
  465. package/src/components/jump-calendar.tsx +0 -265
  466. package/src/components/language-select.tsx +0 -93
  467. package/src/components/legal-labels.ts +0 -105
  468. package/src/components/legal-page.tsx +0 -711
  469. package/src/components/legal.tsx +0 -668
  470. package/src/components/lightbox-labels.ts +0 -18
  471. package/src/components/lightbox.tsx +0 -399
  472. package/src/components/line-items-labels.ts +0 -14
  473. package/src/components/line-items.tsx +0 -602
  474. package/src/components/list-labels.ts +0 -12
  475. package/src/components/list.tsx +0 -870
  476. package/src/components/loading-state.tsx +0 -78
  477. package/src/components/measured-grid-labels.ts +0 -25
  478. package/src/components/measured-grid.tsx +0 -837
  479. package/src/components/menu-item.tsx +0 -241
  480. package/src/components/mini-calendar-labels.ts +0 -17
  481. package/src/components/mini-calendar.tsx +0 -792
  482. package/src/components/modal.tsx +0 -534
  483. package/src/components/money-draft.ts +0 -83
  484. package/src/components/money-field.tsx +0 -76
  485. package/src/components/month-grid.tsx +0 -229
  486. package/src/components/month-picker-labels.ts +0 -22
  487. package/src/components/month-picker.tsx +0 -1087
  488. package/src/components/multi-entity-combobox.tsx +0 -369
  489. package/src/components/multi-select.tsx +0 -376
  490. package/src/components/nav-pills.tsx +0 -198
  491. package/src/components/number-field.tsx +0 -327
  492. package/src/components/number-input.tsx +0 -559
  493. package/src/components/numeric-field.ts +0 -169
  494. package/src/components/numpad-sheet.tsx +0 -285
  495. package/src/components/one-time-code-input.tsx +0 -270
  496. package/src/components/page-contents-labels.ts +0 -9
  497. package/src/components/page-contents.tsx +0 -282
  498. package/src/components/page-header-context.ts +0 -8
  499. package/src/components/page-header.tsx +0 -298
  500. package/src/components/password-strength-labels.ts +0 -22
  501. package/src/components/password-strength.tsx +0 -241
  502. package/src/components/phone-input-labels.ts +0 -10
  503. package/src/components/phone-input.tsx +0 -282
  504. package/src/components/picker-sheet.tsx +0 -330
  505. package/src/components/pie-chart-labels.ts +0 -40
  506. package/src/components/pie-chart.tsx +0 -480
  507. package/src/components/popover-labels.ts +0 -14
  508. package/src/components/popover.tsx +0 -268
  509. package/src/components/progress-bar-labels.ts +0 -10
  510. package/src/components/progress-bar.tsx +0 -479
  511. package/src/components/qr-code.tsx +0 -76
  512. package/src/components/reauth-dialog-labels.ts +0 -13
  513. package/src/components/reauth-dialog.tsx +0 -265
  514. package/src/components/row-actions-labels.ts +0 -12
  515. package/src/components/row-actions.tsx +0 -795
  516. package/src/components/scroll-area.tsx +0 -123
  517. package/src/components/search-field.tsx +0 -192
  518. package/src/components/select.tsx +0 -294
  519. package/src/components/separator.tsx +0 -33
  520. package/src/components/series-chart-axes.ts +0 -342
  521. package/src/components/series-chart-budget.ts +0 -150
  522. package/src/components/series-chart-labels.ts +0 -33
  523. package/src/components/series-chart-thin.ts +0 -180
  524. package/src/components/series-chart-ticks.ts +0 -194
  525. package/src/components/series-chart.tsx +0 -1906
  526. package/src/components/server-wake-labels.ts +0 -11
  527. package/src/components/server-wake.tsx +0 -129
  528. package/src/components/settings-fields.tsx +0 -237
  529. package/src/components/share-card-labels.ts +0 -30
  530. package/src/components/share-card.tsx +0 -675
  531. package/src/components/signature-pad-labels.ts +0 -24
  532. package/src/components/signature-pad.tsx +0 -747
  533. package/src/components/signed-amount-labels.ts +0 -10
  534. package/src/components/signed-amount.tsx +0 -336
  535. package/src/components/skeleton.tsx +0 -80
  536. package/src/components/slider.tsx +0 -338
  537. package/src/components/sparkline-labels.ts +0 -14
  538. package/src/components/sparkline.tsx +0 -322
  539. package/src/components/spinner.tsx +0 -81
  540. package/src/components/stat-tile-labels.ts +0 -15
  541. package/src/components/stat-tile.tsx +0 -754
  542. package/src/components/status-dot.tsx +0 -170
  543. package/src/components/swatch-picker-labels.ts +0 -10
  544. package/src/components/swatch-picker.tsx +0 -283
  545. package/src/components/swipeable-row.tsx +0 -386
  546. package/src/components/switch.tsx +0 -273
  547. package/src/components/table-skeleton.tsx +0 -136
  548. package/src/components/table.tsx +0 -647
  549. package/src/components/tabs-labels.ts +0 -13
  550. package/src/components/tabs.tsx +0 -693
  551. package/src/components/text-link.tsx +0 -359
  552. package/src/components/text.tsx +0 -150
  553. package/src/components/textarea.tsx +0 -330
  554. package/src/components/tile-radio.tsx +0 -332
  555. package/src/components/time-input.tsx +0 -121
  556. package/src/components/toast-labels.ts +0 -12
  557. package/src/components/toast.tsx +0 -519
  558. package/src/components/toggle-group.tsx +0 -752
  559. package/src/components/toggle-legend.tsx +0 -394
  560. package/src/components/tooltip.tsx +0 -1149
  561. package/src/components/translation-review-editor.tsx +0 -290
  562. package/src/components/translation-review-labels.ts +0 -181
  563. package/src/components/translation-review-parts.tsx +0 -272
  564. package/src/components/translation-review.tsx +0 -1240
  565. package/src/components/tree-view.tsx +0 -589
  566. package/src/components/treemap-labels.ts +0 -47
  567. package/src/components/treemap-layout.ts +0 -210
  568. package/src/components/treemap.tsx +0 -1184
  569. package/src/components/trigger-aria.ts +0 -44
  570. package/src/components/use-anchor-dir.ts +0 -20
  571. package/src/components/use-mobile-reveal.ts +0 -62
  572. package/src/components/use-table-state.ts +0 -753
  573. package/src/components/user-avatar.tsx +0 -116
  574. package/src/components/wizard-stepper.tsx +0 -42
  575. package/src/components/write-lock-labels.ts +0 -10
  576. package/src/components/write-lock.tsx +0 -253
  577. package/src/currencies.ts +0 -90
  578. package/src/data-table.ts +0 -42
  579. package/src/demo/demo-banner.tsx +0 -153
  580. package/src/demo/demo-countdown.ts +0 -136
  581. package/src/demo/demo-ended.tsx +0 -90
  582. package/src/demo/demo-labels.ts +0 -78
  583. package/src/demo/demo-session.ts +0 -32
  584. package/src/demo/demo-start.tsx +0 -156
  585. package/src/eslint/index.ts +0 -161
  586. package/src/eslint/role-utilities.generated.ts +0 -146
  587. package/src/eslint/role-utilities.ts +0 -233
  588. package/src/feedback/feedback-attachment-download.tsx +0 -77
  589. package/src/feedback/feedback-attachment-labels.ts +0 -37
  590. package/src/feedback/feedback-attachment.tsx +0 -1239
  591. package/src/feedback/feedback-capture.ts +0 -287
  592. package/src/feedback/feedback-comment-thread.tsx +0 -353
  593. package/src/feedback/feedback-context-labels.ts +0 -11
  594. package/src/feedback/feedback-context.tsx +0 -245
  595. package/src/feedback/feedback-crash.ts +0 -547
  596. package/src/feedback/feedback-diagnostics.tsx +0 -41
  597. package/src/feedback/feedback-dialog-labels.ts +0 -29
  598. package/src/feedback/feedback-dialog.tsx +0 -452
  599. package/src/feedback/feedback-entry-file.tsx +0 -150
  600. package/src/feedback/feedback-inbox.tsx +0 -552
  601. package/src/feedback/feedback-labels.ts +0 -144
  602. package/src/feedback/feedback-menu-labels.ts +0 -12
  603. package/src/feedback/feedback-menu.tsx +0 -177
  604. package/src/feedback/feedback-mutation.ts +0 -20
  605. package/src/feedback/feedback-page-link.ts +0 -90
  606. package/src/feedback/feedback-public-labels.ts +0 -81
  607. package/src/feedback/feedback-public-list.tsx +0 -524
  608. package/src/feedback/feedback-public-switch.tsx +0 -102
  609. package/src/feedback/feedback-public-types.ts +0 -101
  610. package/src/feedback/feedback-record.ts +0 -428
  611. package/src/feedback/feedback-replies-context.ts +0 -9
  612. package/src/feedback/feedback-replies.tsx +0 -343
  613. package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
  614. package/src/feedback/feedback-row-detail-labels.ts +0 -31
  615. package/src/feedback/feedback-row-detail.tsx +0 -871
  616. package/src/feedback/feedback-status-undo.ts +0 -109
  617. package/src/feedback/feedback-submit-dialog.tsx +0 -131
  618. package/src/feedback/feedback-submit.tsx +0 -270
  619. package/src/feedback/feedback-swipe.tsx +0 -192
  620. package/src/feedback/feedback-table-labels.ts +0 -27
  621. package/src/feedback/feedback-table.tsx +0 -912
  622. package/src/feedback/feedback-thread-labels.ts +0 -22
  623. package/src/feedback/feedback-thread-parts-labels.ts +0 -41
  624. package/src/feedback/feedback-thread.tsx +0 -905
  625. package/src/feedback/feedback-vocabulary.ts +0 -263
  626. package/src/feedback/feedback-vote-button.tsx +0 -124
  627. package/src/feedback.ts +0 -116
  628. package/src/hooks/use-anchored-panel.ts +0 -396
  629. package/src/hooks/use-anchored-rect.ts +0 -77
  630. package/src/hooks/use-announce.ts +0 -85
  631. package/src/hooks/use-authed-src.ts +0 -167
  632. package/src/hooks/use-body-scroll-lock.ts +0 -119
  633. package/src/hooks/use-breakpoint.ts +0 -133
  634. package/src/hooks/use-close-transition.ts +0 -107
  635. package/src/hooks/use-copy-to-clipboard.ts +0 -122
  636. package/src/hooks/use-debounce.ts +0 -114
  637. package/src/hooks/use-dismiss.ts +0 -371
  638. package/src/hooks/use-document-title.ts +0 -33
  639. package/src/hooks/use-file-drop.ts +0 -121
  640. package/src/hooks/use-file-picker-labels.ts +0 -28
  641. package/src/hooks/use-file-picker.tsx +0 -359
  642. package/src/hooks/use-focus-trap.ts +0 -199
  643. package/src/hooks/use-hotkey.ts +0 -212
  644. package/src/hooks/use-large-text.ts +0 -41
  645. package/src/hooks/use-long-press.ts +0 -140
  646. package/src/hooks/use-media-query.ts +0 -39
  647. package/src/hooks/use-mounted.ts +0 -39
  648. package/src/hooks/use-noindex.ts +0 -37
  649. package/src/hooks/use-overlay-history.ts +0 -714
  650. package/src/hooks/use-row-swipe.ts +0 -207
  651. package/src/hooks/use-search-param-state.ts +0 -434
  652. package/src/hooks/use-windowed-rows.ts +0 -225
  653. package/src/i18n/defaults.ts +0 -267
  654. package/src/i18n/german.ts +0 -2059
  655. package/src/i18n/kit-labels.tsx +0 -1003
  656. package/src/i18n/languages.ts +0 -349
  657. package/src/i18n/locales/de-CH.ts +0 -24
  658. package/src/i18n/locales/en.ts +0 -267
  659. package/src/i18n/locales/es.ts +0 -1999
  660. package/src/i18n/locales/fr.ts +0 -2037
  661. package/src/i18n/locales/hu.ts +0 -2004
  662. package/src/i18n/locales/it.ts +0 -2014
  663. package/src/i18n/locales/zh.ts +0 -1912
  664. package/src/i18n/plurals.ts +0 -86
  665. package/src/i18n/review.ts +0 -475
  666. package/src/i18n/shared-labels.ts +0 -138
  667. package/src/i18n/swiss.ts +0 -29
  668. package/src/index.ts +0 -1191
  669. package/src/landing/access.ts +0 -93
  670. package/src/landing/landing-actions.tsx +0 -97
  671. package/src/landing/landing-labels.ts +0 -59
  672. package/src/landing/landing-sections.tsx +0 -341
  673. package/src/landing/page-seo.ts +0 -261
  674. package/src/landing/public-header.tsx +0 -121
  675. package/src/landing/public-page.tsx +0 -106
  676. package/src/landing/routing.tsx +0 -225
  677. package/src/lib/broadcast.ts +0 -52
  678. package/src/lib/calc.ts +0 -323
  679. package/src/lib/chip-edge-snap.ts +0 -212
  680. package/src/lib/clipboard-minus.ts +0 -107
  681. package/src/lib/clipping.ts +0 -34
  682. package/src/lib/cn.ts +0 -28
  683. package/src/lib/column-mapping.ts +0 -234
  684. package/src/lib/countries.ts +0 -91
  685. package/src/lib/data-attributes.ts +0 -14
  686. package/src/lib/date-format.ts +0 -227
  687. package/src/lib/dates.ts +0 -288
  688. package/src/lib/day-format.ts +0 -96
  689. package/src/lib/decimal-marks.ts +0 -108
  690. package/src/lib/describe-failure.ts +0 -18
  691. package/src/lib/device-settings.ts +0 -147
  692. package/src/lib/direction.ts +0 -74
  693. package/src/lib/document-navigation.ts +0 -17
  694. package/src/lib/document-title.ts +0 -41
  695. package/src/lib/download.ts +0 -172
  696. package/src/lib/float-clearance.ts +0 -70
  697. package/src/lib/floating-stack.ts +0 -70
  698. package/src/lib/focus-left.ts +0 -156
  699. package/src/lib/format.ts +0 -585
  700. package/src/lib/http-status.ts +0 -38
  701. package/src/lib/iban.ts +0 -251
  702. package/src/lib/ime.ts +0 -24
  703. package/src/lib/intl-cache.ts +0 -27
  704. package/src/lib/iso-day.ts +0 -13
  705. package/src/lib/lazy-with-fallback.ts +0 -82
  706. package/src/lib/logger.ts +0 -69
  707. package/src/lib/minus.ts +0 -50
  708. package/src/lib/path-pattern.ts +0 -55
  709. package/src/lib/person-name.ts +0 -155
  710. package/src/lib/phone.ts +0 -208
  711. package/src/lib/plain-text.ts +0 -22
  712. package/src/lib/presence.ts +0 -18
  713. package/src/lib/qr-encode.ts +0 -444
  714. package/src/lib/quiet-focus.ts +0 -32
  715. package/src/lib/reduced-motion.ts +0 -22
  716. package/src/lib/refs.ts +0 -22
  717. package/src/lib/round.ts +0 -43
  718. package/src/lib/safe-storage.ts +0 -119
  719. package/src/lib/server-wake.ts +0 -315
  720. package/src/lib/session-refresh.ts +0 -472
  721. package/src/lib/share-format.ts +0 -18
  722. package/src/lib/status-tone.ts +0 -43
  723. package/src/lib/strip-fade.ts +0 -287
  724. package/src/lib/table-text.ts +0 -554
  725. package/src/lib/text-case.ts +0 -19
  726. package/src/lib/text-match.ts +0 -169
  727. package/src/lib/thenable.ts +0 -19
  728. package/src/lib/translation-review.ts +0 -769
  729. package/src/notifications/device-zone-report.ts +0 -67
  730. package/src/notifications/feedback-notification-types-labels.ts +0 -33
  731. package/src/notifications/feedback-notification-types.ts +0 -71
  732. package/src/notifications/notification-bell.tsx +0 -119
  733. package/src/notifications/notification-inbox.tsx +0 -309
  734. package/src/notifications/notification-parts.tsx +0 -81
  735. package/src/notifications/notification-types-setting.tsx +0 -406
  736. package/src/notifications/notification-types.ts +0 -89
  737. package/src/notifications/notifications-labels.ts +0 -287
  738. package/src/notifications/push-device-setting.tsx +0 -230
  739. package/src/notifications/push-devices-setting.tsx +0 -374
  740. package/src/notifications/push-worker.ts +0 -168
  741. package/src/notifications/quiet-hours-setting.tsx +0 -238
  742. package/src/notifications/unsubscribe-panel.tsx +0 -200
  743. package/src/notifications/use-push-device.ts +0 -448
  744. package/src/offline/local-first.ts +0 -100
  745. package/src/offline/pwa-update-prompt-labels.ts +0 -9
  746. package/src/offline/pwa-update-prompt.tsx +0 -78
  747. package/src/offline/query-persistence.ts +0 -391
  748. package/src/offline/service-worker-updates.ts +0 -81
  749. package/src/offline/shared-computer-labels.ts +0 -8
  750. package/src/offline/shared-computer.tsx +0 -87
  751. package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
  752. package/src/offline/sign-out-pending-dialog.tsx +0 -135
  753. package/src/offline.ts +0 -37
  754. package/src/push-worker.ts +0 -25
  755. package/src/rhf/fields.tsx +0 -2187
  756. package/src/rhf/form-core.tsx +0 -324
  757. package/src/rhf/form.tsx +0 -12
  758. package/src/rhf/line-items.tsx +0 -135
  759. package/src/rhf/use-rhf-wizard-step.ts +0 -104
  760. package/src/rhf.ts +0 -21
  761. package/src/search/command-palette-labels.ts +0 -16
  762. package/src/search/command-palette.tsx +0 -624
  763. package/src/search/global-search-labels.ts +0 -13
  764. package/src/search/global-search.tsx +0 -660
  765. package/src/search/search-index.ts +0 -283
  766. package/src/search/use-command-key.ts +0 -23
  767. package/src/search.ts +0 -14
  768. package/src/settings/device-reset-setting-labels.ts +0 -20
  769. package/src/settings/device-reset-setting.tsx +0 -116
  770. package/src/settings/settings-card-classes.ts +0 -11
  771. package/src/settings/settings-catalogue.ts +0 -150
  772. package/src/settings/settings-context.ts +0 -33
  773. package/src/settings/settings-heading.tsx +0 -67
  774. package/src/settings/settings-labels.ts +0 -87
  775. package/src/settings/settings-layout.tsx +0 -471
  776. package/src/settings/settings-section.tsx +0 -108
  777. package/src/settings/use-account-appearance.ts +0 -148
  778. package/src/settings/use-account-language.ts +0 -146
  779. package/src/settings/use-settings-focus.ts +0 -128
  780. package/src/settings/use-settings-route.ts +0 -258
  781. package/src/shell/account-menu-language.tsx +0 -130
  782. package/src/shell/account-menu-text-size.tsx +0 -80
  783. package/src/shell/admin-menu.tsx +0 -183
  784. package/src/shell/app-shell-labels.ts +0 -11
  785. package/src/shell/app-shell.tsx +0 -1560
  786. package/src/shell/auth-layout.tsx +0 -186
  787. package/src/shell/company-switcher-labels.ts +0 -13
  788. package/src/shell/company-switcher.tsx +0 -136
  789. package/src/shell/dev-menu.tsx +0 -257
  790. package/src/shell/fill-height.tsx +0 -45
  791. package/src/shell/language-code.ts +0 -5
  792. package/src/shell/option-switcher-menu.tsx +0 -84
  793. package/src/shell/sync-status-indicator.tsx +0 -303
  794. package/src/shell/top-bar-actions.tsx +0 -87
  795. package/src/shell/top-bar-brand.tsx +0 -78
  796. package/src/shell/top-bar-parts-labels.ts +0 -148
  797. package/src/shell/top-bar.tsx +0 -40
  798. package/src/shell/topbar-action-menu.tsx +0 -567
  799. package/src/shell/topbar-controls.tsx +0 -269
  800. package/src/shell/tour-menu.tsx +0 -187
  801. package/src/shell.ts +0 -108
  802. package/src/sync/db.ts +0 -129
  803. package/src/sync/engine.ts +0 -1011
  804. package/src/sync/hooks.ts +0 -98
  805. package/src/sync/testing.ts +0 -73
  806. package/src/sync/wire.ts +0 -61
  807. package/src/sync.ts +0 -37
  808. package/src/table-text.ts +0 -8
  809. package/src/testing/css-variables.generated.ts +0 -112
  810. package/src/testing/css-variables.ts +0 -189
  811. package/src/testing/index.ts +0 -29
  812. package/src/testing/react.ts +0 -58
  813. package/src/testing/tour.ts +0 -41
  814. package/src/testing/viewport.ts +0 -357
  815. package/src/theme/chart-palette.ts +0 -232
  816. package/src/theme/color.ts +0 -272
  817. package/src/theme/contrast-tokens.ts +0 -268
  818. package/src/theme/contrast.ts +0 -250
  819. package/src/theme/palette-derive.ts +0 -825
  820. package/src/theme/palette-presets.ts +0 -544
  821. package/src/theme/palette-store.ts +0 -108
  822. package/src/theme/text-size.ts +0 -289
  823. package/src/theme/theme-store.ts +0 -157
  824. package/src/tour/tour-catalogue-labels.ts +0 -75
  825. package/src/tour/tour-catalogue.tsx +0 -335
  826. package/src/tour/tour-dock.ts +0 -134
  827. package/src/tour/tour-engine.ts +0 -37
  828. package/src/tour/tour-gates.ts +0 -218
  829. package/src/tour/tour-guide-button.tsx +0 -64
  830. package/src/tour/tour-guide-labels.ts +0 -15
  831. package/src/tour/tour-info.ts +0 -144
  832. package/src/tour/tour-labels.ts +0 -23
  833. package/src/tour/tour-overlay.tsx +0 -1170
  834. package/src/tour/tour.tsx +0 -750
  835. package/src/tour/use-tour-progress.ts +0 -671
  836. package/src/tour/use-tour-url-sync.ts +0 -266
  837. package/src/tour.ts +0 -21
  838. package/src/vite-env.d.ts +0 -23
  839. package/src/wizard/stepper-nav.tsx +0 -360
  840. package/src/wizard/types.ts +0 -275
  841. package/src/wizard/use-wizard.ts +0 -560
  842. package/src/wizard/validation.ts +0 -39
  843. package/src/wizard/wizard-context.tsx +0 -74
  844. package/src/wizard/wizard-labels.ts +0 -29
  845. package/src/wizard/wizard-step.tsx +0 -76
  846. package/src/wizard/wizard-summary.tsx +0 -84
  847. package/src/wizard.ts +0 -15
@@ -1,837 +0,0 @@
1
- import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
2
- import type { ComponentPropsWithRef, KeyboardEvent, ReactNode } from "react";
3
- import { ClipboardPaste, Eraser, Plus, Trash2 } from "lucide-react";
4
- import { cn } from "../lib/cn";
5
- import { horizontalStep } from "../lib/direction";
6
- // The locale's mark as far as a cell can hold it — the fields' answer, the same reason
7
- // (DUP-11, refactor audit 2026-10: a verbatim copy lived here).
8
- import { decimalMark } from "../lib/decimal-marks";
9
- import { roundHalfAway } from "../lib/round";
10
- // The cell pair reads ONE cell, where a comma has no columns to separate and so is
11
- // always a decimal mark; `splitRow` and `parseRows` read a pasted table, where it may
12
- // be either and the line decides. See the three named rules at the top of table-text.
13
- import { cellNumber, isCellNumber, parseRows, splitRow } from "../lib/table-text";
14
- import { useKitLabels, useKitLocale, type LabelOverride } from "../i18n/kit-labels";
15
- import { useWindowedRows, WINDOWED_ROW_INDEX } from "../hooks/use-windowed-rows";
16
- import { ToggleGroup } from "./toggle-group";
17
- import { Button } from "./button";
18
- import { FIELD_INVALID, FIELD_TOUCH_TEXT } from "./field-base";
19
- import { FOCUS_RING } from "./focus-ring";
20
- import { Textarea } from "./textarea";
21
- import { DEFAULT_MEASURED_GRID_LABELS } from "./measured-grid-labels";
22
-
23
- /**
24
- * A measured table: a fixed set of numeric columns, typed cell by cell or pasted as a
25
- * block out of a spreadsheet — and the hook that holds it as a draft.
26
- *
27
- * Moved from Lenkbank (`shared/ui/measured-grid.tsx`), where four gear editors and a
28
- * setpoint dialog type rig measurements into it. Nothing in it knows what a column
29
- * holds: the caller passes `{ label, unit }[]`, and the vocabulary of this file is
30
- * cells, rows, a caret and a paste. The lexing under it is `@eifi1/ui-kit/table-text`.
31
- *
32
- * What it is NOT: a `DataTable` mode (that one finds rows among many; this one types
33
- * numbers into columns), a spreadsheet (no formulas, no multi-cell selection, no undo
34
- * beyond the browser's per-input one), or typed columns — every cell is a string that
35
- * should read as a number.
36
- */
37
-
38
- /**
39
- * Every string the grid can speak — the `measuredGrid` namespace of
40
- * `<UiKitProvider labels>`, overridable per instance through the `labels` prop. The
41
- * ones that carry a number are functions of it, for the reason `DataTableLabels` gives:
42
- * the grammar around a count moves with it in most languages.
43
- */
44
- export interface MeasuredGridLabels {
45
- /** Accessible name of the cells/text toggle. */
46
- view: string;
47
- cellsView: string;
48
- textView: string;
49
- addRow: string;
50
- /** The row's remove button, given its 1-based number. */
51
- removeRow: (row: number) => string;
52
- /** Empties the whole table. */
53
- clear: string;
54
- /** The footer's standing note that a block can be pasted into any cell. */
55
- pasteHint: string;
56
- /**
57
- * Accessible name of one cell's input, given its column's label and 1-based row.
58
- * A screen reader in a grid announces the headers on its own when the caret crosses
59
- * one; this is what it reads when the caret lands on an input with no crossing — and
60
- * what a voice-control user says to reach it.
61
- */
62
- cell: (column: string, row: number) => string;
63
- /** The row-number column's header, which shows only "#". */
64
- rowNumber: string;
65
- /** The remove-button column's header, which shows nothing. */
66
- rowActions: string;
67
- /** The grid's description: how its keyboard works. Read once, on entry. */
68
- keyboardHint: string;
69
- /** The text view could not read this 1-based line of what was typed or pasted. */
70
- lineError: (line: number) => string;
71
- /** How many filled rows (measured points) the table holds. */
72
- points: (count: number) => string;
73
- /** How many cells are typed but are not numbers. */
74
- problems: (count: number) => string;
75
- }
76
-
77
- // Defined in ./measured-grid-labels, which holds no component code (0.34, KS U8).
78
- export { DEFAULT_MEASURED_GRID_LABELS };
79
-
80
- /** One column of a measured table: what it holds and what it is measured in. The unit
81
- * is separate from the name because the header shows it small and underneath, and
82
- * because a column with no unit (a count, an index) should not render empty brackets. */
83
- export interface MeasuredGridColumn {
84
- label: string;
85
- unit?: string;
86
- }
87
-
88
- /** The two ways to look at the same table. */
89
- export type MeasuredGridView = "cells" | "text";
90
-
91
- /** A cell that has not been typed into yet. Distinguished from `"0"` on purpose: an
92
- * empty cell is a hole in the measurement, and a table with a hole is not one to save. */
93
- const BLANK = "";
94
-
95
- /** Height of one grid row at Normal text size, in px — the windowing's ESTIMATE since
96
- * 0.32 (docs/text-size-harmonization.md §10.9): `useWindowedRows` multiplies it by the
97
- * text size's scale (35 px at Large, 42 at Extra large) and then measures the rows it
98
- * renders, so a row is never cut to a height the type has outgrown. */
99
- const DEFAULT_ROW_HEIGHT = 28;
100
-
101
- const ALL_VIEWS: readonly MeasuredGridView[] = ["cells", "text"];
102
-
103
- /** A number-shaped cell written with the locale's mark. The lexer hands back points;
104
- * a German user typed commas and should read commas back. Anything that is not a
105
- * number is left exactly as it was, so the mistake stays visible where it was made. */
106
- const withMark = (cell: string, mark: "," | ".") =>
107
- mark === "," && isCellNumber(cell) ? cell.replace(".", ",") : cell;
108
-
109
- /** A computed number as a draft cell: rounded to `digits`, half away from zero as the
110
- * figure is written (1.005 → 1.01), with no trailing zeros. `toFixed` rounded the binary
111
- * value (1.00499… → "1"), a fourth rule beside lib/round's, which BUG-11 made the kit's
112
- * one (0.52, refactor audit 2026-10-30, DUP-14). */
113
- const formatCell = (value: number, digits: number, mark: "," | ".") =>
114
- withMark(String(roundHalfAway(value, digits)), mark);
115
-
116
- const hasContent = (row: readonly string[]) => row.some((cell) => cell.trim() !== "");
117
-
118
- export interface UseMeasuredRowsOptions {
119
- /** Decimals a computed number is rounded to on its way into a cell. Default 4. */
120
- digits?: number;
121
- /** BCP 47 tag whose decimal mark the cells are written with, else the
122
- * `<UiKitProvider locale>`, else the runtime's. */
123
- locale?: string;
124
- }
125
-
126
- export interface MeasuredRows {
127
- /** The draft, as text — what the grid shows and edits. */
128
- cells: string[][];
129
- setCells: (next: string[][]) => void;
130
- /** The filled rows as numbers — EMPTY until the table is `ready`. */
131
- rows: number[][];
132
- /** Replace the whole table with computed numbers (a generated shape, say). */
133
- setRows: (next: number[][]) => void;
134
- /** At least two filled rows, and every cell in them is a number. */
135
- ready: boolean;
136
- /** How many cells are typed but are not numbers — what the grid marks invalid. */
137
- problems: number;
138
- /** Everything `MeasuredGrid` needs, so a caller spreads it in one line. */
139
- props: { cells: string[][]; onCells: (next: string[][]) => void };
140
- }
141
-
142
- /**
143
- * The draft a measured table is edited as.
144
- *
145
- * **Strings, not numbers.** A cell is text while it is being typed — `"-"`, `"1."` and
146
- * `"1e"` are all states a number passes through on its way to being one, and a grid
147
- * that parses on every keystroke turns each of them into a `NaN` and then into a `0`.
148
- * So the draft is text, and the numbers are what falls out when every cell is one.
149
- *
150
- * **"Whole" is a question this answers**, because every editor asks it before it
151
- * offers to save: `ready` wants at least two filled rows with a number in every cell.
152
- * An empty cell is a hole in the measurement, not a zero; a wholly empty row is not a
153
- * row at all (it is what walking off the bottom of the grid leaves behind).
154
- *
155
- * `initial` is read once, like `useState`'s.
156
- */
157
- export function useMeasuredRows(
158
- initial: number[][] | (() => number[][]),
159
- options: UseMeasuredRowsOptions = {},
160
- ): MeasuredRows {
161
- const { digits = 4 } = options;
162
- const mark = decimalMark(useKitLocale(options.locale));
163
- const [cells, setCells] = useState<string[][]>(() =>
164
- (typeof initial === "function" ? initial() : initial).map((row) =>
165
- row.map((value) => formatCell(value, digits, mark)),
166
- ),
167
- );
168
-
169
- const { rows, ready, problems } = useMemo(() => {
170
- const filled = cells.filter(hasContent);
171
- const whole = filled.length >= 2 && filled.every((row) => row.every(isCellNumber));
172
- return {
173
- rows: whole ? filled.map((row) => row.map(cellNumber)) : [],
174
- ready: whole,
175
- problems: filled.flat().filter((cell) => cell.trim() !== "" && !isCellNumber(cell)).length,
176
- };
177
- }, [cells]);
178
-
179
- const setRows = useCallback(
180
- (next: number[][]) => setCells(next.map((row) => row.map((value) => formatCell(value, digits, mark)))),
181
- [digits, mark],
182
- );
183
- const props = useMemo(() => ({ cells, onCells: setCells }), [cells]);
184
-
185
- return { cells, setCells, rows, setRows, ready, problems, props };
186
- }
187
-
188
- export interface MeasuredGridProps extends Omit<ComponentPropsWithRef<"div">, "children" | "onChange"> {
189
- /** What the table is — shown above it, and the grid's accessible name. */
190
- label: string;
191
- /** A note under the table (which columns a layout expects, say). Also the grid's
192
- * description. */
193
- hint?: ReactNode;
194
- columns: readonly MeasuredGridColumn[];
195
- /** The draft — typically `useMeasuredRows().props`. */
196
- cells: string[][];
197
- onCells: (next: string[][]) => void;
198
- /** Read-only: the cells can still be walked and read, nothing can be changed. */
199
- disabled?: boolean;
200
- /** Which views the toggle offers, the first being where it opens. Default both;
201
- * one view hides the toggle. */
202
- views?: ReadonlyArray<MeasuredGridView>;
203
- /** A row's height at Normal text size, in px. Default 28. Since 0.32 it is the
204
- * windowing's estimate and each row's minimum, multiplied by the text size's scale;
205
- * the rendered rows are measured (docs/text-size-harmonization.md §10.9). */
206
- rowHeight?: number;
207
- /** BCP 47 tag for the decimal mark of cells written by a paste or the text view,
208
- * and for the row numbers; else the `<UiKitProvider locale>`. */
209
- locale?: string;
210
- labels?: LabelOverride<MeasuredGridLabels>;
211
- }
212
-
213
- /**
214
- * A measured table as a grid of cells, one number each, with a text view beside it.
215
- *
216
- * The grid is the primary form because a linkage typed off a drawing arrives as
217
- * numbers somebody reads out loud, and a textarea made that an exercise in counting
218
- * tab characters. The paste still works: a block pasted into any cell fills from that
219
- * cell outwards, growing the table to fit. The text view is kept for what a grid is
220
- * worst at — reading a thousand-row export back in one piece.
221
- *
222
- * **It is a grid in the APG sense**, which the Lenkbank original was not (a `<table>`
223
- * of inputs, fifteen tab stops per row). One tab stop — the roving tabindex — and the
224
- * keyboard inside it, as a spreadsheet has it:
225
- *
226
- * - **Arrows** move between cells. Left/Right flip under `dir="rtl"`.
227
- * - **Home/End** go to the first/last column; with Ctrl (or ⌘), to the first/last
228
- * cell of the table. **PageUp/PageDown** move a screenful.
229
- * - **Enter** (and ArrowDown) move down a column, and past the last row ADD one —
230
- * typing down a column is how measured data is entered, and stopping at the last
231
- * row to reach for a button is what makes people paste instead. Shift+Enter moves up.
232
- * - **Typing** replaces the cell: arriving by keyboard selects its text, so the first
233
- * key overwrites it. That is the edit mode data entry wants, entered without a key.
234
- * **F2** edits in place instead (caret at the end). Either way the cell is then
235
- * *editing*: Left/Right move the caret, and cross to the next cell only at the edge
236
- * of the text; Home/End stay in the text. **Escape** puts back what the cell held
237
- * when the caret arrived, and leaves editing.
238
- *
239
- * APG's grid pattern pairs Enter with F2 as the keys that start editing. Enter is
240
- * spent on "next row" here on purpose — it is the one key a person typing a column of
241
- * numbers presses between every one of them, and every spreadsheet spends it the same
242
- * way — and typing-to-replace makes an explicit "start editing" key unnecessary for
243
- * the common case. F2 remains for the uncommon one.
244
- */
245
- export function MeasuredGrid({
246
- label,
247
- hint,
248
- columns,
249
- cells,
250
- onCells,
251
- disabled,
252
- views = ALL_VIEWS,
253
- rowHeight = DEFAULT_ROW_HEIGHT,
254
- locale: localeProp,
255
- labels: labelsProp,
256
- className,
257
- ...rest
258
- }: MeasuredGridProps) {
259
- const labels = useKitLabels("measuredGrid", DEFAULT_MEASURED_GRID_LABELS, labelsProp);
260
- const locale = useKitLocale(localeProp);
261
- const mark = decimalMark(locale);
262
- const id = useId();
263
- const labelId = `${id}-label`;
264
- const hintId = `${id}-hint`;
265
- const keysId = `${id}-keys`;
266
- const offered = views.length ? views : ALL_VIEWS;
267
- const [chosen, setChosen] = useState<MeasuredGridView>(offered[0]);
268
- const view = offered.includes(chosen) ? chosen : offered[0];
269
-
270
- return (
271
- // `relative` so the keyboard description below can be `sr-only` without escaping
272
- // to the initial containing block (see sr-only-containment.test).
273
- <div {...rest} className={cn("relative", className)}>
274
- <div className="mb-1 flex flex-wrap items-center justify-between gap-2">
275
- <span id={labelId} className="text-caption font-medium text-muted">
276
- {label}
277
- </span>
278
- {offered.length > 1 && (
279
- <ToggleGroup
280
- className="w-auto"
281
- aria-label={labels.view}
282
- value={view}
283
- onChange={setChosen}
284
- options={offered.map((value) => ({
285
- value,
286
- label: value === "cells" ? labels.cellsView : labels.textView,
287
- }))}
288
- />
289
- )}
290
- </div>
291
- {view === "cells" ? (
292
- <CellGrid
293
- columns={columns}
294
- cells={cells}
295
- onCells={onCells}
296
- disabled={disabled}
297
- rowHeight={rowHeight}
298
- locale={locale}
299
- mark={mark}
300
- labels={labels}
301
- labelledBy={labelId}
302
- describedBy={hint ? `${keysId} ${hintId}` : keysId}
303
- />
304
- ) : (
305
- <TextView
306
- columns={columns}
307
- cells={cells}
308
- onCells={onCells}
309
- disabled={disabled}
310
- mark={mark}
311
- labels={labels}
312
- labelledBy={labelId}
313
- describedBy={hint ? hintId : undefined}
314
- />
315
- )}
316
- {hint && (
317
- <p id={hintId} className="mt-1 px-1 text-caption text-muted">
318
- {hint}
319
- </p>
320
- )}
321
- {view === "cells" && (
322
- <span id={keysId} className="sr-only">
323
- {labels.keyboardHint}
324
- </span>
325
- )}
326
- </div>
327
- );
328
- }
329
-
330
- /** Where the caret is. Held in state rather than read off `document`, because a
331
- * windowed grid unmounts the cell being walked towards: the move is decided first and
332
- * focused after the row it lands on has been rendered. */
333
- interface Caret {
334
- row: number;
335
- column: number;
336
- }
337
-
338
- interface ViewProps {
339
- columns: readonly MeasuredGridColumn[];
340
- cells: string[][];
341
- onCells: (next: string[][]) => void;
342
- disabled?: boolean;
343
- mark: "," | ".";
344
- labels: MeasuredGridLabels;
345
- labelledBy: string;
346
- describedBy?: string;
347
- }
348
-
349
- function CellGrid({
350
- columns,
351
- cells,
352
- onCells,
353
- disabled,
354
- rowHeight,
355
- locale,
356
- mark,
357
- labels,
358
- labelledBy,
359
- describedBy,
360
- }: ViewProps & { rowHeight: number; locale: string | undefined }) {
361
- const scrollRef = useRef<HTMLDivElement>(null);
362
- const headRef = useRef<HTMLDivElement>(null);
363
- const width = columns.length;
364
- const blankRow = () => columns.map(() => BLANK);
365
- // At least one row to type into: a grid with nothing in it has nowhere to put the
366
- // first number, and "add a row" is not the first thing to ask of someone who has
367
- // just opened an empty table. It is not written back until something is typed.
368
- const grid = cells.length ? cells : [blankRow()];
369
- const { first, last, totalHeight, offsetOf, heightOf, estimate, measureRef } = useWindowedRows(
370
- grid.length,
371
- rowHeight,
372
- scrollRef,
373
- );
374
- const rowNumber = useMemo(() => new Intl.NumberFormat(locale), [locale]);
375
-
376
- // The remove buttons are the last column of the grid, reachable by the arrows like
377
- // any cell — except where they are disabled (a read-only grid, or the placeholder
378
- // row of an empty one), because a disabled button cannot hold the tab stop.
379
- const removable = !disabled && cells.length > 0;
380
- const lastColumn = removable ? width : width - 1;
381
-
382
- const [caret, setCaret] = useState<Caret>({ row: 0, column: 0 });
383
- // Clamped on read, not corrected in an effect: rows removed or columns changed from
384
- // outside must never leave the tab stop on a cell that is not there.
385
- const at = { row: Math.min(caret.row, grid.length - 1), column: Math.min(caret.column, lastColumn) };
386
- /** Whether the caret cell is being edited in place (see the component note). */
387
- const [editing, setEditing] = useState(false);
388
- /** A cell that has to take focus once it exists — one commit away when the move
389
- * crossed the edge of the window. `select` is arrival by keyboard. */
390
- const pending = useRef<(Caret & { select: boolean }) | null>(null);
391
- /** What the caret cell held when the caret arrived: what Escape puts back. */
392
- const origin = useRef(BLANK);
393
- /** The next focus was a pointer's: place the caret where it was clicked, edit. */
394
- const pointer = useRef(false);
395
-
396
- useEffect(() => {
397
- const target = pending.current;
398
- if (!target) return;
399
- const element = scrollRef.current?.querySelector<HTMLElement>(`[data-cell="${target.row}:${target.column}"]`);
400
- if (!element) return;
401
- pending.current = null;
402
- // `preventScroll`: `reveal` already scrolled the row clear of the sticky header,
403
- // which the browser's own scroll-into-view does not know is there.
404
- element.focus({ preventScroll: true });
405
- if (target.select && element instanceof HTMLInputElement) element.select();
406
- });
407
-
408
- const pad = (row: readonly string[] | undefined) =>
409
- Array.from({ length: width }, (_, index) => row?.[index] ?? BLANK);
410
-
411
- const setCell = (row: number, column: number, value: string) => {
412
- const next = grid.map(pad);
413
- next[row][column] = value;
414
- onCells(next);
415
- };
416
-
417
- /** Scroll `row` into the band below the sticky header. */
418
- const reveal = (row: number) => {
419
- const element = scrollRef.current;
420
- if (!element) return;
421
- const room = element.clientHeight - (headRef.current?.offsetHeight ?? 0);
422
- if (room <= 0) return;
423
- // Measured where the row has been rendered, the scaled estimate where not (§10.9).
424
- const top = offsetOf(row);
425
- const height = heightOf(row);
426
- if (top < element.scrollTop) element.scrollTop = top;
427
- else if (top + height > element.scrollTop + room) element.scrollTop = top + height - room;
428
- };
429
-
430
- const focusCell = (row: number, column: number) => {
431
- reveal(row);
432
- pending.current = { row, column, select: true };
433
- setCaret({ row, column });
434
- setEditing(false);
435
- };
436
-
437
- const go = (row: number, column: number) => {
438
- const target = {
439
- row: Math.max(0, Math.min(row, grid.length - 1)),
440
- column: Math.max(0, Math.min(column, lastColumn)),
441
- };
442
- if (target.row === at.row && target.column === at.column) return;
443
- focusCell(target.row, target.column);
444
- };
445
-
446
- /** Down a column — and off the bottom, a new row, unless the last one is still
447
- * empty: holding ArrowDown should not leave a trail of blank rows behind it. */
448
- const down = (row: number, column: number) => {
449
- if (row + 1 < grid.length) return go(row + 1, column);
450
- if (disabled || !hasContent(grid[row])) return;
451
- onCells([...grid.map(pad), blankRow()]);
452
- focusCell(row + 1, Math.min(column, width - 1));
453
- };
454
-
455
- const page = () => {
456
- const element = scrollRef.current;
457
- const room = element ? element.clientHeight - (headRef.current?.offsetHeight ?? 0) : 0;
458
- // No layout (a hidden pane, jsdom): a fixed ten rather than one row at a time.
459
- return room > 0 ? Math.max(1, Math.floor(room / estimate) - 1) : 10;
460
- };
461
-
462
- /**
463
- * On each cell rather than once on the grid, for the reason `MiniCalendar` gives:
464
- * the cell is where focus is, and a container listening for keys it cannot receive
465
- * is the shape `jsx-a11y/interactive-supports-focus` objects to.
466
- */
467
- const onCellKeyDown = (event: KeyboardEvent<HTMLElement>, row: number, column: number) => {
468
- const input = event.currentTarget instanceof HTMLInputElement ? event.currentTarget : null;
469
- const inText = Boolean(input) && editing;
470
- const modified = event.ctrlKey || event.metaKey;
471
- switch (event.key) {
472
- case "ArrowUp":
473
- event.preventDefault();
474
- return go(row - 1, column);
475
- case "ArrowDown":
476
- event.preventDefault();
477
- return down(row, column);
478
- case "Enter":
479
- // On the remove button Enter is the button's own.
480
- if (!input) return;
481
- event.preventDefault();
482
- return event.shiftKey ? go(row - 1, column) : down(row, column);
483
- case "ArrowLeft":
484
- case "ArrowRight": {
485
- // Along the reading direction: ArrowLeft is "next column" in RTL.
486
- const forward = horizontalStep(event.key, event.currentTarget) === 1;
487
- if (inText && input) {
488
- const edge = forward ? input.value.length : 0;
489
- // Inside the text the caret moves; only at its edge does it leave the cell.
490
- if (input.selectionStart !== edge || input.selectionEnd !== edge) return;
491
- }
492
- event.preventDefault();
493
- return go(row, column + (forward ? 1 : -1));
494
- }
495
- case "Home":
496
- case "End": {
497
- if (inText && !modified) return;
498
- event.preventDefault();
499
- const home = event.key === "Home";
500
- if (modified) return go(home ? 0 : grid.length - 1, home ? 0 : width - 1);
501
- return go(row, home ? 0 : width - 1);
502
- }
503
- case "PageUp":
504
- event.preventDefault();
505
- return go(row - page(), column);
506
- case "PageDown":
507
- event.preventDefault();
508
- return go(row + page(), column);
509
- case "F2":
510
- if (!input || disabled) return;
511
- event.preventDefault();
512
- setEditing(true);
513
- input.setSelectionRange(input.value.length, input.value.length);
514
- return;
515
- case "Escape":
516
- // Not editing: nothing of ours to undo, so the key belongs to whatever the
517
- // grid sits in — the dialog it is in closes, as it should.
518
- if (!input || !editing) return;
519
- event.preventDefault();
520
- event.stopPropagation();
521
- if (input.value !== origin.current) setCell(row, column, origin.current);
522
- pending.current = { row, column, select: true };
523
- setEditing(false);
524
- return;
525
- }
526
- };
527
-
528
- /**
529
- * A pasted block, written in from the cell it was pasted into.
530
- *
531
- * Rows past the end grow the table; columns past the last are dropped, because a
532
- * paste wider than the measurement is a paste with a trailing timestamp column and
533
- * not an error worth refusing. One header line is skipped — pasted data almost
534
- * always has one. Each line is read on its own evidence (`splitRow`, the per-line
535
- * comma rule), so one line cannot change what another means.
536
- */
537
- const paste = (row: number, column: number, text: string) => {
538
- const lines = text.split(/\r?\n/).filter((line) => line.trim() !== "");
539
- if (!lines.length) return;
540
- const block = lines.map(splitRow);
541
- if (block.length > 1 && block[0].some((cell) => !isCellNumber(cell))) block.shift();
542
-
543
- const height = Math.max(grid.length, row + block.length);
544
- const next = Array.from({ length: height }, (_, index) => pad(grid[index]));
545
- block.forEach((line, downwards) => {
546
- line.forEach((cell, across) => {
547
- const target = column + across;
548
- if (target < width) next[row + downwards][target] = withMark(cell.trim(), mark);
549
- });
550
- });
551
- onCells(next);
552
- pending.current = { row, column, select: true };
553
- setEditing(false);
554
- };
555
-
556
- const template = `2.5rem repeat(${width}, minmax(5.5rem, 1fr)) 2rem`;
557
- // The caret's row is mounted even when it has been scrolled out of the window: it
558
- // holds the grid's only tab stop, and a tab stop that is not in the DOM is a grid
559
- // Tab walks straight past.
560
- const mounted: number[] = [];
561
- for (let index = first; index < last; index += 1) mounted.push(index);
562
- if (at.row < first || at.row >= last) mounted.push(at.row);
563
-
564
- const filled = cells.filter(hasContent);
565
- const problems = filled.flat().filter((cell) => cell.trim() !== "" && !isCellNumber(cell)).length;
566
-
567
- return (
568
- <div className="rounded-md border border-subtle bg-surface">
569
- <div ref={scrollRef} className="max-h-72 overflow-auto">
570
- <div
571
- role="grid"
572
- aria-labelledby={labelledBy}
573
- aria-describedby={describedBy}
574
- // The true size, not the mounted one: a screen reader otherwise reports the
575
- // thirty rows in the window as the whole table.
576
- aria-rowcount={grid.length + 1}
577
- aria-colcount={width + 2}
578
- aria-readonly={disabled || undefined}
579
- className="text-xs"
580
- style={{ minWidth: `calc(4.5rem + ${width} * 5.5rem)` }}
581
- >
582
- {/* The header stays put vertically and scrolls sideways with the body, so a
583
- fifteen-column linkage can be read without losing which column is which. */}
584
- <div ref={headRef} role="rowgroup" className="sticky top-0 z-10 bg-surface-2">
585
- <div
586
- role="row"
587
- aria-rowindex={1}
588
- className="grid border-b border-subtle"
589
- style={{ gridTemplateColumns: template }}
590
- >
591
- <div
592
- role="columnheader"
593
- aria-label={labels.rowNumber}
594
- className="flex items-end justify-end px-1 py-1 text-micro text-placeholder"
595
- >
596
- #
597
- </div>
598
- {columns.map((column, index) => (
599
- <div key={index} role="columnheader" className="min-w-0 border-s border-subtle px-2 py-1 text-end">
600
- <span className="block truncate font-medium text-primary">{column.label}</span>
601
- {column.unit && <span className="block truncate text-micro text-muted">{column.unit}</span>}
602
- </div>
603
- ))}
604
- <div role="columnheader" aria-label={labels.rowActions} className="border-s border-subtle" />
605
- </div>
606
- </div>
607
- {/* Only the rows in the window are mounted — a swept linkage is thousands of
608
- them across fifteen inputs — each placed at its own offset, so mounting
609
- one more (the caret's) costs nothing in the arithmetic. Since 0.32 a row
610
- is at least the scaled estimate tall and measured as it renders (§10.9):
611
- `minHeight`, not `height`, so the type at Extra large is never cut. */}
612
- <div role="rowgroup" className="relative" style={{ height: totalHeight }}>
613
- {mounted.map((index) => {
614
- const row = grid[index];
615
- return (
616
- <div
617
- key={index}
618
- ref={measureRef}
619
- {...{ [WINDOWED_ROW_INDEX]: index }}
620
- role="row"
621
- aria-rowindex={index + 2}
622
- className="absolute inset-x-0 grid hover:bg-hover"
623
- style={{ top: offsetOf(index), minHeight: estimate, gridTemplateColumns: template }}
624
- >
625
- <div
626
- role="rowheader"
627
- className="flex items-center justify-end px-1 text-micro tabular-nums text-placeholder"
628
- >
629
- {rowNumber.format(index + 1)}
630
- </div>
631
- {columns.map((column, columnIndex) => {
632
- const value = row[columnIndex] ?? BLANK;
633
- const bad = value.trim() !== "" && !isCellNumber(value);
634
- const isCaret = at.row === index && at.column === columnIndex;
635
- return (
636
- <div key={columnIndex} role="gridcell" className="min-w-0 border-s border-subtle">
637
- <input
638
- data-cell={`${index}:${columnIndex}`}
639
- value={value}
640
- // `readOnly`, not `disabled`: a disabled input cannot take
641
- // focus, and a read-only table should still be walkable.
642
- readOnly={disabled}
643
- tabIndex={isCaret ? 0 : -1}
644
- inputMode="decimal"
645
- spellCheck={false}
646
- autoComplete="off"
647
- aria-label={labels.cell(column.label, index + 1)}
648
- // Said, not only painted: the ring is what a sighted user
649
- // sees, `aria-invalid` is what a screen reader reads.
650
- aria-invalid={bad || undefined}
651
- className={cn(
652
- "block size-full bg-transparent px-2 text-end tabular-nums text-primary outline-none",
653
- // A cell is a field: 16 px on touch, or iOS zooms on focus (§10.1).
654
- FIELD_TOUCH_TEXT,
655
- // Arriving selects the text (typing replaces it); editing
656
- // in place is the plain surface with a caret in it.
657
- // The kit's focus frame (§5), inset so the next cell's
658
- // border does not paint over it. A text input is
659
- // `:focus-visible` however it was focused.
660
- "focus:bg-brand-soft",
661
- FOCUS_RING,
662
- "focus-visible:ring-inset",
663
- isCaret && editing && "focus:bg-surface",
664
- disabled && "text-muted",
665
- bad && cn(FIELD_INVALID, "ring-inset"),
666
- )}
667
- onMouseDown={(event) => {
668
- // A click places a caret, which is editing. On the cell
669
- // already focused there is no focus event to say so.
670
- if (document.activeElement === event.currentTarget) setEditing(!disabled);
671
- else pointer.current = true;
672
- }}
673
- onFocus={(event) => {
674
- origin.current = event.currentTarget.value;
675
- if (!isCaret) setCaret({ row: index, column: columnIndex });
676
- const byPointer = pointer.current;
677
- pointer.current = false;
678
- setEditing(byPointer && !disabled);
679
- if (!byPointer) event.currentTarget.select();
680
- }}
681
- onBlur={() => setEditing(false)}
682
- onChange={(event) => {
683
- setCell(index, columnIndex, event.target.value);
684
- setEditing(true);
685
- }}
686
- onPaste={(event) => {
687
- if (disabled) return;
688
- const text = event.clipboardData.getData("text/plain");
689
- // One cell's worth of text is an ordinary paste, and the
690
- // browser does it better than this would; only a block is
691
- // the grid's business.
692
- if (!/[\t\n;]/.test(text)) return;
693
- event.preventDefault();
694
- paste(index, columnIndex, text);
695
- }}
696
- onKeyDown={(event) => onCellKeyDown(event, index, columnIndex)}
697
- />
698
- </div>
699
- );
700
- })}
701
- <div role="gridcell" className="flex items-center justify-center border-s border-subtle">
702
- <button
703
- type="button"
704
- data-cell={`${index}:${width}`}
705
- disabled={!removable}
706
- tabIndex={at.row === index && at.column === width ? 0 : -1}
707
- aria-label={labels.removeRow(index + 1)}
708
- className={cn(
709
- "rounded p-1 text-placeholder outline-none hover:text-danger disabled:cursor-default disabled:hover:text-placeholder",
710
- FOCUS_RING,
711
- )}
712
- onKeyDown={(event) => onCellKeyDown(event, index, width)}
713
- onFocus={() => {
714
- if (at.row !== index || at.column !== width) setCaret({ row: index, column: width });
715
- }}
716
- onClick={() => {
717
- const next = grid.filter((_, other) => other !== index);
718
- onCells(next);
719
- // Focus stays in the column, on the row that moved up into
720
- // this one; an emptied table sends it to the first cell.
721
- if (next.length) focusCell(Math.min(index, next.length - 1), width);
722
- else focusCell(0, 0);
723
- }}
724
- >
725
- <Trash2 aria-hidden className="size-3.5" />
726
- </button>
727
- </div>
728
- </div>
729
- );
730
- })}
731
- </div>
732
- </div>
733
- </div>
734
- <div className="flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-subtle px-2 py-1.5">
735
- <Button
736
- variant="ghost"
737
- size="sm"
738
- disabled={disabled}
739
- onClick={() => {
740
- onCells([...grid.map(pad), blankRow()]);
741
- focusCell(grid.length, 0);
742
- }}
743
- >
744
- <Plus aria-hidden className="size-3.5" /> {labels.addRow}
745
- </Button>
746
- <Button
747
- variant="ghost"
748
- size="sm"
749
- className="text-muted"
750
- disabled={disabled || !cells.length}
751
- onClick={() => {
752
- onCells([]);
753
- // The button is about to disable itself; focus must not go down with it.
754
- focusCell(0, 0);
755
- }}
756
- >
757
- <Eraser aria-hidden className="size-3.5" /> {labels.clear}
758
- </Button>
759
- <span className="text-caption tabular-nums text-muted">
760
- {/* bdi: an LTR label ("3 points") in an RTL grid would reorder to "points 3". */}
761
- <bdi>{labels.points(filled.length)}</bdi>
762
- </span>
763
- {problems > 0 && <span className="text-caption text-danger">{labels.problems(problems)}</span>}
764
- <span className="ms-auto flex items-center gap-1 text-caption text-muted">
765
- <ClipboardPaste aria-hidden className="size-3.5" /> {labels.pasteHint}
766
- </span>
767
- </div>
768
- </div>
769
- );
770
- }
771
-
772
- const textOf = (cells: string[][]) => cells.map((row) => row.join("\t")).join("\n");
773
-
774
- /**
775
- * The same table as text.
776
- *
777
- * Kept because the grid is worst at exactly what a textarea is best at: reading a long
778
- * export back in one piece. It commits on blur — through `parseRows`, the paste door —
779
- * and a line it cannot read is NAMED rather than dropped: half a sweep saved as a
780
- * measurement is worse than a refusal.
781
- */
782
- function TextView({ columns, cells, onCells, disabled, mark, labels, labelledBy, describedBy }: ViewProps) {
783
- const text = textOf(cells);
784
- const [draft, setDraft] = useState(text);
785
- const [errorLine, setErrorLine] = useState<number | null>(null);
786
- // Follow the table when it changes from outside (a generated shape, a cleared form).
787
- // Compared as text, so a caller that rebuilds the same cells every render does not
788
- // wipe what is being typed.
789
- const [seen, setSeen] = useState(text);
790
- if (seen !== text) {
791
- setSeen(text);
792
- setDraft(text);
793
- setErrorLine(null);
794
- }
795
-
796
- const commit = () => {
797
- // Untouched: nothing to read back, and re-reading would rewrite every cell in the
798
- // lexer's spelling of it.
799
- if (draft === text) return;
800
- if (!draft.trim()) {
801
- setErrorLine(null);
802
- onCells([]);
803
- return;
804
- }
805
- const parsed = parseRows(draft, columns.length);
806
- if ("error" in parsed) {
807
- setErrorLine(parsed.error);
808
- return;
809
- }
810
- setErrorLine(null);
811
- onCells(parsed.rows.map((row) => row.map((value) => withMark(String(value), mark))));
812
- };
813
-
814
- const lines = draft.split("\n").filter((line) => line.trim()).length;
815
-
816
- return (
817
- <div>
818
- <Textarea
819
- aria-labelledby={labelledBy}
820
- aria-describedby={describedBy}
821
- rows={10}
822
- value={draft}
823
- readOnly={disabled}
824
- spellCheck={false}
825
- className="font-mono text-xs"
826
- error={errorLine !== null ? labels.lineError(errorLine) : undefined}
827
- onChange={(event) => setDraft(event.target.value)}
828
- onBlur={commit}
829
- />
830
- <p className="mt-1 px-1 text-caption text-muted">
831
- {columns.map((column) => column.label).join(" · ")}
832
- {" — "}
833
- <bdi>{labels.points(lines)}</bdi>
834
- </p>
835
- </div>
836
- );
837
- }