@eifi1/ui-kit 0.54.0 → 0.55.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 +5 -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 +6 -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 +80 -0
  113. package/dist/components/legended-series-chart.js +70 -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 +5 -9
  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,1087 +0,0 @@
1
- import { useEffect, useId, useMemo, useRef, useState } from "react";
2
- import type { ComponentPropsWithoutRef, KeyboardEvent, ReactNode, Ref, RefObject } from "react";
3
- import { Calendar, ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";
4
- import { cn } from "../lib/cn";
5
- import { dirOf, horizontalStep, type Direction } from "../lib/direction";
6
- import { monthKey, pad } from "../lib/dates";
7
- import { upperFirst } from "../lib/text-case";
8
- import { Button } from "./button";
9
- import { FIELD_FLOATING_PAD, FIELD_INVALID, FIELD_TRIGGER } from "./field-base";
10
- import { IconButton } from "./icon-button";
11
- import { FOCUS_RING, FOCUS_RING_WIDTH } from "./focus-ring";
12
- import { Popover } from "./popover";
13
- import { splitTriggerAria } from "./trigger-aria";
14
- import type { TriggerAria } from "./trigger-aria";
15
- import { useKitDateFormatter, useKitLabels, useKitLocale, type LabelOverride } from "../i18n/kit-labels";
16
- import { hasContent } from "../lib/presence";
17
- import {
18
- FieldBox,
19
- FieldLabelLine,
20
- LABEL_ABOVE_BOX,
21
- LockedReason,
22
- mergeDescribedBy,
23
- mergeRefs,
24
- useFieldMessages,
25
- useLockReason,
26
- type DisabledReasonDisplay,
27
- type FieldHelpProps,
28
- } from "./field-parts";
29
- import { MonthGrid, clampKey, shiftKey, yearArrowsBlocked } from "./month-grid";
30
- import { DEFAULT_MONTH_PICKER_LABELS } from "./month-picker-labels";
31
- import type { CommitScope } from "./write-lock";
32
-
33
- /**
34
- * Every string the month picker can speak. The month and year names are NOT here —
35
- * they come from `Intl` in the `locale` prop, so they are already in the user's
36
- * language. What is left is the two icon-only year arrows, whose `aria-label` is the
37
- * only name they have, the panel's name, and a month cell's name.
38
- */
39
- export interface MonthPickerLabels {
40
- previousYear: string;
41
- nextYear: string;
42
- /** The popover's accessible name (`role="dialog"`). */
43
- panel: string;
44
- /**
45
- * Accessible name of one month cell, given that month and its year formatted in
46
- * `locale` ("August 2026"). The cell's visible text is the short month alone, and
47
- * "Aug" read out on its own does not say which year the grid is on.
48
- */
49
- month: (monthYear: string) => string;
50
- /** `variant="stepper"`: the icon-only arrows that step the value by one month. */
51
- previousMonth: string;
52
- nextMonth: string;
53
- /** `variant="stepper"`: the button that jumps to the current month. Visible text. */
54
- today: string;
55
- /** `mode="year"`: the popover's accessible name. */
56
- yearPanel: string;
57
- /** `mode="year"`: the icon-only arrows that page the year grid back and forward by a
58
- * page of twelve years. */
59
- earlierYears: string;
60
- laterYears: string;
61
- /** `mode="year"`, `variant="stepper"`: the button that jumps to the current year.
62
- * Visible text. */
63
- thisYear: string;
64
- }
65
-
66
- // Defined in ./month-picker-labels, which holds no component code (0.34, KS U8).
67
- export { DEFAULT_MONTH_PICKER_LABELS };
68
-
69
- /** Merge caller overrides onto the English defaults. */
70
- function useMonthPickerLabels(partial?: Partial<MonthPickerLabels>): MonthPickerLabels {
71
- // Prop > <UiKitProvider> > English, like every labelled component in the kit.
72
- return useKitLabels("monthPicker", DEFAULT_MONTH_PICKER_LABELS, partial);
73
- }
74
-
75
- /**
76
- * `onChange` is omitted from the `<div>` attributes: the DOM event of that name carries
77
- * a `FormEvent`, and this one answers with a month key. Everything else reaches the
78
- * field's root, so a test id or a `data-tour` anchor can find it.
79
- */
80
- export interface MonthPickerProps extends Omit<ComponentPropsWithoutRef<"div">, "onChange">, FieldHelpProps {
81
- /**
82
- * The selected month as a `"YYYY-MM"` key, or `""` for none.
83
- *
84
- * A string rather than `{ year, month }` or a `Date`, for the reason every date in
85
- * this kit is one: it is what `monthKey()` in `lib/dates` produces, it sorts
86
- * chronologically so the bounds are plain `<` / `>`, and it crosses a URL or an API
87
- * without a serialiser. A `{ year, month }` caller converts with
88
- * `` `${year}-${pad(month)}` `` (month 1–12) and back with `key.split("-").map(Number)`.
89
- */
90
- value: string;
91
- /** Called with the picked month as `"YYYY-MM"`. */
92
- onChange: (month: string) => void;
93
- /** Drives the month and year names (`Intl.DateTimeFormat`). Defaults to the
94
- * `<UiKitProvider>` locale, then the runtime's. */
95
- locale?: string;
96
- /**
97
- * Inclusive bounds, as `"YYYY-MM"`. A full ISO date (`"YYYY-MM-DD"`) is accepted and
98
- * read as its month, so a host holding "the first day we have data for" can pass it
99
- * straight in. Months outside are shown but refuse selection; a year arrow refuses
100
- * once the whole year beyond it is out of bounds (`aria-disabled`, so the focus stays
101
- * on the arrow just pressed — 0.52).
102
- */
103
- min?: string;
104
- max?: string;
105
- /** Embedded top-boundary label, matching the other field-shaped controls. */
106
- label?: ReactNode;
107
- /** Trigger text when `value` is `""`. */
108
- placeholder?: string;
109
- disabled?: boolean;
110
- /**
111
- * Why the month cannot be changed — {@link Select}'s `disabledReason`, for a picker
112
- * that SAVES on change (a budget page's month, a calendar view kept per user). The
113
- * trigger stays focusable and `aria-disabled`, the grid does not open, the stepper's
114
- * Today and ‹ › refuse, and `onChange` never fires; the reason is a line under the
115
- * field (or the stepper) at Large and on a touch screen, else in the kit
116
- * {@link Tooltip} (`disabledReasonDisplay`), and on the trigger's `aria-describedby`.
117
- * Wins over `disabled`. 0.52 (refactor audit 2026-10-30, API-3).
118
- */
119
- disabledReason?: ReactNode;
120
- /** Where the reason shows — {@link Button}'s `disabledReasonDisplay`: a line under the
121
- * field at Large and on a touch screen by default, the tooltip otherwise. */
122
- disabledReasonDisplay?: DisabledReasonDisplay;
123
- /**
124
- * This picker COMMITS — picking saves. Under a locked {@link WriteLockProvider} it is
125
- * locked the `disabledReason` way, with the lock's reason; a {@link CommitScope}, as on
126
- * every kit control. A month field inside a form with its own Save stays editable
127
- * under the lock — leave this off there, and put `commit` on the Save. 0.52 (API-3).
128
- */
129
- commit?: CommitScope;
130
- /** Required and unanswered — {@link FIELD_INVALID}. See {@link Input}'s `invalid`. */
131
- invalid?: boolean;
132
- /**
133
- * What is wrong with the month, in the caller's words — {@link Input}'s `error`
134
- * (keksdose K4): under the field, attached to the trigger with `aria-describedby`
135
- * (merged, after any caption), and implies `invalid`. Passing the key keeps the
136
- * field's box while there is no message, so the trigger is never remounted.
137
- */
138
- error?: ReactNode;
139
- /** Standing advice, as on a {@link Select}: text is a caption under the field; a
140
- * {@link FieldHint} rides the label line. */
141
- hint?: ReactNode;
142
- /**
143
- * `"md"` (default): the form field. `"sm"`: the toolbar trigger — 36px tall (an
144
- * `IconButton`'s height) and as wide as the month it shows, for a picker that sits
145
- * between two icon buttons in a page header (keksdose K13: the budget header wrote
146
- * `triggerClassName="h-9 w-auto … py-0"` by hand, live #260 — 34px between two 36px
147
- * buttons, *"the kind of 2px that reads as sloppy"*). Unlabelled pickers only, as on
148
- * {@link Select}: a floating label needs the tall box to float in. The width follows
149
- * the month's name; add a `min-w-*` in `triggerClassName` if the buttons beside it
150
- * must not move as it changes.
151
- */
152
- size?: "sm" | "md";
153
- /**
154
- * `"month"` (default): the value is a month, `"YYYY-MM"`.
155
- *
156
- * `"year"`: the value is a YEAR, `"YYYY"`, and the panel is a grid of years — kastlan's
157
- * budget fiscal year (a `Select` of 2020 to three years ahead) and keksdose's tax tab
158
- * ("this year and four before", tax-tab.tsx:33). `min` / `max` are read as their year
159
- * (`"2022"`, or any longer key). A bounded span of twelve years or fewer is shown
160
- * whole, with no paging; otherwise the grid pages twelve years at a time (PageUp /
161
- * PageDown, or the arrows), starting from `min` when there is one. The stepper
162
- * variant steps a year, and its Today button reads "This year".
163
- *
164
- * A string rather than a number, for the reason the month key is one: it is the
165
- * same type across both modes, it crosses a URL as is, and it sorts. A numeric
166
- * caller converts with `String(year)` and `Number(key)`.
167
- */
168
- mode?: "month" | "year";
169
- /** Intl options for the trigger's text (default: long month + numeric year, or the
170
- * numeric year in `mode="year"`). Win over the provider's `formatDate`. */
171
- formatOptions?: Intl.DateTimeFormatOptions;
172
- /**
173
- * The month to ring as "now", as `"YYYY-MM"`. Defaults to the local calendar's
174
- * current month; pass one to pin it (a test, a host with its own notion of today).
175
- */
176
- currentMonth?: string;
177
- /** User-facing strings; see {@link MonthPickerLabels}. */
178
- labels?: LabelOverride<MonthPickerLabels>;
179
- /** Extra classes for the field's root. */
180
- className?: string;
181
- /** Extra classes for the trigger button — e.g. a compact `h-9 w-auto` trigger
182
- * sitting between two icon buttons in a toolbar. */
183
- triggerClassName?: string;
184
- /**
185
- * `"field"` (default): the field-shaped trigger, for a form.
186
- *
187
- * `"stepper"`: the header of a month PAGE — the month as a heading that opens the
188
- * grid, then Today and ‹ › stepping the value by one month. What a calendar page
189
- * assembled by hand around the field (overriding its trigger to look like a
190
- * heading). `label`, `placeholder`, `invalid`, `hint`, `error`, `size` and
191
- * `triggerClassName` are the field's and are not drawn here; with no `value` the
192
- * arrows step from the current month (or year).
193
- */
194
- variant?: "field" | "stepper";
195
- /** `variant="stepper"`: the heading level the month is set in (`<h2>` by default), or
196
- * `false` for no heading element — the page already has one for the month. */
197
- headingLevel?: 1 | 2 | 3 | 4 | 5 | 6 | false;
198
- /** `variant="stepper"`: draw the Today button. Default `true`. */
199
- showToday?: boolean;
200
- /**
201
- * The TRIGGER — the field's button, or the stepper's heading button — as a React 19
202
- * ref prop (0.34, API-3, refactor audit 2026-10). The picker took none, so
203
- * react-hook-form's focus-on-error reached it only through /rhf's id lookup. Not the
204
- * wrapper, which takes the rest of the props.
205
- */
206
- ref?: Ref<HTMLButtonElement>;
207
- }
208
-
209
- // ── Month keys ────────────────────────────────────────────────────────────
210
-
211
- interface YearMonth {
212
- year: number;
213
- /** 1–12, as in the key. */
214
- month: number;
215
- }
216
-
217
- const KEY = /^(\d{4})-(\d{2})/;
218
-
219
- function parseMonth(key: string | undefined): YearMonth | null {
220
- const m = key ? KEY.exec(key) : null;
221
- if (!m) return null;
222
- const month = Number(m[2]);
223
- return month >= 1 && month <= 12 ? { year: Number(m[1]), month } : null;
224
- }
225
-
226
- function toKey({ year, month }: YearMonth): string {
227
- return `${year}-${pad(month)}`;
228
- }
229
-
230
- /** Move a month key by whole months, carrying into the year. */
231
- function shiftMonth(ym: YearMonth, delta: number): YearMonth {
232
- const index = ym.year * 12 + (ym.month - 1) + delta;
233
- return { year: Math.floor(index / 12), month: (index % 12) + 1 };
234
- }
235
-
236
- /** A bound, normalised to its month key — so `"2024-03-15"` compares as `"2024-03"`. */
237
- function boundKey(bound: string | undefined): string | null {
238
- const ym = parseMonth(bound);
239
- return ym ? toKey(ym) : null;
240
- }
241
-
242
- /** Local-calendar Date for the 1st of a month, for `Intl` to format. */
243
- function firstOf({ year, month }: YearMonth): Date {
244
- return new Date(year, month - 1, 1);
245
- }
246
-
247
- const DEFAULT_TRIGGER_FORMAT: Intl.DateTimeFormatOptions = { month: "long", year: "numeric" };
248
- const YEAR_FORMAT: Intl.DateTimeFormatOptions = { year: "numeric" };
249
-
250
- // ── Year keys ─────────────────────────────────────────────────────────────
251
-
252
- const YEAR = /^(\d{4})/;
253
-
254
- /** The year of `"YYYY"`, `"YYYY-MM"` or `"YYYY-MM-DD"`, or null. */
255
- function parseYear(key: string | undefined): number | null {
256
- const m = key ? YEAR.exec(key) : null;
257
- return m ? Number(m[1]) : null;
258
- }
259
-
260
- // ── Trigger ───────────────────────────────────────────────────────────────
261
-
262
- /** Hand focus back to the trigger when the panel closes with focus still inside it. */
263
- function useFocusBackOnClose(open: boolean, triggerRef: RefObject<HTMLButtonElement | null>) {
264
- const wasOpen = useRef(false);
265
- useEffect(() => {
266
- const justClosed = wasOpen.current && !open;
267
- wasOpen.current = open;
268
- if (!justClosed) return;
269
- // Only when focus went down with the panel. An outside click has already put it
270
- // somewhere real, and dragging it back here would be worse than leaving it.
271
- const active = document.activeElement;
272
- if (!active || active === document.body) triggerRef.current?.focus();
273
- }, [open, triggerRef]);
274
- }
275
-
276
- /** The Popover's handle on the trigger and the picker's own `ref` prop (API-3), as one. */
277
- function useTriggerRef(triggerRef: RefObject<HTMLButtonElement | null>, fieldRef: Ref<HTMLButtonElement> | undefined) {
278
- return useMemo(() => mergeRefs(triggerRef, fieldRef), [triggerRef, fieldRef]);
279
- }
280
-
281
- /**
282
- * The stepper's trigger: the month as a heading-sized button that opens the grid.
283
- *
284
- * Its own text is its name ("September 2026"), so it needs no label of its own, and
285
- * it is `aria-live` for the reason `MiniCalendar`'s caption is: pressing ‹ or › leaves
286
- * focus on the arrow, and the heading is the only thing that says where the arrow
287
- * went. A plain button with `aria-haspopup`, not the field's `combobox` — it does not
288
- * look or behave like a field, and a heading reading "combobox" is a surprise.
289
- */
290
- function MonthHeadingTrigger({
291
- open,
292
- toggle,
293
- triggerRef,
294
- fieldRef,
295
- text,
296
- panelId,
297
- disabled,
298
- locked,
299
- aria,
300
- }: {
301
- open: boolean;
302
- toggle: () => void;
303
- triggerRef: RefObject<HTMLButtonElement | null>;
304
- fieldRef?: Ref<HTMLButtonElement>;
305
- text: string;
306
- panelId: string;
307
- disabled?: boolean;
308
- /** The write lock: the focusable kind of disabled. */
309
- locked: boolean;
310
- aria: TriggerAria;
311
- }) {
312
- useFocusBackOnClose(open, triggerRef);
313
- const setTrigger = useTriggerRef(triggerRef, fieldRef);
314
- return (
315
- <button
316
- ref={setTrigger}
317
- type="button"
318
- disabled={locked ? undefined : disabled}
319
- aria-disabled={locked || undefined}
320
- onClick={() => {
321
- if (!locked) toggle();
322
- }}
323
- aria-haspopup="dialog"
324
- aria-controls={panelId}
325
- aria-expanded={open}
326
- id={aria.id}
327
- aria-label={aria["aria-label"]}
328
- aria-labelledby={aria["aria-labelledby"]}
329
- aria-describedby={aria["aria-describedby"]}
330
- className={cn(
331
- "-ms-1.5 inline-flex h-9 min-w-0 items-center gap-1 rounded-md px-1.5 text-lg font-semibold text-primary transition-colors",
332
- "hover:bg-hover",
333
- FOCUS_RING,
334
- (disabled || locked) && "cursor-not-allowed opacity-50",
335
- )}
336
- >
337
- <span aria-live="polite" className="truncate">
338
- {text || "\u00a0"}
339
- </span>
340
- <ChevronDown aria-hidden className="size-4 shrink-0 text-muted" />
341
- </button>
342
- );
343
- }
344
-
345
- /**
346
- * The field-shaped button that opens the grid. The same shape as `DatePicker`'s
347
- * trigger, for the same reasons written down there: `role="combobox"` so it may carry
348
- * `aria-expanded` / `aria-invalid`, a name made of the label AND the value, and focus
349
- * handed back here when the panel closes with focus still inside it.
350
- */
351
- function MonthFieldTrigger({
352
- open,
353
- toggle,
354
- triggerRef,
355
- fieldRef,
356
- triggerText,
357
- hasValue,
358
- labelledBy,
359
- valueId,
360
- panelId,
361
- padded,
362
- small,
363
- disabled,
364
- locked,
365
- invalid,
366
- className,
367
- aria,
368
- }: {
369
- open: boolean;
370
- toggle: () => void;
371
- triggerRef: RefObject<HTMLButtonElement | null>;
372
- fieldRef?: Ref<HTMLButtonElement>;
373
- triggerText: string;
374
- hasValue: boolean;
375
- labelledBy: string;
376
- /** The caller's naming attributes — see `trigger-aria.ts`. */
377
- aria: TriggerAria;
378
- valueId: string;
379
- panelId: string;
380
- padded: boolean;
381
- /** `size="sm"`: the 36px, content-wide toolbar trigger. */
382
- small: boolean;
383
- disabled?: boolean;
384
- /** The write lock: the focusable kind of disabled (Button's rule — native `disabled`
385
- * would take the field out of the tab order, and the reason with it). */
386
- locked: boolean;
387
- invalid?: boolean;
388
- className?: string;
389
- }) {
390
- useFocusBackOnClose(open, triggerRef);
391
- const setTrigger = useTriggerRef(triggerRef, fieldRef);
392
-
393
- return (
394
- <button
395
- ref={setTrigger}
396
- type="button"
397
- disabled={locked ? undefined : disabled}
398
- aria-disabled={locked || undefined}
399
- onClick={() => {
400
- // Locked, the grid does not open. One open when the lock arrives closes: the
401
- // field moves into the reason's frame, which remounts it, as Select's does.
402
- if (!locked) toggle();
403
- }}
404
- role="combobox"
405
- aria-haspopup="dialog"
406
- aria-controls={panelId}
407
- aria-expanded={open}
408
- id={aria.id}
409
- aria-invalid={invalid || aria["aria-invalid"] === true || aria["aria-invalid"] === "true" || undefined}
410
- aria-required={aria["aria-required"]}
411
- aria-labelledby={aria["aria-label"] && !aria["aria-labelledby"] ? undefined : labelledBy}
412
- aria-label={aria["aria-label"]}
413
- aria-describedby={aria["aria-describedby"]}
414
- className={cn(
415
- FIELD_TRIGGER,
416
- "pe-9",
417
- padded && FIELD_FLOATING_PAD,
418
- // keksdose K13 (live #260): an IconButton's 36px, and only as wide as the
419
- // month — `py-0` with a fixed height so the box is 36px whatever the type's
420
- // line height. `pe-9` stays: the calendar glyph still sits at the end.
421
- small && "h-9 w-auto py-0",
422
- (disabled || locked) && "cursor-not-allowed opacity-50",
423
- invalid && FIELD_INVALID,
424
- className,
425
- )}
426
- >
427
- {/* The U+00A0 fallback keeps the line box when there is no text — see
428
- DatePicker. The value arrives capitalised (see `upperFirst`); this span does
429
- NOT use `capitalize`, which upper-cases every WORD — "Choose A Month",
430
- "Septiembre De 2026". It wraps from Large up, as DatePicker's value does
431
- (`truncate-until-large`, text size §10.17; round 0.34 T1: the sweep read
432
- "Choose a mo…" at 360 px / Extra large). */}
433
- <span id={valueId} className={cn("truncate-until-large", !hasValue && "text-placeholder")}>
434
- {triggerText || " "}
435
- </span>
436
- </button>
437
- );
438
- }
439
-
440
- // ── Grid ──────────────────────────────────────────────────────────────────
441
-
442
- const COLUMNS = 3;
443
-
444
- /**
445
- * A year arrow over a grid (the month grid's ‹ › years, the year grid's pages). At a
446
- * bound it refuses rather than turning `disabled`, JumpCalendar's rule (refactor audit
447
- * 2026-10-30, INP-4): the press that reaches the bound is made with the focus ON the
448
- * arrow, and a focused button that turns `disabled` drops the focus to <body>, mid-panel
449
- * (keksdose's budget MonthPicker passes `min`). `aria-disabled`, a click that does
450
- * nothing, and the look through `aria-disabled:`.
451
- */
452
- const PANEL_ARROW =
453
- "flex size-7 items-center justify-center rounded text-muted hover:bg-hover aria-disabled:cursor-not-allowed aria-disabled:opacity-30 aria-disabled:hover:bg-transparent";
454
-
455
- /** The stepper's Today and ‹ › while refused: Button's look for its focusable kind of
456
- * disabled — the kit's `disabled:` classes cannot match an `aria-disabled` button. The
457
- * arrows, ghost IconButtons, also pin their resting fill under hover, as
458
- * `disabled:hover:` does for them. */
459
- const STEPPER_REFUSED = "aria-disabled:cursor-not-allowed aria-disabled:opacity-50";
460
- const STEPPER_ARROW_REFUSED = `${STEPPER_REFUSED} aria-disabled:hover:bg-transparent`;
461
-
462
- /**
463
- * The panel: a year caption between ‹ › arrows, over the year's {@link MonthGrid} (4×3,
464
- * its keys and its bounds — one with JumpCalendar's since 0.52, DUP-11).
465
- *
466
- * Mounted only while the popover is open, so every opening starts from the current
467
- * value's year — a value moved from outside (a prev/next-month button beside the
468
- * field) is where the grid lands, with no effect needed to snap it back.
469
- */
470
- function MonthPanel({
471
- value,
472
- onPick,
473
- locale,
474
- minKey,
475
- maxKey,
476
- currentKey,
477
- labels,
478
- }: {
479
- value: YearMonth | null;
480
- onPick: (key: string) => void;
481
- locale: string | undefined;
482
- minKey: string | null;
483
- maxKey: string | null;
484
- currentKey: string;
485
- labels: MonthPickerLabels;
486
- }) {
487
- const selectedKey = value ? toKey(value) : null;
488
- // The month holding the tab order, and with it the year on screen — one piece of
489
- // state, as in MiniCalendar, so the two cannot disagree. Opens on the value, or on
490
- // the current month, pulled inside the bounds.
491
- const [active, setActive] = useState(() => clampKey(selectedKey ?? currentKey, minKey, maxKey));
492
- const year = Number(active.slice(0, 4));
493
- const captionId = `${useId()}-year`;
494
- const yearCaption = new Intl.DateTimeFormat(locale, YEAR_FORMAT).format(new Date(year, 0, 1));
495
- const blocked = yearArrowsBlocked(active, minKey, maxKey);
496
-
497
- return (
498
- <div className="select-none">
499
- <div className="mb-1 flex items-center justify-between">
500
- <button
501
- type="button"
502
- aria-label={labels.previousYear}
503
- aria-disabled={blocked.previous || undefined}
504
- // Focus stays on the arrow being pressed — only the grid moves.
505
- onClick={() => {
506
- if (!blocked.previous) setActive(shiftKey(active, -12));
507
- }}
508
- className={PANEL_ARROW}
509
- >
510
- {/* Mirrored in RTL, where "previous" points the other way. */}
511
- <ChevronLeft className="size-4 rtl:-scale-x-100" />
512
- </button>
513
- {/* Names the grid, and `aria-live` so stepping a year says which one you are
514
- on — the user pressing the arrow is not inside the grid to hear it change. */}
515
- <div id={captionId} aria-live="polite" className="text-sm font-semibold tabular-nums text-primary">
516
- {yearCaption}
517
- </div>
518
- <button
519
- type="button"
520
- aria-label={labels.nextYear}
521
- aria-disabled={blocked.next || undefined}
522
- onClick={() => {
523
- if (!blocked.next) setActive(shiftKey(active, 12));
524
- }}
525
- className={PANEL_ARROW}
526
- >
527
- <ChevronRight className="size-4 rtl:-scale-x-100" />
528
- </button>
529
- </div>
530
- <MonthGrid
531
- active={active}
532
- onActiveChange={setActive}
533
- onPick={onPick}
534
- from={selectedKey}
535
- to={selectedKey}
536
- minKey={minKey}
537
- maxKey={maxKey}
538
- currentKey={currentKey}
539
- locale={locale}
540
- cellName={labels.month}
541
- labelledBy={captionId}
542
- />
543
- </div>
544
- );
545
- }
546
-
547
- /** Years on one page of the year grid: the month grid's 4×3. */
548
- const YEAR_PAGE = 12;
549
-
550
- /**
551
- * `mode="year"`'s panel: a page of years between ‹ › arrows — {@link MonthGrid}'s shape
552
- * and keyboard, one level up (kastlan 7, keksdose tax-tab.tsx:33).
553
- *
554
- * Which years a page holds:
555
- * - Bounded on both sides by twelve years or fewer: exactly those years, and no
556
- * arrows — keksdose's "this year and four before" is five cells, not a page of
557
- * twelve with seven greyed out.
558
- * - Otherwise twelve at a time, starting from `min` when there is one (so the first
559
- * page opens on it), else ending at `max`, else on multiples of twelve.
560
- *
561
- * The arrow keys walk the years (up/down by a row of three), PageUp / PageDown a page,
562
- * Home / End the row; walking off a page turns it. Focus stops at the bounds rather
563
- * than walking into years that refuse selection: a page has no "next year" past the
564
- * last selectable one worth landing on.
565
- */
566
- function YearGrid({
567
- value,
568
- onPick,
569
- locale,
570
- minYear,
571
- maxYear,
572
- currentYear,
573
- labels,
574
- }: {
575
- value: number | null;
576
- onPick: (key: string) => void;
577
- locale: string | undefined;
578
- minYear: number | null;
579
- maxYear: number | null;
580
- currentYear: number;
581
- labels: MonthPickerLabels;
582
- }) {
583
- const clamp = (y: number) => Math.min(maxYear ?? y, Math.max(minYear ?? y, y));
584
- // A bounded span that fits one page is shown whole.
585
- const whole =
586
- minYear !== null && maxYear !== null && maxYear >= minYear && maxYear - minYear < YEAR_PAGE
587
- ? { first: minYear, count: maxYear - minYear + 1 }
588
- : null;
589
- // The year holding the tab order, and with it the page on screen — one piece of
590
- // state, as in MonthPanel. Opens on the value, or on this year, inside the bounds.
591
- const [active, setActive] = useState(() => clamp(value ?? currentYear));
592
- const anchor = minYear ?? (maxYear !== null ? maxYear - (YEAR_PAGE - 1) : 0);
593
- const first = whole ? whole.first : anchor + Math.floor((active - anchor) / YEAR_PAGE) * YEAR_PAGE;
594
- const count = whole ? whole.count : YEAR_PAGE;
595
- const years = Array.from({ length: count }, (_, i) => first + i);
596
- const outOfBounds = (y: number) => (minYear !== null && y < minYear) || (maxYear !== null && y > maxYear);
597
-
598
- const gridRef = useRef<HTMLDivElement>(null);
599
- const captionId = `${useId()}-years`;
600
- const yearFormat = useMemo(() => new Intl.DateTimeFormat(locale, YEAR_FORMAT), [locale]);
601
- // "2016–2027" in the locale's own range punctuation and digits.
602
- const caption = yearFormat.formatRange(new Date(first, 0, 1), new Date(first + count - 1, 0, 1));
603
-
604
- const pendingFocus = useRef<number | null>(null);
605
- useEffect(() => {
606
- const year = pendingFocus.current;
607
- if (year === null) return;
608
- pendingFocus.current = null;
609
- gridRef.current?.querySelector<HTMLElement>(`[data-year="${year}"]`)?.focus();
610
- });
611
- // Opened to pick a year: land on it (before the popover's trap, which keeps it).
612
- useEffect(() => {
613
- gridRef.current?.querySelector<HTMLElement>('[tabindex="0"]')?.focus();
614
- }, []);
615
-
616
- const moveTo = (next: number, focus: boolean) => {
617
- const year = clamp(next);
618
- if (focus) pendingFocus.current = year;
619
- setActive(year);
620
- };
621
-
622
- const onCellKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {
623
- const step = horizontalStep(e.key, e.currentTarget);
624
- const col = (active - first) % COLUMNS;
625
- let delta: number;
626
- switch (step ? "horizontal" : e.key) {
627
- case "horizontal":
628
- delta = step;
629
- break;
630
- case "ArrowUp":
631
- delta = -COLUMNS;
632
- break;
633
- case "ArrowDown":
634
- delta = COLUMNS;
635
- break;
636
- case "Home":
637
- delta = -col;
638
- break;
639
- case "End":
640
- delta = Math.min(COLUMNS - 1 - col, first + count - 1 - active);
641
- break;
642
- case "PageUp":
643
- delta = -YEAR_PAGE;
644
- break;
645
- case "PageDown":
646
- delta = YEAR_PAGE;
647
- break;
648
- default:
649
- return;
650
- }
651
- e.preventDefault();
652
- if (delta !== 0) moveTo(active + delta, true);
653
- };
654
-
655
- const prevBlocked = minYear !== null && first - 1 < minYear;
656
- const nextBlocked = maxYear !== null && first + count > maxYear;
657
-
658
- return (
659
- <div className="select-none">
660
- <div className={cn("mb-1 flex items-center", whole ? "h-7 justify-center" : "justify-between")}>
661
- {!whole && (
662
- <button
663
- type="button"
664
- aria-label={labels.earlierYears}
665
- aria-disabled={prevBlocked || undefined}
666
- onClick={() => {
667
- if (!prevBlocked) moveTo(active - YEAR_PAGE, false);
668
- }}
669
- className={PANEL_ARROW}
670
- >
671
- <ChevronLeft className="size-4 rtl:-scale-x-100" />
672
- </button>
673
- )}
674
- <div id={captionId} aria-live="polite" className="text-sm font-semibold tabular-nums text-primary">
675
- {caption}
676
- </div>
677
- {!whole && (
678
- <button
679
- type="button"
680
- aria-label={labels.laterYears}
681
- aria-disabled={nextBlocked || undefined}
682
- onClick={() => {
683
- if (!nextBlocked) moveTo(active + YEAR_PAGE, false);
684
- }}
685
- className={PANEL_ARROW}
686
- >
687
- <ChevronRight className="size-4 rtl:-scale-x-100" />
688
- </button>
689
- )}
690
- </div>
691
- <div ref={gridRef} role="grid" aria-labelledby={captionId} className="grid gap-1">
692
- {Array.from({ length: Math.ceil(count / COLUMNS) }, (_, row) => (
693
- <div key={row} role="row" className="grid grid-cols-3 gap-1">
694
- {years.slice(row * COLUMNS, row * COLUMNS + COLUMNS).map((year) => {
695
- const disabled = outOfBounds(year);
696
- const selected = year === value;
697
- const current = year === currentYear;
698
- return (
699
- <button
700
- key={year}
701
- type="button"
702
- role="gridcell"
703
- data-year={year}
704
- tabIndex={year === active ? 0 : -1}
705
- aria-selected={selected}
706
- aria-disabled={disabled || undefined}
707
- aria-current={current ? "date" : undefined}
708
- onClick={() => {
709
- if (disabled) return;
710
- setActive(year);
711
- onPick(String(year));
712
- }}
713
- onKeyDown={onCellKeyDown}
714
- className={cn(
715
- // The month grid's 44px rows (DUP-11): one picker, one row height.
716
- "h-11 rounded px-1 text-sm tabular-nums transition-colors",
717
- FOCUS_RING_WIDTH,
718
- "focus-visible:outline-none focus-visible:ring-inset",
719
- selected && !disabled ? "focus-visible:ring-brand-contrast" : "focus-visible:ring-brand",
720
- disabled
721
- ? "cursor-not-allowed text-placeholder"
722
- : selected
723
- ? "bg-brand text-brand-contrast hover:bg-brand-hover"
724
- : "text-primary hover:bg-hover",
725
- current && !selected && !disabled && "ring-1 ring-inset ring-strong",
726
- )}
727
- >
728
- {yearFormat.format(new Date(year, 0, 1))}
729
- </button>
730
- );
731
- })}
732
- </div>
733
- ))}
734
- </div>
735
- </div>
736
- );
737
- }
738
-
739
- // ── Field ─────────────────────────────────────────────────────────────────
740
-
741
- /**
742
- * Month picker: a field showing the selected month ("August 2026"), opening a 12-month
743
- * grid with year arrows. For a value that IS a month — a budget period, a calendar
744
- * view, a statement — where a day picker would ask for a day nobody means.
745
- *
746
- * One component for the two app-local pickers it replaces: keksdose's budget-header
747
- * popover (grid + year steppers + a floor) and kastlan's calendar header (a month list
748
- * and a year list in two popovers). The grid does both jobs — the year arrows and
749
- * PageUp/PageDown cover what the year list did, without a fixed ±5-year window.
750
- */
751
- export function MonthPicker(props: MonthPickerProps) {
752
- const {
753
- value,
754
- onChange,
755
- locale: localeProp,
756
- min,
757
- max,
758
- label,
759
- placeholder,
760
- disabled,
761
- disabledReason,
762
- disabledReasonDisplay,
763
- commit,
764
- invalid,
765
- error,
766
- hint,
767
- help,
768
- size = "md",
769
- mode = "month",
770
- formatOptions,
771
- currentMonth,
772
- labels: labelsProp,
773
- className,
774
- triggerClassName,
775
- variant = "field",
776
- headingLevel = 2,
777
- showToday = true,
778
- // The trigger's (API-3); named apart from the Popover trigger's own `ref` below.
779
- ref: fieldRef,
780
- ...rest
781
- } = props;
782
- const labels = useMonthPickerLabels(labelsProp);
783
- const locale = useKitLocale(localeProp);
784
- const fromProvider = useKitDateFormatter();
785
- const years = mode === "year";
786
- const selected = years ? null : parseMonth(value);
787
- const selectedYear = years ? parseYear(value) : null;
788
- const minKey = boundKey(min);
789
- const maxKey = boundKey(max);
790
- const minYear = parseYear(min);
791
- const maxYear = parseYear(max);
792
- const currentKey = boundKey(currentMonth) ?? monthKey(new Date());
793
- const currentYear = parseYear(currentKey)!;
794
- // The key the trigger shows, in the mode's own shape: "YYYY-MM" or "YYYY".
795
- const shownKey = years ? (selectedYear !== null ? String(selectedYear) : null) : selected ? toKey(selected) : null;
796
-
797
- // The kit's order: `formatOptions` (this field's own Intl look), then the provider's
798
- // `formatDate` (keksdose K12 — the app's one way of writing a month), then the default.
799
- const triggerText = shownKey
800
- ? (formatOptions === undefined &&
801
- fromProvider?.(shownKey, { unit: years ? "year" : "month", source: "monthPicker", locale, weekday: false })) ||
802
- upperFirst(
803
- new Intl.DateTimeFormat(locale, formatOptions ?? (years ? YEAR_FORMAT : DEFAULT_TRIGGER_FORMAT)).format(
804
- years ? new Date(selectedYear!, 0, 1) : firstOf(selected!),
805
- ),
806
- locale,
807
- )
808
- : (placeholder ?? "");
809
-
810
- const id = useId();
811
- // The write lock (API-3): Select's — the trigger stays reachable and says why.
812
- const lock = useLockReason(commit, disabledReason);
813
- const locked = lock.locked;
814
- const reasonId = locked ? lock.reasonId : undefined;
815
- const change = (key: string) => {
816
- if (!locked) onChange(key);
817
- };
818
- // keksdose K4: the caption and the error, on the trigger after the caller's own
819
- // description; a lock's reason between the two, as on Select. Painted for `invalid`
820
- // and a message — not for a bare `aria-invalid`, which this field has never painted for.
821
- const messages = useFieldMessages({
822
- hint,
823
- help,
824
- name: label ?? rest["aria-label"],
825
- error,
826
- describedBy: rest["aria-describedby"],
827
- reasonId,
828
- });
829
- const [ownAria, wrapperRest] = splitTriggerAria(rest);
830
- // The field's trigger is described by the caption and the error too; the stepper
831
- // draws neither, so its heading keeps the caller's own description — and a lock's.
832
- const aria: TriggerAria = { ...ownAria, "aria-describedby": messages.describedBy };
833
- const headingAria: TriggerAria = {
834
- ...ownAria,
835
- "aria-describedby": mergeDescribedBy(ownAria["aria-describedby"], reasonId),
836
- };
837
- // Locked, the field (or the stepper) sits in the reason's frame — the line, or the
838
- // Tooltip — which becomes the outermost box and takes the caller's classes, as on
839
- // Select, so a lock does not reflow the page.
840
- const rootClass = locked ? undefined : className;
841
- const withReason = (box: ReactNode) =>
842
- locked ? (
843
- <LockedReason lock={lock} display={disabledReasonDisplay} className={cn("block", className)}>
844
- {box}
845
- </LockedReason>
846
- ) : (
847
- box
848
- );
849
- const labelId = `${id}-label`;
850
- const valueId = `${id}-value`;
851
- const panelId = `${id}-panel`;
852
- // Only a STRING label can double as a name; a ReactNode may hold its own controls.
853
- const named = typeof label === "string";
854
- // `sm` is the toolbar trigger, for an unlabelled picker only (see `size`).
855
- const small = size === "sm" && label === undefined;
856
- // The panel is portalled to <body>, out of the subtree whose `dir` it inherited — an
857
- // RTL form got an LTR grid. Read when opening (`toggle` is the popover's only way
858
- // open) and put back on the panel. Also what the arrow keys above read.
859
- const rootRef = useRef<HTMLDivElement>(null);
860
- const [dir, setDir] = useState<Direction>("ltr");
861
- const panelLabel = years ? labels.yearPanel : labels.panel;
862
-
863
- const grid = (close: () => void) =>
864
- years ? (
865
- <YearGrid
866
- value={selectedYear}
867
- locale={locale}
868
- minYear={minYear}
869
- maxYear={maxYear}
870
- currentYear={currentYear}
871
- labels={labels}
872
- onPick={(key) => {
873
- change(key);
874
- close();
875
- }}
876
- />
877
- ) : (
878
- <MonthPanel
879
- value={selected}
880
- locale={locale}
881
- minKey={minKey}
882
- maxKey={maxKey}
883
- currentKey={currentKey}
884
- labels={labels}
885
- onPick={(key) => {
886
- change(key);
887
- close();
888
- }}
889
- />
890
- );
891
-
892
- if (variant === "stepper") {
893
- // The arrows step from the value, or from "now" when there is none; each is dead
894
- // once the month (or year) it leads to is out of bounds, and Today once "now" is.
895
- let prevKey: string;
896
- let nextKey: string;
897
- let nowKey: string;
898
- let outside: (key: string) => boolean;
899
- if (years) {
900
- const base = selectedYear ?? currentYear;
901
- prevKey = String(base - 1);
902
- nextKey = String(base + 1);
903
- nowKey = String(currentYear);
904
- outside = (key) => {
905
- const y = Number(key);
906
- return (minYear !== null && y < minYear) || (maxYear !== null && y > maxYear);
907
- };
908
- } else {
909
- const base = selected ?? parseMonth(currentKey)!;
910
- prevKey = toKey(shiftMonth(base, -1));
911
- nextKey = toKey(shiftMonth(base, 1));
912
- nowKey = currentKey;
913
- outside = (key) => Boolean((minKey && key < minKey) || (maxKey && key > maxKey));
914
- }
915
- const Heading = headingLevel ? (`h${headingLevel}` as const) : null;
916
- const trigger = (
917
- <Popover
918
- width="16rem"
919
- panelId={panelId}
920
- labels={{ panel: panelLabel }}
921
- dir={dir}
922
- trigger={({ open, toggle, ref }) => (
923
- <MonthHeadingTrigger
924
- open={open}
925
- toggle={() => {
926
- setDir(dirOf(rootRef.current));
927
- toggle();
928
- }}
929
- triggerRef={ref}
930
- fieldRef={fieldRef}
931
- text={triggerText}
932
- panelId={panelId}
933
- disabled={disabled}
934
- locked={locked}
935
- aria={headingAria}
936
- />
937
- )}
938
- >
939
- {grid}
940
- </Popover>
941
- );
942
- // ‹ › at a bound refuse rather than turn `disabled` (refactor audit 2026-10-30,
943
- // INP-4): the press that reaches the bound is made with the focus on the arrow, and
944
- // a focused button that turns `disabled` drops the focus to <body>. A lock refuses
945
- // them, and Today, the same focusable way — its reason is the frame's, so no name
946
- // bubble of their own beside it. `disabled` (a lock's reason wins over it) and
947
- // Today's "now is out of bounds", which no press here changes, stay native.
948
- const off = Boolean(disabled) && !locked;
949
- const prevRefused = locked || outside(prevKey);
950
- const nextRefused = locked || outside(nextKey);
951
- return withReason(
952
- // `flex-wrap`: where the heading and the buttons do not fit one row, the buttons
953
- // take the next line, at the end (0.32.1, the 360 px Extra-large sweep;
954
- // docs/text-size-harmonization.md §4). In one row at 150 % "Today ‹ ›" left the
955
- // heading 30 px on a 360 px phone, and "October 2026" was drawn under "Today".
956
- // Where they fit, nothing changes.
957
- <div {...wrapperRest} ref={rootRef} className={cn("flex min-w-0 flex-wrap items-center gap-2", rootClass)}>
958
- {Heading ? <Heading className="m-0 min-w-0 text-lg font-semibold">{trigger}</Heading> : trigger}
959
- <div className="ms-auto flex shrink-0 items-center gap-1">
960
- {showToday && (
961
- <Button
962
- variant="secondary"
963
- size="sm"
964
- disabled={!locked && (disabled || outside(nowKey))}
965
- aria-disabled={locked || undefined}
966
- aria-describedby={reasonId}
967
- onClick={() => {
968
- if (nowKey !== shownKey) change(nowKey);
969
- }}
970
- className={STEPPER_REFUSED}
971
- >
972
- {years ? labels.thisYear : labels.today}
973
- </Button>
974
- )}
975
- <IconButton
976
- aria-label={years ? labels.previousYear : labels.previousMonth}
977
- disabled={off}
978
- aria-disabled={(!off && prevRefused) || undefined}
979
- aria-describedby={reasonId}
980
- tooltip={!locked}
981
- onClick={() => {
982
- if (!prevRefused) change(prevKey);
983
- }}
984
- className={STEPPER_ARROW_REFUSED}
985
- >
986
- {/* Mirrored in RTL, where "previous" points the other way. */}
987
- <ChevronLeft className="rtl:-scale-x-100" />
988
- </IconButton>
989
- <IconButton
990
- aria-label={years ? labels.nextYear : labels.nextMonth}
991
- disabled={off}
992
- aria-disabled={(!off && nextRefused) || undefined}
993
- aria-describedby={reasonId}
994
- tooltip={!locked}
995
- onClick={() => {
996
- if (!nextRefused) change(nextKey);
997
- }}
998
- className={STEPPER_ARROW_REFUSED}
999
- >
1000
- <ChevronRight className="rtl:-scale-x-100" />
1001
- </IconButton>
1002
- </div>
1003
- </div>,
1004
- );
1005
- }
1006
-
1007
- const field = (
1008
- // `w-fit` for the toolbar size: the calendar glyph is placed against this box, and a
1009
- // full-width box would park it at the far end of the row, away from its trigger.
1010
- // At Large a labelled box is a grid: the label above, the calendar glyph measured
1011
- // against the trigger's row (LABEL_ABOVE_BOX, 0.33 §10.17).
1012
- <div
1013
- {...wrapperRest}
1014
- ref={rootRef}
1015
- className={cn("relative", small && "w-fit max-w-full", label !== undefined && LABEL_ABOVE_BOX, rootClass)}
1016
- >
1017
- {label !== undefined && <FieldLabelLine label={label} hint={messages.labelHint} />}
1018
- {/* The hidden twin the trigger is named by — see DateField. `sr-only-fixed`,
1019
- and inside this `relative` root either way. */}
1020
- {named && (
1021
- <span id={labelId} aria-hidden className="sr-only-fixed">
1022
- {label}
1023
- </span>
1024
- )}
1025
- <Popover
1026
- width="16rem"
1027
- panelId={panelId}
1028
- labels={{ panel: panelLabel }}
1029
- dir={dir}
1030
- trigger={({ open, toggle, ref }) => (
1031
- <MonthFieldTrigger
1032
- open={open}
1033
- toggle={() => {
1034
- setDir(dirOf(rootRef.current));
1035
- toggle();
1036
- }}
1037
- triggerRef={ref}
1038
- fieldRef={fieldRef}
1039
- triggerText={triggerText}
1040
- hasValue={shownKey !== null}
1041
- // As DatePicker: a caller's reference first; an `id` without a label of our
1042
- // own references the trigger itself, so an external <label htmlFor> names it.
1043
- labelledBy={[
1044
- aria["aria-labelledby"],
1045
- named ? labelId : !aria["aria-labelledby"] && aria.id ? aria.id : undefined,
1046
- valueId,
1047
- ]
1048
- .filter(Boolean)
1049
- .join(" ")}
1050
- aria={aria}
1051
- valueId={valueId}
1052
- panelId={panelId}
1053
- padded={label !== undefined}
1054
- small={small}
1055
- disabled={disabled}
1056
- locked={locked}
1057
- invalid={invalid || hasContent(error)}
1058
- className={triggerClassName}
1059
- />
1060
- )}
1061
- >
1062
- {grid}
1063
- </Popover>
1064
- <Calendar
1065
- aria-hidden
1066
- className="pointer-events-none absolute end-2.5 top-1/2 size-4 -translate-y-1/2 text-placeholder"
1067
- />
1068
- </div>
1069
- );
1070
- // An unlabelled picker has no label line: a FieldHint goes at its end, outside the
1071
- // box, as on an unlabelled Select.
1072
- const endHint = label === undefined ? messages.labelHint : undefined;
1073
- return (
1074
- <FieldBox below={messages.below} reserve={"error" in props || "hint" in props}>
1075
- {withReason(
1076
- endHint === undefined ? (
1077
- field
1078
- ) : (
1079
- <div className="flex items-center gap-1.5">
1080
- <div className={cn("min-w-0", !small && "flex-1")}>{field}</div>
1081
- <span className="flex shrink-0 items-center">{endHint}</span>
1082
- </div>
1083
- ),
1084
- )}
1085
- </FieldBox>
1086
- );
1087
- }