@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,225 +0,0 @@
1
- import { useEffect } from "react";
2
- import type { ReactNode } from "react";
3
- import { Navigate, Outlet, useLocation } from "react-router";
4
-
5
- import { matchesPathPattern, routerPathname } from "../lib/path-pattern";
6
- import { readStored, removeStored, writeStored } from "../lib/safe-storage";
7
- import type { LandingSession } from "./landing-actions";
8
- import { LoadingState } from "../components/loading-state";
9
-
10
- /**
11
- * 0.31.1: a session that is still being restored — an app whose access token lives in
12
- * memory reads it back from its refresh token first (kastlan's 0.31 adoption). Until
13
- * then `/` neither shows the landing nor resumes, and a public page neither shows nor
14
- * redirects: both render `loading` instead.
15
- */
16
- export type RoutingSession = LandingSession | "loading";
17
-
18
- /**
19
- * The public routes' logic (docs/landing-demo-harmonization.md §3): what `/` shows,
20
- * which pages a session skips, and the page a session resumes on — keksdose's
21
- * `RootEntry`, `RedirectIfAuthed` and use-last-visited-page.ts, for every app.
22
- * Router-aware (react-router), so they belong to the `./shell` entry.
23
- */
24
-
25
- /* ── ?next= ──────────────────────────────────────────────────────────────── */
26
-
27
- /** The query parameter that carries "where I was actually trying to go" through the
28
- * sign-in bounce (keksdose's `NEXT_PARAM`). */
29
- export const NEXT_PARAM = "next";
30
-
31
- /**
32
- * A `?next=` value that is safe to navigate to, or null.
33
- *
34
- * Same-origin PATHS only, decided by the URL PARSER rather than by string prefix —
35
- * this is the open-redirect check, and it is the reason this lives in one place
36
- * instead of at each call site.
37
- *
38
- * The prefix version ("starts with `/`, does not start with `//`") let two shapes
39
- * through that the browser resolves cross-origin, because the WHATWG parser does not
40
- * read them as text: a backslash after the leading slash counts as a second slash for
41
- * a special scheme, so `/\evil.example` resolves to `https://evil.example/`; and tab,
42
- * LF and CR are STRIPPED anywhere in the input before parsing, so `/<TAB>/evil.example`
43
- * becomes `//evil.example`. Asking the same parser the browser will use closes every
44
- * such shape at once, including ones nobody has thought of yet, and it normalises what
45
- * comes back instead of echoing the caller's spelling.
46
- *
47
- * keksdose's (shared/hooks/use-last-visited-page.ts), verbatim but for the fallback
48
- * origin.
49
- */
50
- export function safeNextPath(raw: string | null | undefined): string | null {
51
- if (!raw) return null;
52
- const base = typeof window !== "undefined" ? window.location.origin : "https://kit.invalid";
53
- try {
54
- const url = new URL(raw, base);
55
- if (url.origin !== base) return null;
56
- return `${url.pathname}${url.search}${url.hash}`;
57
- } catch {
58
- return null;
59
- }
60
- }
61
-
62
- /* ── The last visited page (§3.2) ────────────────────────────────────────── */
63
-
64
- /** A path to leave out: a string is the path and everything under it (`/demo` is
65
- * `/demo` and `/demo/ended`; `/` is only `/`), a RegExp is tested on the pathname. Both
66
- * as React Router matches a route: case-insensitive (a RegExp gets the `i` flag) and on
67
- * the percent-decoded path (0.52). */
68
- export type PathPattern = string | RegExp;
69
-
70
- /**
71
- * The pages never recorded as a resume target (§3.2): the landing (`/`, `/welcome`), the
72
- * auth pages, the demo's own (`/demo*`) and the legal pages. The 404 has no path of its
73
- * own — call {@link useLastVisitedPage} inside the signed-in layout, as keksdose does,
74
- * and it never sees one. The app adds its own one-shot routes (keksdose:
75
- * `/banks/callback`, `/join`, `/share-target`) through `exclude`.
76
- */
77
- export const DEFAULT_LAST_VISITED_EXCLUDES: readonly PathPattern[] = Object.freeze([
78
- "/",
79
- "/welcome",
80
- "/login",
81
- "/register",
82
- "/forgot-password",
83
- "/reset-password",
84
- "/verify-email",
85
- "/demo",
86
- "/impressum",
87
- "/privacy",
88
- "/terms",
89
- ]);
90
-
91
- /**
92
- * Whether `pathname` is one of the defaults or the app's `exclude` — read as the ROUTER
93
- * reads it, decoded and case-insensitive (lib/path-pattern). This module's own copy of the
94
- * rule compared the raw pathname case-sensitively after the feedback guard's copy had
95
- * learnt both, and `exclude: ["/banks/callback"]` recorded `/Banks/Callback?code=…` as the
96
- * page the next launch resumes on (0.52 code review, lib/path-pattern.ts). One rule now.
97
- */
98
- function isExcluded(pathname: string, exclude: readonly PathPattern[]): boolean {
99
- const path = routerPathname(pathname);
100
- const named = (pattern: PathPattern) => matchesPathPattern(path, pattern);
101
- return DEFAULT_LAST_VISITED_EXCLUDES.some(named) || exclude.some(named);
102
- }
103
-
104
- export interface LastVisitedPageOptions {
105
- /** The device key: `<app>.lastVisitedPage` (§3.2), one per app on the origin. */
106
- key: string;
107
- /** The app's own paths to leave out, ON TOP of {@link DEFAULT_LAST_VISITED_EXCLUDES}. */
108
- exclude?: readonly PathPattern[];
109
- /** `false` records nothing — while the session is still being restored, say. */
110
- enabled?: boolean;
111
- }
112
-
113
- /**
114
- * Remember the page a session is on (path and query), on every navigation, so `/` — a
115
- * revisit, a fresh sign-in, the installed PWA, whose `start_url` is `/` — resumes there
116
- * (§3.2, keksdose feedback #59). Device-local, in `localStorage` under `key`; a blocked
117
- * storage records nothing.
118
- *
119
- * Call it once in the signed-in layout. The excluded paths are never written, so a
120
- * one-shot page (a bank callback, an invitation link) never becomes the place the next
121
- * launch opens on.
122
- */
123
- export function useLastVisitedPage({ key, exclude = [], enabled = true }: LastVisitedPageOptions): void {
124
- const { pathname, search } = useLocation();
125
- // Decided here, so the effect depends on the answer and not on an `exclude` array the
126
- // caller likely builds inline.
127
- const skip = !enabled || isExcluded(pathname, exclude);
128
- useEffect(() => {
129
- if (skip) return;
130
- writeStored(key, pathname + search);
131
- }, [key, pathname, search, skip]);
132
- }
133
-
134
- /**
135
- * The page {@link useLastVisitedPage} remembered under `key` — checked by
136
- * {@link safeNextPath}, so a value someone planted in storage cannot leave the origin —
137
- * or `fallback` (default `null`) when there is none or storage is blocked. A string
138
- * fallback narrows the answer to a string, for react-router's `to`.
139
- */
140
- export function readLastVisitedPage(key: string, fallback: string): string;
141
- export function readLastVisitedPage(key: string, fallback?: null): string | null;
142
- export function readLastVisitedPage(key: string, fallback: string | null = null): string | null {
143
- return safeNextPath(readStored(key)) ?? fallback;
144
- }
145
-
146
- /** Forget the remembered page — on an explicit sign-out, so the next account does not
147
- * resume on the previous one's page. */
148
- export function clearLastVisitedPage(key: string): void {
149
- removeStored(key);
150
- }
151
-
152
- /* ── RootEntry ───────────────────────────────────────────────────────────── */
153
-
154
- export interface RootEntryProps {
155
- /** Without a session `/` is the landing; with one (real or demo) it resumes;
156
- * `"loading"` while the app restores one. */
157
- session: RoutingSession;
158
- /** What shows while `session` is `"loading"`. Default: the kit's `LoadingState`. */
159
- loading?: ReactNode;
160
- /** The remembered page — `readLastVisitedPage(key)`. */
161
- resumePath?: string | null;
162
- /** The landing page element. */
163
- landing: ReactNode;
164
- /** The app's home: where a session goes with nothing to resume (keksdose `/budget`,
165
- * kastlan and Kurvenschmiede `/dashboard`). */
166
- home: string;
167
- }
168
-
169
- /**
170
- * The `/` route (§3.1): the landing for a visitor, and for a session — real or demo —
171
- * the last visited page, else the app's home. Indexed and canonical `/` for the visitor;
172
- * a crawler never has a session, so for it `/` is stable.
173
- *
174
- * keksdose showed a session with nothing remembered the landing; the contract sends it
175
- * home instead, because a session at `/` came to use the app. The landing stays one tap
176
- * away at `/welcome`, where the signed-in brand link points.
177
- */
178
- export function RootEntry({ session, resumePath, landing, home, loading }: RootEntryProps) {
179
- if (session === "loading") return <>{loading ?? <LoadingState />}</>;
180
- if (session === "none") return <>{landing}</>;
181
- const resume = safeNextPath(resumePath);
182
- return <Navigate to={resume && resume !== "/" ? resume : home} replace />;
183
- }
184
-
185
- /* ── RedirectIfAuthed ────────────────────────────────────────────────────── */
186
-
187
- export interface RedirectIfAuthedProps {
188
- /** `"loading"` while the app restores a session: neither the page nor a redirect. */
189
- session: RoutingSession;
190
- /** What shows while `session` is `"loading"`. Default: the kit's `LoadingState`. */
191
- loading?: ReactNode;
192
- /**
193
- * Let a DEMO session through (§5.6): on `/login`, `/register` and the app's invitation
194
- * pages, so a demo visitor can sign in or accept an invitation — a successful one
195
- * replaces the demo session. Default `false`: on `/demo` a live demo continues instead
196
- * of starting a second one (§5.2), and on `/forgot-password` a demo has no password.
197
- */
198
- allowDemo?: boolean;
199
- /** Where a redirected session goes: the resume target —
200
- * `readLastVisitedPage(key, home)`. A safe `?next=` goes first. */
201
- fallback: string;
202
- /** The page. Left out, an `<Outlet />`: the component is a layout route around the
203
- * public pages, as in keksdose. */
204
- children?: ReactNode;
205
- }
206
-
207
- /**
208
- * Public pages a session skips (§3.1): a signed-in visitor at `/login` goes back into
209
- * the app, to a safe `?next=` when the URL carries one (a share invitation or a push
210
- * deep link opened with a live session in another tab — keksdose) and else to
211
- * `fallback`.
212
- *
213
- * A demo session passes where `allowDemo` says so (§5.6). Mount one wrapper with
214
- * `allowDemo` around `/login`, `/register` and the invitation pages, and one without
215
- * around `/demo` (and `/forgot-password`).
216
- */
217
- export function RedirectIfAuthed({ session, allowDemo = false, fallback, children, loading }: RedirectIfAuthedProps) {
218
- const { search } = useLocation();
219
- if (session === "loading") return <>{loading ?? <LoadingState />}</>;
220
- if (session === "none" || (session === "demo" && allowDemo)) {
221
- return children === undefined ? <Outlet /> : <>{children}</>;
222
- }
223
- const next = safeNextPath(new URLSearchParams(search).get(NEXT_PARAM));
224
- return <Navigate to={next ?? fallback} replace />;
225
- }
@@ -1,52 +0,0 @@
1
- /*
2
- * The cross-tab messages of the sync engine (the copy's new epoch after `forget()`) and of the
3
- * query copy (`clear`), refactor audit 2026-10-30 FLW-1. 0.52 code review
4
- * (src/sync/engine.ts, src/offline/query-persistence.ts): both wrote the open, the feature
5
- * check, the try/catch and the close by hand, the listening side twice too — and the two
6
- * listeners had drifted (only the query copy's let go of Node's worker).
7
- */
8
-
9
- /**
10
- * Tell this origin's other tabs one thing over a `BroadcastChannel`, and let go of the
11
- * channel at once.
12
- *
13
- * Best-effort by design: the message makes another tab stop sooner, and each caller has a
14
- * fallback that holds without it (the epoch in `meta`, the key deleted from storage).
15
- *
16
- * The message goes out on a channel of its own, so a caller that listens on `name` itself
17
- * hears it too, like every other channel of that name in this tab: it ignores its own.
18
- */
19
- export function postOnce(name: string, message: unknown): void {
20
- // Older browsers and some test environments have none: nothing is posted.
21
- if (typeof BroadcastChannel === "undefined") return;
22
- try {
23
- const channel = new BroadcastChannel(name);
24
- try {
25
- channel.postMessage(message);
26
- } finally {
27
- channel.close();
28
- }
29
- } catch {
30
- /* best-effort: a message that cannot be cloned, a channel refused (an opaque origin) */
31
- }
32
- }
33
-
34
- /**
35
- * Hear what this origin's other tabs post on `name` until the returned function is called.
36
- * Nothing is heard (and closing is a no-op) where there is no BroadcastChannel or none can be
37
- * opened (an opaque origin): each caller has a fallback that holds without it.
38
- */
39
- export function listenOn(name: string, onMessage: (data: unknown) => void): () => void {
40
- if (typeof BroadcastChannel === "undefined") return () => undefined;
41
- let channel: BroadcastChannel;
42
- try {
43
- channel = new BroadcastChannel(name);
44
- } catch {
45
- return () => undefined;
46
- }
47
- // Node's channel (an app's tests) holds its worker open while it listens, and a test that
48
- // never stops the listener would keep it listening. Browsers have no `unref`.
49
- (channel as BroadcastChannel & { unref?: () => void }).unref?.();
50
- channel.onmessage = ({ data }: MessageEvent<unknown>) => onMessage(data);
51
- return () => channel.close();
52
- }
package/src/lib/calc.ts DELETED
@@ -1,323 +0,0 @@
1
- /**
2
- * A tiny, dependency-free arithmetic evaluator for the numeric input fields.
3
- * It lets users type a calculation (e.g. "12.50+3.20" or "100/3") straight into
4
- * an amount field, or build one in the calculator popover, and have it resolve
5
- * to a number. Deliberately NOT backed by `eval`/`Function` — it's a hand-rolled
6
- * tokenizer + recursive-descent parser over a closed grammar (digits, decimals,
7
- * `+ - * /`, unary minus, parentheses), so no arbitrary code can run.
8
- */
9
-
10
- type Token =
11
- | { kind: "num"; value: number }
12
- | { kind: "op"; value: "+" | "-" | "*" | "/" }
13
- | { kind: "lparen" }
14
- | { kind: "rparen" };
15
-
16
- function tokenize(input: string): Token[] | null {
17
- const tokens: Token[] = [];
18
- let i = 0;
19
- while (i < input.length) {
20
- const ch = input[i];
21
- if (ch === " ") {
22
- i++;
23
- continue;
24
- }
25
- if (ch === "+" || ch === "-" || ch === "*" || ch === "/") {
26
- tokens.push({ kind: "op", value: ch });
27
- i++;
28
- continue;
29
- }
30
- if (ch === "(") {
31
- tokens.push({ kind: "lparen" });
32
- i++;
33
- continue;
34
- }
35
- if (ch === ")") {
36
- tokens.push({ kind: "rparen" });
37
- i++;
38
- continue;
39
- }
40
- if ((ch >= "0" && ch <= "9") || ch === ".") {
41
- let j = i;
42
- let dotSeen = false;
43
- while (j < input.length && ((input[j] >= "0" && input[j] <= "9") || input[j] === ".")) {
44
- if (input[j] === ".") {
45
- if (dotSeen) return null; // two dots in one number → invalid
46
- dotSeen = true;
47
- }
48
- j++;
49
- }
50
- const num = Number(input.slice(i, j));
51
- if (!Number.isFinite(num)) return null;
52
- tokens.push({ kind: "num", value: num });
53
- i = j;
54
- continue;
55
- }
56
- return null; // unknown character
57
- }
58
- return tokens;
59
- }
60
-
61
- /**
62
- * Recursive-descent parse honouring `* /` over `+ -` and left-associativity.
63
- * Returns `null` for any malformed input (the `null` sentinel is safe because a
64
- * valid result of 0 is distinct from it). Division by zero is treated as invalid.
65
- *
66
- * expr := term (('+' | '-') term)*
67
- * term := factor (('*' | '/') factor)*
68
- * factor := ('+' | '-') factor | number | '(' expr ')'
69
- */
70
- function parse(tokens: Token[]): number | null {
71
- let pos = 0;
72
-
73
- function parseExpr(): number | null {
74
- let value = parseTerm();
75
- if (value === null) return null;
76
- while (pos < tokens.length) {
77
- const tok = tokens[pos];
78
- if (tok.kind === "op" && (tok.value === "+" || tok.value === "-")) {
79
- pos++;
80
- const rhs = parseTerm();
81
- if (rhs === null) return null;
82
- value = tok.value === "+" ? value + rhs : value - rhs;
83
- } else break;
84
- }
85
- return value;
86
- }
87
-
88
- function parseTerm(): number | null {
89
- let value = parseFactor();
90
- if (value === null) return null;
91
- while (pos < tokens.length) {
92
- const tok = tokens[pos];
93
- if (tok.kind === "op" && (tok.value === "*" || tok.value === "/")) {
94
- pos++;
95
- const rhs = parseFactor();
96
- if (rhs === null) return null;
97
- if (tok.value === "/") {
98
- if (rhs === 0) return null;
99
- value = value / rhs;
100
- } else {
101
- value = value * rhs;
102
- }
103
- } else break;
104
- }
105
- return value;
106
- }
107
-
108
- function parseFactor(): number | null {
109
- const tok = tokens[pos];
110
- if (!tok) return null;
111
- if (tok.kind === "op" && (tok.value === "+" || tok.value === "-")) {
112
- pos++;
113
- const operand = parseFactor();
114
- if (operand === null) return null;
115
- return tok.value === "-" ? -operand : operand;
116
- }
117
- if (tok.kind === "lparen") {
118
- pos++;
119
- const inner = parseExpr();
120
- if (inner === null) return null;
121
- if (tokens[pos]?.kind !== "rparen") return null;
122
- pos++;
123
- return inner;
124
- }
125
- if (tok.kind === "num") {
126
- pos++;
127
- return tok.value;
128
- }
129
- return null;
130
- }
131
-
132
- const result = parseExpr();
133
- if (result === null) return null;
134
- if (pos !== tokens.length) return null; // leftover tokens → invalid
135
- return result;
136
- }
137
-
138
- /** Evaluate an arithmetic string, returning `null` if it isn't a valid sum.
139
- * Accepts the on-screen operator glyphs (`× ÷ −`) and comma decimals too. */
140
- export function evaluateExpression(expr: string): number | null {
141
- const normalized = expr
142
- .replace(/×/g, "*")
143
- .replace(/÷/g, "/")
144
- .replace(/[−–—]/g, "-") // unicode minus / en / em dash → ascii
145
- .replace(/,/g, ".")
146
- .trim();
147
- if (normalized === "") return null;
148
- const tokens = tokenize(normalized);
149
- if (tokens === null || tokens.length === 0) return null;
150
- const result = parse(tokens);
151
- if (result === null || !Number.isFinite(result)) return null;
152
- return result;
153
- }
154
-
155
- /** True when `s` carries arithmetic beyond a single leading minus — i.e. a plain
156
- * number (or a lone negative like "-5") is NOT an expression, but "12+5" is.
157
- * Used to decide whether a field's text should be evaluated on commit.
158
- *
159
- * The operator set is the one {@link evaluateExpression} accepts, on-screen glyphs
160
- * included: the calculator keypad inserts `× ÷ −`, and a `−` that this said was not
161
- * arithmetic went on to be read as a plain number — where the digits-only fallback
162
- * in {@link commitExpression} silently ate it, turning "-42−−50" (= 8) into a bare
163
- * 8 with no record that a sum had happened at all. */
164
- export function looksLikeExpression(s: string): boolean {
165
- const t = s.trim();
166
- if (t === "") return false;
167
- if (/^-?\d*[.,]?\d*$/.test(t)) return false; // plain (optionally negative) decimal
168
- return /[+\-*/×÷−–—()]/.test(t.replace(/^-/, ""));
169
- }
170
-
171
- /** Render an evaluated number back to a field-friendly string, trimming binary
172
- * float noise (so 0.1 + 0.2 reads "0.3", not "0.30000000000000004").
173
- *
174
- * FIXED notation, always, and that is the whole point of the function rather than a
175
- * detail of it. This used to end in `parseFloat(n.toFixed(10)).toString()`, and
176
- * `Number.prototype.toString` switches to EXPONENT notation below 1e-6 and at or
177
- * above 1e21 — an alphabet containing `e`, `+` and `-`. Neither function that reads a
178
- * field's text back accepts it: {@link tokenize} rejects `e` as an unknown character
179
- * and {@link sanitizeLive} deletes it. So {@link commitExpression} fell through to
180
- * its digits-only cleanup, which stripped the `e` and CONCATENATED the mantissa to
181
- * the exponent. A field committed its own output as a different number:
182
- *
183
- * "1/10000000" -> "1e-7" -> "17" (AmountInput: "6")
184
- * "999999999999*999999999999" -> "9.99999999998e+23" -> "9.9999999999823"
185
- *
186
- * Both controls commit on blur AND on Enter, so Enter-then-click-away was enough on
187
- * its own, it was silent, and it was in a money field.
188
- *
189
- * The invariant, which the test asserts directly rather than by example:
190
- * **`commitExpression(formatResult(n))` equals `formatResult(n)` for every finite
191
- * `n`.** Anything rendered here has to survive being read back. */
192
- export function formatResult(n: number): string {
193
- if (!Number.isFinite(n)) return "";
194
- // At or above 1e21 `toFixed` gives up and hands back `toString`'s exponent form —
195
- // but every double that large is an integer, so BigInt renders it exactly.
196
- if (Math.abs(n) >= 1e21) return BigInt(n).toString();
197
- return trimTrailingZeros(n.toFixed(10));
198
- }
199
-
200
- /** "15.7000000000" -> "15.7", "0.0000000000" -> "0". The ten decimals are where the
201
- * binary float noise gets rounded off; this is only about not showing the padding. */
202
- function trimTrailingZeros(fixed: string): string {
203
- if (!fixed.includes(".")) return fixed;
204
- const trimmed = fixed.replace(/0+$/, "").replace(/\.$/, "");
205
- // `toFixed` keeps the sign on a magnitude that rounded away to nothing
206
- // ("-0.0000000000"); `toString` did not, and "-0" in an amount field is noise.
207
- return trimmed === "-0" || trimmed === "" ? "0" : trimmed;
208
- }
209
-
210
- /** The single "on blur / Enter" transform a numeric field applies: evaluate the
211
- * text if it's an expression, otherwise normalise it to a bare number string
212
- * (comma → dot, dropping stray characters, non-leading minuses and anything after
213
- * a second decimal point).
214
- *
215
- * The last clause is the backstop for Keksdose live #201. A field the user typed in
216
- * cannot reach here malformed any more — {@link sanitizeLive} runs on every change,
217
- * including a paste — but a value handed in from elsewhere (a recurring rule, an
218
- * import, a test) still can, and "1.2.3" is not an expression (no operator), so it
219
- * used to fall straight through unchanged and be read as NaN. Here the text is CUT
220
- * at the second dot ("1.2") rather than joined ("1.23"): with no keystroke to
221
- * ignore there is nothing to say which reading was meant, and the shorter one
222
- * cannot silently invent a bigger number. */
223
- export function commitExpression(raw: string): string {
224
- const s = raw.trim();
225
- if (looksLikeExpression(s)) {
226
- const n = evaluateExpression(s);
227
- if (n !== null) return formatResult(n);
228
- // Unparseable (e.g. a half-typed "12+"): fall through to a digits-only clean.
229
- }
230
- // Global, like sanitizeLive's: these two are the two halves of one rule and must
231
- // not appear to state it differently. (The `[^0-9.-]` strip on the same line
232
- // already ate whatever commas a non-global replace missed, so this changes no
233
- // behaviour — it removes the need for the next reader to run it to find that out.)
234
- const cleaned = s
235
- .replace(/,/g, ".")
236
- .replace(/[^0-9.-]/g, "")
237
- .replace(/(?!^)-/g, "");
238
- return cleaned.replace(/^(-?\d*\.?\d*).*$/, "$1");
239
- }
240
-
241
- /** The live, per-keystroke transform a numeric field applies: comma → dot and
242
- * drop anything that isn't a digit, decimal point, arithmetic operator (incl.
243
- * the on-screen `× ÷` glyphs) or paren — so a typed calculation survives
244
- * keystroke-by-keystroke but stray characters can't be entered. A lone leading
245
- * `-` is kept — in a plain field it is simply a negative amount; in a field whose
246
- * caller owns the sign it is read off again by {@link splitLeadingSign}. The text
247
- * is resolved to a plain number on blur/Enter via {@link commitExpression}.
248
- *
249
- * The typographic minus and the two dashes become "-" first, as in
250
- * {@link evaluateExpression}: U+2212 is what the kit's own `formatMoney` and
251
- * `formatNumber` print for every negative since 0.49, and stripping it with the
252
- * stray characters turned a pasted "−1.234,50 €" into a positive amount (refactor
253
- * audit 2026-10-30, INP-3). */
254
- export function sanitizeLive(raw: string): string {
255
- return dropExtraDots(
256
- raw
257
- .replace(/[−–—]/g, "-")
258
- .replace(/,/g, ".")
259
- .replace(/[^0-9.+\-*/×÷()]/g, ""),
260
- );
261
- }
262
-
263
- /**
264
- * At most ONE decimal point per number (Keksdose live #201).
265
- *
266
- * Per NUMBER, not per string: "1.5+2.5" is a legitimate calculation with two dots
267
- * in two operands, so the counter resets at every operator and parenthesis.
268
- *
269
- * A second dot inside one operand is a **no-op keystroke** — the digits after it
270
- * keep landing, so "1.2" + "." + "3" is "1.23". That is what every calculator does
271
- * with a repeated decimal point, and it is the only option that does not make the
272
- * field feel broken ("my 3 disappeared"). This runs on paste as well as on typing,
273
- * so the malformed value never reaches the rest of the app: everything downstream
274
- * reads the field with `Number()`, NaN became a silent 0, and on the create form
275
- * that 0 was painted with the income green — a figure that was not a number at all
276
- * asserting money was coming in.
277
- */
278
- function dropExtraDots(s: string): string {
279
- let out = "";
280
- let dotInNumber = false;
281
- for (const ch of s) {
282
- if (ch === ".") {
283
- if (dotInNumber) continue;
284
- dotInNumber = true;
285
- } else if (ch < "0" || ch > "9") {
286
- // An operator or a paren ends the current operand.
287
- dotInNumber = false;
288
- }
289
- out += ch;
290
- }
291
- return out;
292
- }
293
-
294
- /** A bare, unsigned amount: digits with at most one decimal separator and nothing
295
- * else — "42", "42.", ".5", "0,5". NOT "" (an empty field has no figure to put a
296
- * sign in front of), not "-42", not "12+5". It is the only shape a DISPLAYED sign
297
- * prefix makes sense in front of; an expression carries its own arithmetic and has
298
- * to survive keystroke-for-keystroke. */
299
- export function isBareAmount(s: string): boolean {
300
- const t = s.trim();
301
- return t !== "" && /^\d*[.,]?\d*$/.test(t);
302
- }
303
-
304
- /**
305
- * Split a LEADING sign off a plain signed number (Keksdose live #201 rework):
306
- * `"-42"` → `{ sign: "-", rest: "42" }`, everything else → `{ sign: "", rest: text }`.
307
- *
308
- * Only in front of a bare amount, because a minus with arithmetic after it IS
309
- * arithmetic: "12-30" is a subtraction, and "-12+5" is -7, not -(12+5). Those come
310
- * back untouched and are resolved by {@link commitExpression} on blur — at which
311
- * point the RESULT is a plain signed number and this function does get to speak.
312
- *
313
- * A lone "-" splits (rest ""): the sign is a statement about the direction the
314
- * moment it is typed, before any digit exists.
315
- */
316
- export function splitLeadingSign(text: string): { sign: "" | "-" | "+"; rest: string } {
317
- const trimmed = text.trimStart();
318
- const sign = trimmed.charAt(0);
319
- if (sign !== "-" && sign !== "+") return { sign: "", rest: text };
320
- const rest = trimmed.slice(1);
321
- if (rest !== "" && !isBareAmount(rest)) return { sign: "", rest: text };
322
- return { sign, rest };
323
- }