@eifi1/ui-kit 0.51.7 → 0.52.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 (746) hide show
  1. package/README.md +141 -23
  2. package/dist/account/account-parts.d.ts +10 -8
  3. package/dist/account/account-parts.js +1 -18
  4. package/dist/account/account-parts.js.map +1 -1
  5. package/dist/account/data-export-setting-labels.js +1 -1
  6. package/dist/account/data-export-setting-labels.js.map +1 -1
  7. package/dist/account/delete-account-setting-labels.js +1 -1
  8. package/dist/account/delete-account-setting-labels.js.map +1 -1
  9. package/dist/account/email-change-setting-labels.js +1 -1
  10. package/dist/account/email-change-setting-labels.js.map +1 -1
  11. package/dist/account/passkeys-setting.d.ts +9 -2
  12. package/dist/account/passkeys-setting.js +41 -29
  13. package/dist/account/passkeys-setting.js.map +1 -1
  14. package/dist/account/sessions-setting.d.ts +3 -2
  15. package/dist/account/sessions-setting.js +10 -8
  16. package/dist/account/sessions-setting.js.map +1 -1
  17. package/dist/admin/admin-action-confirm.js +1 -3
  18. package/dist/admin/admin-action-confirm.js.map +1 -1
  19. package/dist/admin/admin-parts.d.ts +6 -3
  20. package/dist/admin/admin-parts.js +6 -21
  21. package/dist/admin/admin-parts.js.map +1 -1
  22. package/dist/admin/mail-test-card-labels.js +1 -1
  23. package/dist/admin/mail-test-card-labels.js.map +1 -1
  24. package/dist/admin/plan-change-labels.d.ts +2 -2
  25. package/dist/admin/plan-change-labels.js +1 -17
  26. package/dist/admin/plan-change-labels.js.map +1 -1
  27. package/dist/admin/plan-change.d.ts +3 -42
  28. package/dist/admin/plan-change.js +1 -1
  29. package/dist/admin/plan-change.js.map +1 -1
  30. package/dist/admin/reviewer-scope-editor.js +3 -3
  31. package/dist/admin/reviewer-scope-editor.js.map +1 -1
  32. package/dist/auth/auth-errors-labels.d.ts +11 -0
  33. package/dist/auth/auth-errors-labels.js +13 -0
  34. package/dist/auth/auth-errors-labels.js.map +1 -0
  35. package/dist/auth/auth-errors.d.ts +7 -23
  36. package/dist/auth/auth-errors.js +2 -15
  37. package/dist/auth/auth-errors.js.map +1 -1
  38. package/dist/auth/complete-name-dialog.js +2 -1
  39. package/dist/auth/complete-name-dialog.js.map +1 -1
  40. package/dist/auth/forgot-password-form-labels.js +1 -1
  41. package/dist/auth/forgot-password-form-labels.js.map +1 -1
  42. package/dist/auth/forgot-password-form.js +7 -2
  43. package/dist/auth/forgot-password-form.js.map +1 -1
  44. package/dist/auth/register-form-labels.js +1 -1
  45. package/dist/auth/register-form-labels.js.map +1 -1
  46. package/dist/auth/reset-password-form-labels.js +1 -1
  47. package/dist/auth/reset-password-form-labels.js.map +1 -1
  48. package/dist/auth/reset-password-form.js +5 -1
  49. package/dist/auth/reset-password-form.js.map +1 -1
  50. package/dist/auth/sign-in-form-labels.js +1 -1
  51. package/dist/auth/sign-in-form-labels.js.map +1 -1
  52. package/dist/auth/status-parts.d.ts +0 -3
  53. package/dist/auth/status-parts.js +0 -4
  54. package/dist/auth/status-parts.js.map +1 -1
  55. package/dist/auth/verify-email-labels.js +1 -1
  56. package/dist/auth/verify-email-labels.js.map +1 -1
  57. package/dist/auth/verify-email.js +7 -2
  58. package/dist/auth/verify-email.js.map +1 -1
  59. package/dist/billing/cancel-subscription.d.ts +20 -8
  60. package/dist/billing/cancel-subscription.js +7 -5
  61. package/dist/billing/cancel-subscription.js.map +1 -1
  62. package/dist/billing/dialog-close.d.ts +29 -0
  63. package/dist/billing/dialog-close.js +8 -0
  64. package/dist/billing/dialog-close.js.map +1 -0
  65. package/dist/billing/plan-card.d.ts +14 -4
  66. package/dist/billing/plan-card.js +15 -8
  67. package/dist/billing/plan-card.js.map +1 -1
  68. package/dist/billing/plan-change-labels.d.ts +42 -0
  69. package/dist/billing/plan-change-labels.js +22 -0
  70. package/dist/billing/plan-change-labels.js.map +1 -0
  71. package/dist/billing/plan-switch.d.ts +19 -7
  72. package/dist/billing/plan-switch.js +8 -4
  73. package/dist/billing/plan-switch.js.map +1 -1
  74. package/dist/chart.d.ts +12 -0
  75. package/dist/chart.js +16 -1
  76. package/dist/chart.js.map +1 -1
  77. package/dist/components/account-chips.d.ts +5 -5
  78. package/dist/components/account-chips.js +11 -13
  79. package/dist/components/account-chips.js.map +1 -1
  80. package/dist/components/alert-banner.d.ts +16 -5
  81. package/dist/components/alert-banner.js +46 -1
  82. package/dist/components/alert-banner.js.map +1 -1
  83. package/dist/components/amount-input.d.ts +13 -0
  84. package/dist/components/amount-input.js +1 -0
  85. package/dist/components/amount-input.js.map +1 -1
  86. package/dist/components/autocomplete.js +57 -65
  87. package/dist/components/autocomplete.js.map +1 -1
  88. package/dist/components/bulk-action-bar.d.ts +12 -2
  89. package/dist/components/bulk-action-bar.js +65 -21
  90. package/dist/components/bulk-action-bar.js.map +1 -1
  91. package/dist/components/button-look.d.ts +5 -5
  92. package/dist/components/button-look.js.map +1 -1
  93. package/dist/components/button.d.ts +2 -2
  94. package/dist/components/button.js.map +1 -1
  95. package/dist/components/chart-edge.d.ts +16 -0
  96. package/dist/components/chart-edge.js +14 -1
  97. package/dist/components/chart-edge.js.map +1 -1
  98. package/dist/components/chart-figure.d.ts +13 -0
  99. package/dist/components/chart-figure.js +15 -0
  100. package/dist/components/chart-figure.js.map +1 -0
  101. package/dist/components/chart-zoom-core.js +1 -4
  102. package/dist/components/chart-zoom-core.js.map +1 -1
  103. package/dist/components/chart.d.ts +8 -1
  104. package/dist/components/chart.js +19 -10
  105. package/dist/components/chart.js.map +1 -1
  106. package/dist/components/combobox-core.d.ts +111 -2
  107. package/dist/components/combobox-core.js +148 -42
  108. package/dist/components/combobox-core.js.map +1 -1
  109. package/dist/components/combobox.d.ts +1 -1
  110. package/dist/components/combobox.js +141 -130
  111. package/dist/components/combobox.js.map +1 -1
  112. package/dist/components/copy-button.d.ts +6 -5
  113. package/dist/components/copy-button.js +5 -3
  114. package/dist/components/copy-button.js.map +1 -1
  115. package/dist/components/country-select.js +2 -2
  116. package/dist/components/country-select.js.map +1 -1
  117. package/dist/components/data-table-column-settings.d.ts +1 -1
  118. package/dist/components/data-table-column-settings.js +33 -7
  119. package/dist/components/data-table-column-settings.js.map +1 -1
  120. package/dist/components/data-table-filters.d.ts +4 -2
  121. package/dist/components/data-table-filters.js +2 -2
  122. package/dist/components/data-table-filters.js.map +1 -1
  123. package/dist/components/data-table-fit.d.ts +6 -4
  124. package/dist/components/data-table-fit.js +4 -1
  125. package/dist/components/data-table-fit.js.map +1 -1
  126. package/dist/components/data-table-groups.d.ts +1 -1
  127. package/dist/components/data-table-groups.js.map +1 -1
  128. package/dist/components/data-table-head.d.ts +1 -1
  129. package/dist/components/data-table-head.js +15 -12
  130. package/dist/components/data-table-head.js.map +1 -1
  131. package/dist/components/data-table-mobile.d.ts +12 -7
  132. package/dist/components/data-table-mobile.js +43 -30
  133. package/dist/components/data-table-mobile.js.map +1 -1
  134. package/dist/components/data-table-pagination.js +11 -6
  135. package/dist/components/data-table-pagination.js.map +1 -1
  136. package/dist/components/data-table-resize.d.ts +1 -1
  137. package/dist/components/data-table-resize.js.map +1 -1
  138. package/dist/components/data-table-row-actions.d.ts +2 -2
  139. package/dist/components/data-table-row-actions.js.map +1 -1
  140. package/dist/components/data-table-row.d.ts +6 -2
  141. package/dist/components/data-table-row.js +17 -10
  142. package/dist/components/data-table-row.js.map +1 -1
  143. package/dist/components/data-table-selection.d.ts +1 -1
  144. package/dist/components/data-table-selection.js.map +1 -1
  145. package/dist/components/data-table-shared.d.ts +10 -2
  146. package/dist/components/data-table-shared.js +18 -0
  147. package/dist/components/data-table-shared.js.map +1 -1
  148. package/dist/components/data-table-sort.d.ts +21 -2
  149. package/dist/components/data-table-sort.js +24 -0
  150. package/dist/components/data-table-sort.js.map +1 -1
  151. package/dist/components/data-table-virtual.d.ts +1 -1
  152. package/dist/components/data-table-virtual.js +18 -6
  153. package/dist/components/data-table-virtual.js.map +1 -1
  154. package/dist/components/data-table.d.ts +13 -4
  155. package/dist/components/data-table.js +139 -36
  156. package/dist/components/data-table.js.map +1 -1
  157. package/dist/components/date-field.d.ts +24 -2
  158. package/dist/components/date-field.js +33 -8
  159. package/dist/components/date-field.js.map +1 -1
  160. package/dist/components/date-picker.d.ts +15 -2
  161. package/dist/components/date-picker.js +55 -26
  162. package/dist/components/date-picker.js.map +1 -1
  163. package/dist/components/date-range-picker.d.ts +47 -20
  164. package/dist/components/date-range-picker.js +23 -7
  165. package/dist/components/date-range-picker.js.map +1 -1
  166. package/dist/components/error-boundary.js +37 -30
  167. package/dist/components/error-boundary.js.map +1 -1
  168. package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
  169. package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
  170. package/dist/components/field-base-labels.js.map +1 -0
  171. package/dist/components/field-base.d.ts +4 -3
  172. package/dist/components/field-base.js +3 -3
  173. package/dist/components/field-base.js.map +1 -1
  174. package/dist/components/field-sync-labels.d.ts +1 -0
  175. package/dist/components/field-sync-labels.js.map +1 -1
  176. package/dist/components/field-sync.d.ts +23 -1
  177. package/dist/components/field-sync.js.map +1 -1
  178. package/dist/components/form-actions.js +11 -5
  179. package/dist/components/form-actions.js.map +1 -1
  180. package/dist/components/hover-menu.d.ts +3 -0
  181. package/dist/components/hover-menu.js +5 -3
  182. package/dist/components/hover-menu.js.map +1 -1
  183. package/dist/components/icon-button.js +14 -9
  184. package/dist/components/icon-button.js.map +1 -1
  185. package/dist/components/inline-confirm.d.ts +43 -0
  186. package/dist/components/inline-confirm.js +67 -0
  187. package/dist/components/inline-confirm.js.map +1 -0
  188. package/dist/components/inline-entity-combobox.d.ts +4 -3
  189. package/dist/components/inline-entity-combobox.js +148 -140
  190. package/dist/components/inline-entity-combobox.js.map +1 -1
  191. package/dist/components/input.js +1 -1
  192. package/dist/components/input.js.map +1 -1
  193. package/dist/components/jump-calendar.js +28 -112
  194. package/dist/components/jump-calendar.js.map +1 -1
  195. package/dist/components/legal-page.d.ts +3 -1
  196. package/dist/components/legal-page.js +3 -2
  197. package/dist/components/legal-page.js.map +1 -1
  198. package/dist/components/legal.d.ts +4 -2
  199. package/dist/components/legal.js.map +1 -1
  200. package/dist/components/lightbox.d.ts +2 -2
  201. package/dist/components/lightbox.js +17 -6
  202. package/dist/components/lightbox.js.map +1 -1
  203. package/dist/components/list.d.ts +6 -2
  204. package/dist/components/list.js +3 -2
  205. package/dist/components/list.js.map +1 -1
  206. package/dist/components/measured-grid.d.ts +1 -1
  207. package/dist/components/measured-grid.js +2 -1
  208. package/dist/components/measured-grid.js.map +1 -1
  209. package/dist/components/mini-calendar.js +3 -5
  210. package/dist/components/mini-calendar.js.map +1 -1
  211. package/dist/components/modal.js +3 -1
  212. package/dist/components/modal.js.map +1 -1
  213. package/dist/components/month-grid.d.ts +55 -0
  214. package/dist/components/month-grid.js +148 -0
  215. package/dist/components/month-grid.js.map +1 -0
  216. package/dist/components/month-picker.d.ts +36 -4
  217. package/dist/components/month-picker.js +123 -146
  218. package/dist/components/month-picker.js.map +1 -1
  219. package/dist/components/multi-select.d.ts +2 -2
  220. package/dist/components/multi-select.js +11 -6
  221. package/dist/components/multi-select.js.map +1 -1
  222. package/dist/components/picker-sheet.js +2 -1
  223. package/dist/components/picker-sheet.js.map +1 -1
  224. package/dist/components/pie-chart-labels.d.ts +7 -0
  225. package/dist/components/pie-chart-labels.js +1 -0
  226. package/dist/components/pie-chart-labels.js.map +1 -1
  227. package/dist/components/pie-chart.d.ts +5 -3
  228. package/dist/components/pie-chart.js +7 -22
  229. package/dist/components/pie-chart.js.map +1 -1
  230. package/dist/components/popover.d.ts +3 -0
  231. package/dist/components/popover.js +7 -1
  232. package/dist/components/popover.js.map +1 -1
  233. package/dist/components/row-actions.js +2 -1
  234. package/dist/components/row-actions.js.map +1 -1
  235. package/dist/components/section-nav.d.ts +7 -0
  236. package/dist/components/section-nav.js.map +1 -1
  237. package/dist/components/series-chart-axes.d.ts +3 -3
  238. package/dist/components/series-chart-axes.js.map +1 -1
  239. package/dist/components/series-chart-labels.d.ts +7 -4
  240. package/dist/components/series-chart-labels.js.map +1 -1
  241. package/dist/components/series-chart.d.ts +31 -7
  242. package/dist/components/series-chart.js +72 -29
  243. package/dist/components/series-chart.js.map +1 -1
  244. package/dist/components/share-card.js +3 -3
  245. package/dist/components/share-card.js.map +1 -1
  246. package/dist/components/sign-chip-labels.d.ts +1 -0
  247. package/dist/components/sign-chip-labels.js.map +1 -1
  248. package/dist/components/sign-chip.d.ts +10 -1
  249. package/dist/components/sign-chip.js.map +1 -1
  250. package/dist/components/tabs-labels.d.ts +2 -0
  251. package/dist/components/tabs-labels.js +11 -0
  252. package/dist/components/tabs-labels.js.map +1 -0
  253. package/dist/components/tabs.d.ts +1 -1
  254. package/dist/components/tabs.js +1 -1
  255. package/dist/components/tabs.js.map +1 -1
  256. package/dist/components/toggle-legend.d.ts +2 -2
  257. package/dist/components/toggle-legend.js +6 -6
  258. package/dist/components/toggle-legend.js.map +1 -1
  259. package/dist/components/translation-review-editor.d.ts +4 -2
  260. package/dist/components/translation-review-editor.js +2 -3
  261. package/dist/components/translation-review-editor.js.map +1 -1
  262. package/dist/components/translation-review.d.ts +2 -1
  263. package/dist/components/translation-review.js +2 -2
  264. package/dist/components/translation-review.js.map +1 -1
  265. package/dist/components/treemap-labels.d.ts +26 -0
  266. package/dist/components/treemap-labels.js +10 -0
  267. package/dist/components/treemap-labels.js.map +1 -0
  268. package/dist/components/treemap-layout.d.ts +62 -0
  269. package/dist/components/treemap-layout.js +126 -0
  270. package/dist/components/treemap-layout.js.map +1 -0
  271. package/dist/components/treemap.d.ts +140 -17
  272. package/dist/components/treemap.js +324 -97
  273. package/dist/components/treemap.js.map +1 -1
  274. package/dist/components/use-table-state.d.ts +5 -5
  275. package/dist/components/use-table-state.js +4 -1
  276. package/dist/components/use-table-state.js.map +1 -1
  277. package/dist/data-table.d.ts +6 -2
  278. package/dist/data-table.js +7 -2
  279. package/dist/data-table.js.map +1 -1
  280. package/dist/eslint/index.js +1 -1
  281. package/dist/eslint/role-utilities.d.ts +36 -7
  282. package/dist/eslint/role-utilities.js +42 -9
  283. package/dist/eslint/role-utilities.js.map +1 -1
  284. package/dist/feedback/feedback-dialog.d.ts +25 -16
  285. package/dist/feedback/feedback-dialog.js +6 -2
  286. package/dist/feedback/feedback-dialog.js.map +1 -1
  287. package/dist/feedback/feedback-mutation.d.ts +30 -0
  288. package/dist/feedback/feedback-mutation.js +16 -0
  289. package/dist/feedback/feedback-mutation.js.map +1 -0
  290. package/dist/feedback/feedback-page-link.d.ts +53 -0
  291. package/dist/feedback/feedback-page-link.js +37 -0
  292. package/dist/feedback/feedback-page-link.js.map +1 -0
  293. package/dist/feedback/feedback-public-list.d.ts +12 -3
  294. package/dist/feedback/feedback-public-list.js +2 -1
  295. package/dist/feedback/feedback-public-list.js.map +1 -1
  296. package/dist/feedback/feedback-replies.d.ts +3 -1
  297. package/dist/feedback/feedback-replies.js +5 -4
  298. package/dist/feedback/feedback-replies.js.map +1 -1
  299. package/dist/feedback/feedback-row-detail-labels.js +5 -0
  300. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  301. package/dist/feedback/feedback-row-detail.d.ts +64 -28
  302. package/dist/feedback/feedback-row-detail.js +30 -28
  303. package/dist/feedback/feedback-row-detail.js.map +1 -1
  304. package/dist/feedback/feedback-status-undo.d.ts +30 -11
  305. package/dist/feedback/feedback-status-undo.js +10 -15
  306. package/dist/feedback/feedback-status-undo.js.map +1 -1
  307. package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
  308. package/dist/feedback/feedback-submit-dialog.js +1 -1
  309. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  310. package/dist/feedback/feedback-submit.js +9 -3
  311. package/dist/feedback/feedback-submit.js.map +1 -1
  312. package/dist/feedback/feedback-swipe.d.ts +1 -1
  313. package/dist/feedback/feedback-swipe.js.map +1 -1
  314. package/dist/feedback/feedback-table.d.ts +21 -9
  315. package/dist/feedback/feedback-table.js +45 -25
  316. package/dist/feedback/feedback-table.js.map +1 -1
  317. package/dist/feedback/feedback-thread-labels.d.ts +2 -2
  318. package/dist/feedback/feedback-thread-labels.js.map +1 -1
  319. package/dist/feedback/feedback-thread.d.ts +24 -23
  320. package/dist/feedback/feedback-thread.js +2 -1
  321. package/dist/feedback/feedback-thread.js.map +1 -1
  322. package/dist/feedback.d.ts +34 -0
  323. package/dist/feedback.js +42 -0
  324. package/dist/feedback.js.map +1 -1
  325. package/dist/hooks/use-focus-trap.d.ts +35 -0
  326. package/dist/hooks/use-focus-trap.js +6 -4
  327. package/dist/hooks/use-focus-trap.js.map +1 -1
  328. package/dist/hooks/use-hotkey.d.ts +5 -2
  329. package/dist/hooks/use-hotkey.js +5 -4
  330. package/dist/hooks/use-hotkey.js.map +1 -1
  331. package/dist/hooks/use-long-press.d.ts +7 -4
  332. package/dist/hooks/use-long-press.js +3 -0
  333. package/dist/hooks/use-long-press.js.map +1 -1
  334. package/dist/hooks/use-media-query.js +12 -4
  335. package/dist/hooks/use-media-query.js.map +1 -1
  336. package/dist/hooks/use-mounted.d.ts +22 -0
  337. package/dist/hooks/use-mounted.js +24 -0
  338. package/dist/hooks/use-mounted.js.map +1 -0
  339. package/dist/hooks/use-overlay-history.js +19 -3
  340. package/dist/hooks/use-overlay-history.js.map +1 -1
  341. package/dist/i18n/defaults.js +4 -5
  342. package/dist/i18n/defaults.js.map +1 -1
  343. package/dist/i18n/german.js +7 -1
  344. package/dist/i18n/german.js.map +1 -1
  345. package/dist/i18n/kit-labels.d.ts +9 -2
  346. package/dist/i18n/kit-labels.js.map +1 -1
  347. package/dist/i18n/locales/en.js +20 -41
  348. package/dist/i18n/locales/en.js.map +3 -3
  349. package/dist/i18n/locales/es.js +7 -1
  350. package/dist/i18n/locales/es.js.map +1 -1
  351. package/dist/i18n/locales/fr.js +20 -10
  352. package/dist/i18n/locales/fr.js.map +1 -1
  353. package/dist/i18n/locales/hu.js +9 -1
  354. package/dist/i18n/locales/hu.js.map +1 -1
  355. package/dist/i18n/locales/it.js +7 -1
  356. package/dist/i18n/locales/it.js.map +1 -1
  357. package/dist/i18n/locales/zh.js +8 -1
  358. package/dist/i18n/locales/zh.js.map +1 -1
  359. package/dist/i18n/review.js +5 -0
  360. package/dist/i18n/review.js.map +1 -1
  361. package/dist/index.d.ts +64 -17
  362. package/dist/index.js +77 -12
  363. package/dist/index.js.map +1 -1
  364. package/dist/landing/routing.d.ts +3 -1
  365. package/dist/landing/routing.js +4 -7
  366. package/dist/landing/routing.js.map +1 -1
  367. package/dist/lib/broadcast.d.ts +17 -0
  368. package/dist/lib/broadcast.js +30 -0
  369. package/dist/lib/broadcast.js.map +1 -0
  370. package/dist/lib/date-format.d.ts +37 -2
  371. package/dist/lib/date-format.js +34 -8
  372. package/dist/lib/date-format.js.map +1 -1
  373. package/dist/lib/day-format.d.ts +46 -0
  374. package/dist/lib/day-format.js +46 -0
  375. package/dist/lib/day-format.js.map +1 -0
  376. package/dist/lib/describe-failure.d.ts +14 -0
  377. package/dist/lib/describe-failure.js +9 -0
  378. package/dist/lib/describe-failure.js.map +1 -0
  379. package/dist/lib/direction.d.ts +16 -0
  380. package/dist/lib/direction.js +9 -1
  381. package/dist/lib/direction.js.map +1 -1
  382. package/dist/lib/focus-left.d.ts +63 -0
  383. package/dist/lib/focus-left.js +67 -0
  384. package/dist/lib/focus-left.js.map +1 -0
  385. package/dist/lib/format.js +5 -14
  386. package/dist/lib/format.js.map +1 -1
  387. package/dist/lib/http-status.d.ts +24 -0
  388. package/dist/lib/http-status.js +14 -0
  389. package/dist/lib/http-status.js.map +1 -0
  390. package/dist/lib/intl-cache.d.ts +14 -0
  391. package/dist/lib/intl-cache.js +15 -0
  392. package/dist/lib/intl-cache.js.map +1 -0
  393. package/dist/lib/isin.d.ts +10 -0
  394. package/dist/lib/isin.js.map +1 -1
  395. package/dist/lib/iso-day.d.ts +11 -0
  396. package/dist/lib/iso-day.js +8 -0
  397. package/dist/lib/iso-day.js.map +1 -0
  398. package/dist/lib/lazy-with-fallback.d.ts +31 -0
  399. package/dist/lib/lazy-with-fallback.js +40 -0
  400. package/dist/lib/lazy-with-fallback.js.map +1 -0
  401. package/dist/lib/path-pattern.d.ts +34 -0
  402. package/dist/lib/path-pattern.js +24 -0
  403. package/dist/lib/path-pattern.js.map +1 -0
  404. package/dist/lib/reduced-motion.d.ts +2 -1
  405. package/dist/lib/reduced-motion.js.map +1 -1
  406. package/dist/lib/round.d.ts +2 -1
  407. package/dist/lib/round.js +2 -1
  408. package/dist/lib/round.js.map +1 -1
  409. package/dist/lib/safe-storage.d.ts +24 -5
  410. package/dist/lib/safe-storage.js +27 -2
  411. package/dist/lib/safe-storage.js.map +1 -1
  412. package/dist/lib/session-refresh.js +1 -1
  413. package/dist/lib/session-refresh.js.map +1 -1
  414. package/dist/lib/share-format.d.ts +13 -0
  415. package/dist/lib/share-format.js +10 -0
  416. package/dist/lib/share-format.js.map +1 -0
  417. package/dist/lib/text-case.d.ts +17 -0
  418. package/dist/lib/text-case.js +8 -0
  419. package/dist/lib/text-case.js.map +1 -0
  420. package/dist/lib/text-match.d.ts +29 -0
  421. package/dist/lib/text-match.js +20 -2
  422. package/dist/lib/text-match.js.map +1 -1
  423. package/dist/lib/thenable.d.ts +13 -0
  424. package/dist/lib/thenable.js +8 -0
  425. package/dist/lib/thenable.js.map +1 -0
  426. package/dist/lib/translation-review.d.ts +7 -2
  427. package/dist/lib/translation-review.js +4 -4
  428. package/dist/lib/translation-review.js.map +1 -1
  429. package/dist/notifications/device-zone-report.js +1 -1
  430. package/dist/notifications/device-zone-report.js.map +1 -1
  431. package/dist/notifications/notification-bell.d.ts +2 -1
  432. package/dist/notifications/notification-bell.js +3 -3
  433. package/dist/notifications/notification-bell.js.map +1 -1
  434. package/dist/notifications/notification-inbox.d.ts +10 -6
  435. package/dist/notifications/notification-inbox.js +26 -48
  436. package/dist/notifications/notification-inbox.js.map +1 -1
  437. package/dist/notifications/notification-parts.d.ts +3 -2
  438. package/dist/notifications/notification-parts.js +1 -3
  439. package/dist/notifications/notification-parts.js.map +1 -1
  440. package/dist/notifications/notification-types-setting.js +1 -1
  441. package/dist/notifications/notification-types-setting.js.map +1 -1
  442. package/dist/notifications/notifications-labels.d.ts +6 -0
  443. package/dist/notifications/notifications-labels.js +1 -0
  444. package/dist/notifications/notifications-labels.js.map +1 -1
  445. package/dist/notifications/push-device-setting.js +1 -1
  446. package/dist/notifications/push-device-setting.js.map +1 -1
  447. package/dist/notifications/push-devices-setting.d.ts +2 -1
  448. package/dist/notifications/push-devices-setting.js +27 -49
  449. package/dist/notifications/push-devices-setting.js.map +1 -1
  450. package/dist/notifications/quiet-hours-setting.d.ts +10 -3
  451. package/dist/notifications/quiet-hours-setting.js +65 -26
  452. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  453. package/dist/notifications/unsubscribe-panel.js +4 -7
  454. package/dist/notifications/unsubscribe-panel.js.map +1 -1
  455. package/dist/notifications/use-push-device.d.ts +39 -1
  456. package/dist/notifications/use-push-device.js +28 -7
  457. package/dist/notifications/use-push-device.js.map +1 -1
  458. package/dist/offline/query-persistence.d.ts +3 -1
  459. package/dist/offline/query-persistence.js +19 -2
  460. package/dist/offline/query-persistence.js.map +1 -1
  461. package/dist/rhf/fields.d.ts +11 -4
  462. package/dist/rhf/fields.js.map +1 -1
  463. package/dist/search/command-palette.js +1 -1
  464. package/dist/search/command-palette.js.map +1 -1
  465. package/dist/search/global-search.js +19 -9
  466. package/dist/search/global-search.js.map +1 -1
  467. package/dist/search/use-command-key.d.ts +12 -1
  468. package/dist/search/use-command-key.js +3 -12
  469. package/dist/search/use-command-key.js.map +1 -1
  470. package/dist/search.d.ts +7 -0
  471. package/dist/search.js +10 -0
  472. package/dist/search.js.map +1 -1
  473. package/dist/settings/use-settings-focus.js +1 -0
  474. package/dist/settings/use-settings-focus.js.map +1 -1
  475. package/dist/shell/account-menu-language.d.ts +21 -5
  476. package/dist/shell/account-menu-language.js +3 -1
  477. package/dist/shell/account-menu-language.js.map +1 -1
  478. package/dist/shell/account-menu-text-size.d.ts +26 -9
  479. package/dist/shell/account-menu-text-size.js +3 -2
  480. package/dist/shell/account-menu-text-size.js.map +1 -1
  481. package/dist/shell/dev-menu.js +5 -18
  482. package/dist/shell/dev-menu.js.map +1 -1
  483. package/dist/shell/role-switcher.d.ts +7 -0
  484. package/dist/shell/role-switcher.js.map +1 -1
  485. package/dist/shell/top-bar-actions.d.ts +1 -1
  486. package/dist/shell/top-bar-actions.js.map +1 -1
  487. package/dist/shell/top-bar-parts-labels.d.ts +0 -2
  488. package/dist/shell/top-bar-parts-labels.js +0 -1
  489. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  490. package/dist/shell.d.ts +27 -8
  491. package/dist/shell.js +28 -7
  492. package/dist/shell.js.map +1 -1
  493. package/dist/sync/engine.d.ts +30 -4
  494. package/dist/sync/engine.js +172 -52
  495. package/dist/sync/engine.js.map +1 -1
  496. package/dist/sync.d.ts +6 -2
  497. package/dist/sync.js +6 -1
  498. package/dist/sync.js.map +1 -1
  499. package/dist/testing/css-variables.js +3 -8
  500. package/dist/testing/css-variables.js.map +1 -1
  501. package/dist/theme/contrast.d.ts +2 -1
  502. package/dist/theme/contrast.js +3 -8
  503. package/dist/theme/contrast.js.map +1 -1
  504. package/dist/theme/palette-store.js +6 -6
  505. package/dist/theme/palette-store.js.map +1 -1
  506. package/dist/theme/text-size.js +3 -8
  507. package/dist/theme/text-size.js.map +1 -1
  508. package/dist/theme/theme-store.js +3 -6
  509. package/dist/theme/theme-store.js.map +1 -1
  510. package/dist/tour/tour-catalogue.d.ts +7 -4
  511. package/dist/tour/tour-catalogue.js +12 -10
  512. package/dist/tour/tour-catalogue.js.map +1 -1
  513. package/dist/tour/tour-dock.d.ts +0 -2
  514. package/dist/tour/tour-dock.js +0 -2
  515. package/dist/tour/tour-dock.js.map +1 -1
  516. package/dist/tour/tour-gates.d.ts +4 -0
  517. package/dist/tour/tour-gates.js +14 -0
  518. package/dist/tour/tour-gates.js.map +1 -1
  519. package/dist/tour/tour-overlay.d.ts +27 -0
  520. package/dist/tour/tour-overlay.js +741 -0
  521. package/dist/tour/tour-overlay.js.map +1 -0
  522. package/dist/tour/tour.d.ts +13 -3
  523. package/dist/tour/tour.js +59 -781
  524. package/dist/tour/tour.js.map +1 -1
  525. package/dist/tour/use-tour-progress.js +1 -1
  526. package/dist/tour/use-tour-progress.js.map +1 -1
  527. package/dist/wizard/stepper-nav.d.ts +5 -1
  528. package/dist/wizard/stepper-nav.js.map +1 -1
  529. package/dist/wizard/types.d.ts +6 -2
  530. package/dist/wizard/types.js.map +1 -1
  531. package/dist/wizard/use-wizard.d.ts +3 -1
  532. package/dist/wizard/use-wizard.js.map +1 -1
  533. package/dist/wizard/validation.d.ts +3 -1
  534. package/dist/wizard/validation.js.map +1 -1
  535. package/package.json +10 -6
  536. package/src/account/account-parts.ts +5 -25
  537. package/src/account/data-export-setting-labels.ts +1 -1
  538. package/src/account/delete-account-setting-labels.ts +1 -1
  539. package/src/account/email-change-setting-labels.ts +1 -1
  540. package/src/account/passkeys-setting.tsx +60 -38
  541. package/src/account/sessions-setting.tsx +18 -12
  542. package/src/admin/admin-action-confirm.tsx +1 -5
  543. package/src/admin/admin-parts.ts +11 -25
  544. package/src/admin/mail-test-card-labels.ts +1 -1
  545. package/src/admin/plan-change-labels.ts +5 -23
  546. package/src/admin/plan-change.tsx +7 -44
  547. package/src/admin/reviewer-scope-editor.tsx +3 -3
  548. package/src/auth/auth-errors-labels.ts +23 -0
  549. package/src/auth/auth-errors.ts +11 -38
  550. package/src/auth/complete-name-dialog.tsx +4 -1
  551. package/src/auth/forgot-password-form-labels.ts +1 -1
  552. package/src/auth/forgot-password-form.tsx +11 -6
  553. package/src/auth/register-form-labels.ts +1 -1
  554. package/src/auth/reset-password-form-labels.ts +1 -1
  555. package/src/auth/reset-password-form.tsx +8 -4
  556. package/src/auth/sign-in-form-labels.ts +1 -1
  557. package/src/auth/status-parts.tsx +0 -6
  558. package/src/auth/verify-email-labels.ts +1 -1
  559. package/src/auth/verify-email.tsx +11 -6
  560. package/src/billing/cancel-subscription.tsx +26 -12
  561. package/src/billing/dialog-close.ts +34 -0
  562. package/src/billing/plan-card.tsx +36 -11
  563. package/src/billing/plan-change-labels.ts +66 -0
  564. package/src/billing/plan-switch.tsx +26 -12
  565. package/src/chart.ts +21 -3
  566. package/src/components/account-chips.tsx +20 -23
  567. package/src/components/alert-banner.tsx +82 -5
  568. package/src/components/amount-input.tsx +18 -7
  569. package/src/components/autocomplete.tsx +64 -70
  570. package/src/components/bulk-action-bar.tsx +70 -2
  571. package/src/components/button-look.ts +5 -5
  572. package/src/components/button.tsx +2 -2
  573. package/src/components/chart-edge.ts +34 -1
  574. package/src/components/chart-figure.tsx +35 -0
  575. package/src/components/chart-zoom-core.tsx +6 -5
  576. package/src/components/chart.tsx +26 -5
  577. package/src/components/combobox-core.tsx +293 -62
  578. package/src/components/combobox.tsx +183 -153
  579. package/src/components/copy-button.tsx +34 -23
  580. package/src/components/country-select.tsx +16 -11
  581. package/src/components/data-table-column-settings.tsx +52 -10
  582. package/src/components/data-table-filters.ts +6 -4
  583. package/src/components/data-table-fit.ts +19 -5
  584. package/src/components/data-table-groups.tsx +1 -1
  585. package/src/components/data-table-head.tsx +32 -22
  586. package/src/components/data-table-mobile.tsx +61 -26
  587. package/src/components/data-table-pagination.tsx +21 -6
  588. package/src/components/data-table-resize.ts +1 -1
  589. package/src/components/data-table-row-actions.tsx +3 -3
  590. package/src/components/data-table-row.tsx +25 -14
  591. package/src/components/data-table-selection.ts +1 -1
  592. package/src/components/data-table-shared.tsx +33 -1
  593. package/src/components/data-table-sort.ts +57 -2
  594. package/src/components/data-table-virtual.ts +32 -8
  595. package/src/components/data-table.tsx +239 -68
  596. package/src/components/date-field.tsx +65 -8
  597. package/src/components/date-picker.tsx +125 -48
  598. package/src/components/date-range-picker.tsx +82 -31
  599. package/src/components/error-boundary.tsx +53 -39
  600. package/src/components/field-base-labels.ts +20 -0
  601. package/src/components/field-base.tsx +13 -7
  602. package/src/components/field-sync-labels.ts +1 -0
  603. package/src/components/field-sync.tsx +23 -1
  604. package/src/components/form-actions.tsx +20 -5
  605. package/src/components/hover-menu.tsx +18 -8
  606. package/src/components/icon-button.tsx +14 -9
  607. package/src/components/inline-confirm.tsx +116 -0
  608. package/src/components/inline-entity-combobox.tsx +197 -153
  609. package/src/components/input.tsx +1 -1
  610. package/src/components/jump-calendar.tsx +30 -146
  611. package/src/components/legal-page.tsx +10 -7
  612. package/src/components/legal.tsx +4 -2
  613. package/src/components/lightbox.tsx +21 -8
  614. package/src/components/list.tsx +10 -4
  615. package/src/components/measured-grid.tsx +8 -4
  616. package/src/components/mini-calendar.tsx +6 -5
  617. package/src/components/modal.tsx +6 -1
  618. package/src/components/month-grid.tsx +229 -0
  619. package/src/components/month-picker.tsx +192 -200
  620. package/src/components/multi-select.tsx +21 -9
  621. package/src/components/picker-sheet.tsx +12 -9
  622. package/src/components/pie-chart-labels.ts +8 -0
  623. package/src/components/pie-chart.tsx +22 -28
  624. package/src/components/popover.tsx +18 -1
  625. package/src/components/row-actions.tsx +2 -1
  626. package/src/components/section-nav.tsx +7 -0
  627. package/src/components/series-chart-axes.ts +3 -3
  628. package/src/components/series-chart-labels.ts +7 -4
  629. package/src/components/series-chart.tsx +178 -69
  630. package/src/components/share-card.tsx +6 -6
  631. package/src/components/sign-chip-labels.ts +1 -0
  632. package/src/components/sign-chip.tsx +10 -1
  633. package/src/components/tabs-labels.ts +13 -0
  634. package/src/components/tabs.tsx +2 -2
  635. package/src/components/toggle-legend.tsx +16 -11
  636. package/src/components/translation-review-editor.tsx +6 -5
  637. package/src/components/translation-review.tsx +4 -3
  638. package/src/components/treemap-labels.ts +39 -0
  639. package/src/components/treemap-layout.ts +210 -0
  640. package/src/components/treemap.tsx +722 -133
  641. package/src/components/use-table-state.ts +12 -9
  642. package/src/data-table.ts +9 -2
  643. package/src/eslint/role-utilities.ts +97 -19
  644. package/src/feedback/feedback-dialog.tsx +30 -19
  645. package/src/feedback/feedback-mutation.ts +41 -0
  646. package/src/feedback/feedback-page-link.ts +90 -0
  647. package/src/feedback/feedback-public-list.tsx +17 -5
  648. package/src/feedback/feedback-replies.tsx +13 -6
  649. package/src/feedback/feedback-row-detail-labels.ts +5 -0
  650. package/src/feedback/feedback-row-detail.tsx +103 -67
  651. package/src/feedback/feedback-status-undo.ts +41 -27
  652. package/src/feedback/feedback-submit-dialog.tsx +2 -2
  653. package/src/feedback/feedback-submit.tsx +21 -7
  654. package/src/feedback/feedback-swipe.tsx +1 -1
  655. package/src/feedback/feedback-table.tsx +86 -38
  656. package/src/feedback/feedback-thread-labels.ts +2 -2
  657. package/src/feedback/feedback-thread.tsx +27 -25
  658. package/src/feedback.ts +42 -0
  659. package/src/hooks/use-focus-trap.ts +8 -24
  660. package/src/hooks/use-hotkey.ts +24 -7
  661. package/src/hooks/use-long-press.ts +16 -2
  662. package/src/hooks/use-media-query.ts +20 -4
  663. package/src/hooks/use-mounted.ts +39 -0
  664. package/src/hooks/use-overlay-history.ts +32 -3
  665. package/src/i18n/defaults.ts +4 -5
  666. package/src/i18n/german.ts +8 -2
  667. package/src/i18n/kit-labels.tsx +9 -2
  668. package/src/i18n/locales/es.ts +8 -2
  669. package/src/i18n/locales/fr.ts +21 -13
  670. package/src/i18n/locales/hu.ts +10 -2
  671. package/src/i18n/locales/it.ts +8 -2
  672. package/src/i18n/locales/zh.ts +9 -2
  673. package/src/i18n/review.ts +5 -0
  674. package/src/index.ts +103 -13
  675. package/src/landing/routing.tsx +14 -10
  676. package/src/lib/broadcast.ts +52 -0
  677. package/src/lib/date-format.ts +89 -13
  678. package/src/lib/day-format.ts +96 -0
  679. package/src/lib/describe-failure.ts +18 -0
  680. package/src/lib/direction.ts +39 -0
  681. package/src/lib/focus-left.ts +156 -0
  682. package/src/lib/format.ts +5 -17
  683. package/src/lib/http-status.ts +38 -0
  684. package/src/lib/intl-cache.ts +25 -0
  685. package/src/lib/isin.ts +10 -0
  686. package/src/lib/iso-day.ts +13 -0
  687. package/src/lib/lazy-with-fallback.ts +82 -0
  688. package/src/lib/path-pattern.ts +55 -0
  689. package/src/lib/reduced-motion.ts +2 -1
  690. package/src/lib/round.ts +7 -2
  691. package/src/lib/safe-storage.ts +48 -6
  692. package/src/lib/session-refresh.ts +1 -1
  693. package/src/lib/share-format.ts +18 -0
  694. package/src/lib/text-case.ts +19 -0
  695. package/src/lib/text-match.ts +57 -2
  696. package/src/lib/thenable.ts +19 -0
  697. package/src/lib/translation-review.ts +13 -5
  698. package/src/notifications/device-zone-report.ts +1 -1
  699. package/src/notifications/notification-bell.tsx +7 -4
  700. package/src/notifications/notification-inbox.tsx +40 -58
  701. package/src/notifications/notification-parts.tsx +3 -4
  702. package/src/notifications/notification-types-setting.tsx +1 -1
  703. package/src/notifications/notifications-labels.ts +7 -0
  704. package/src/notifications/push-device-setting.tsx +1 -1
  705. package/src/notifications/push-devices-setting.tsx +30 -55
  706. package/src/notifications/quiet-hours-setting.tsx +93 -31
  707. package/src/notifications/unsubscribe-panel.tsx +4 -7
  708. package/src/notifications/use-push-device.ts +76 -10
  709. package/src/offline/query-persistence.ts +35 -3
  710. package/src/rhf/fields.tsx +11 -4
  711. package/src/search/command-palette.tsx +2 -4
  712. package/src/search/global-search.tsx +36 -15
  713. package/src/search/use-command-key.ts +13 -12
  714. package/src/search.ts +9 -0
  715. package/src/settings/use-settings-focus.ts +3 -0
  716. package/src/shell/account-menu-language.tsx +27 -5
  717. package/src/shell/account-menu-text-size.tsx +32 -10
  718. package/src/shell/dev-menu.tsx +7 -21
  719. package/src/shell/role-switcher.tsx +7 -0
  720. package/src/shell/top-bar-actions.tsx +1 -1
  721. package/src/shell/top-bar-parts-labels.ts +0 -3
  722. package/src/shell.ts +40 -9
  723. package/src/sync/engine.ts +339 -61
  724. package/src/sync.ts +8 -1
  725. package/src/testing/css-variables.ts +8 -9
  726. package/src/theme/contrast.ts +8 -9
  727. package/src/theme/palette-store.ts +9 -9
  728. package/src/theme/text-size.ts +6 -8
  729. package/src/theme/theme-store.ts +7 -9
  730. package/src/tour/tour-catalogue.tsx +26 -15
  731. package/src/tour/tour-dock.ts +0 -2
  732. package/src/tour/tour-gates.ts +23 -0
  733. package/src/tour/tour-overlay.tsx +1170 -0
  734. package/src/tour/tour.tsx +108 -1202
  735. package/src/tour/use-tour-progress.ts +1 -1
  736. package/src/wizard/stepper-nav.tsx +3 -1
  737. package/src/wizard/types.ts +11 -2
  738. package/src/wizard/use-wizard.ts +2 -1
  739. package/src/wizard/validation.ts +8 -2
  740. package/tokens.css +2 -1
  741. package/dist/components/ui-labels.js.map +0 -1
  742. package/dist/shell/dev-switchers.d.ts +0 -6
  743. package/dist/shell/dev-switchers.js +0 -12
  744. package/dist/shell/dev-switchers.js.map +0 -1
  745. package/src/components/ui-labels.ts +0 -24
  746. package/src/shell/dev-switchers.tsx +0 -18
package/src/index.ts CHANGED
@@ -16,12 +16,25 @@ export { logger, setStoreLog } from "./lib/logger";
16
16
  // Intl number / money / percent / date / relative-time formatting, and `useKitFormat()`
17
17
  // for the same bound to the provider's locale (kastlan's formatters.ts, English "5m ago").
18
18
  export * from "./lib/format";
19
- // localStorage that never throws (Safari private mode, blocked site data).
20
- export { readStored, writeStored } from "./lib/safe-storage";
19
+ // localStorage that never throws (Safari private mode, blocked site data). 0.52 (DUP-8,
20
+ // refactor audit 2026-10-30): the remove, the sessionStorage pair and a JSON pair with a
21
+ // shape check — 16 files in the apps wrap storage by hand, a few of them with no guard.
22
+ export {
23
+ readStored,
24
+ writeStored,
25
+ removeStored,
26
+ readSessionStored,
27
+ writeSessionStored,
28
+ readStoredJson,
29
+ writeStoredJson,
30
+ } from "./lib/safe-storage";
31
+ // 0.52 (DUP-8): `prefers-reduced-motion`, asked at the moment of the motion (KS copied it).
32
+ export { prefersReducedMotion } from "./lib/reduced-motion";
21
33
  // Save a fetched Blob as a download, and read the name a Content-Disposition asks for
22
34
  // (`filename*` first) — 0.34, KS U5; the kit's own three downloads use them.
23
35
  export { saveBlob, filenameFromDisposition } from "./lib/download";
24
- // Date helpers are also available via the "@eifi1/ui-kit/dates" subpath.
36
+ // The local-calendar ISO date helpers are the "@eifi1/ui-kit/dates" entry, standalone: none
37
+ // of its names is in this barrel (public-surface.test.ts, STANDALONE).
25
38
  // One fold and one ranking for every list's search box (DUP-5), for an app's own lists;
26
39
  // and the pickers' every-word match (0.51.5), for an async `loadOptions` that filters itself.
27
40
  export { foldForSearch, rankMatch, searchWords, matchesSearch } from "./lib/text-match";
@@ -114,6 +127,7 @@ export type {
114
127
  export { COUNTRY_CODES, countryName } from "./lib/countries";
115
128
  export { IBAN_LENGTHS, compactIban, formatIban, ibanCheckDigits, ibanProblem, isValidIban, isQrIban } from "./lib/iban";
116
129
  export type { IbanKind, IbanProblem } from "./lib/iban";
130
+ // 0.52: deprecated, removed in 0.53 (MOD-5; tagged in lib/isin).
117
131
  export { formatIsin, isinCheckDigit, isValidIsin } from "./lib/isin";
118
132
  export { PHONE_DIAL_CODES, PHONE_COUNTRIES, parsePhone, formatNationalPhone, formatPhone, isE164 } from "./lib/phone";
119
133
  export type { PhoneCountryCode, PhoneCountry, ParsedPhone } from "./lib/phone";
@@ -156,12 +170,21 @@ export type { UseAnnounceReturn, UseAnnounceOptions, AnnounceRegionProps } from
156
170
  export { useOverlayHistory } from "./hooks/use-overlay-history";
157
171
  export { useCloseTransition, OVERLAY_EXIT_MS } from "./hooks/use-close-transition";
158
172
  export { useRowSwipe } from "./hooks/use-row-swipe";
173
+ // 0.52 (DUP-8): DataTable's press-and-hold, which keksdose wrote first and still keeps.
174
+ export { useLongPress } from "./hooks/use-long-press";
175
+ export type { LongPressOptions, LongPressResult } from "./hooks/use-long-press";
159
176
  // 0.28: keksdose's noindex marker, for the legal and auth pages of every app.
160
177
  export { useNoIndex } from "./hooks/use-noindex";
161
178
  // 0.49 KIT-9: the window's title from page, section and app, in the provider's format.
162
179
  export { useDocumentTitle } from "./hooks/use-document-title";
163
180
  // 0.49 KIT-1b: U+2212 before a number as "-", the copy handler's rule, for an app's text.
164
- export { asciiMinusInNumbers } from "./lib/clipboard-minus";
181
+ // 0.52: deprecated with the other 54 names no app, test or showcase page reads (refactor
182
+ // audit 2026-10-30, API-4, decision 4). Each is tagged on its specifier here, not on its
183
+ // declaration: the module keeps it for the kit's own use, only the barrel lets it go.
184
+ export {
185
+ /** @deprecated 0.52 — a formatter's `minus: "ascii"`, where the figure is made (API-4); removed in 0.53 */
186
+ asciiMinusInNumbers,
187
+ } from "./lib/clipboard-minus";
165
188
  export { DEFAULT_DOCUMENT_TITLE_FORMAT, formatDocumentTitle } from "./lib/document-title";
166
189
  export type { DocumentTitleParts } from "./lib/document-title";
167
190
  export type { SwipeStage, RowSwipeOptions, RowSwipeReturn } from "./hooks/use-row-swipe";
@@ -324,6 +347,7 @@ export * from "./components/settings-fields";
324
347
  // Sync state for a database-backed field: the engine (`useFieldSync`) and the
325
348
  // affordance (`FieldSyncIndicator`), kept separate because the state is useful
326
349
  // without the dot — a form can gate its submit on any field being `pending`.
350
+ // 0.52: deprecated as a whole, removed in 0.53 (MOD-5; tagged in the module).
327
351
  export * from "./components/field-sync";
328
352
  export * from "./components/month-picker";
329
353
  export * from "./components/checkbox";
@@ -398,7 +422,8 @@ export * from "./components/alert-banner";
398
422
  export * from "./components/toggle-group";
399
423
  // A wrapping set of links/buttons marked `aria-current` — Tabs-like looks, not tabs.
400
424
  export * from "./components/nav-pills";
401
- // 0.49.0 (KIT-6): a section's pages on the phone, one scrolling row of pills.
425
+ // 0.49.0 (KIT-6): a section's pages on the phone, one scrolling row of pills. 0.52:
426
+ // deprecated, removed in 0.53 (MOD-5; tagged in the module).
402
427
  export * from "./components/section-nav";
403
428
  // A pill carrying one VALUE — inert, a link, or a toggle, depending on which prop it is
404
429
  // given — and the list field built from it. Distinct from Button on purpose: a row of
@@ -417,6 +442,10 @@ export * from "./components/grouped-picker";
417
442
  export * from "./components/file-dropzone";
418
443
  export * from "./components/mini-calendar";
419
444
  export * from "./components/calendar-heatmap";
445
+ export {
446
+ /** @deprecated 0.52 — `CalendarHeatmap`, which steps its cells with it (API-4); removed in 0.53 */
447
+ heatmapLevel,
448
+ } from "./components/calendar-heatmap";
420
449
  export * from "./components/date-picker";
421
450
  export * from "./components/tree-view";
422
451
  // 0.8.0 layout and feedback primitives the apps hand-rolled or took from shadcn/Radix.
@@ -437,7 +466,12 @@ export {
437
466
  DEFAULT_WRITE_LOCK_LABELS,
438
467
  } from "./components/write-lock";
439
468
  // 0.46 (kastlan K4): the offline lock kind, its scope and its source.
440
- export { OFFLINE_LOCK, COMMIT_EXCEPT_OFFLINE, useOfflineWriteLock } from "./components/write-lock";
469
+ export {
470
+ /** @deprecated 0.52 — the kind itself, `"offline"`, which `useOfflineWriteLock` holds (API-4); removed in 0.53 */
471
+ OFFLINE_LOCK,
472
+ COMMIT_EXCEPT_OFFLINE,
473
+ useOfflineWriteLock,
474
+ } from "./components/write-lock";
441
475
  export type {
442
476
  WriteLock,
443
477
  WriteLockLabels,
@@ -502,6 +536,10 @@ export * from "./components/copy-button";
502
536
  export { AuthedImage, DEFAULT_AUTHED_IMAGE_LABELS } from "./components/authed-image";
503
537
  export type { AuthedImageProps, AuthedImageLabels } from "./components/authed-image";
504
538
  export * from "./components/image-grid";
539
+ export {
540
+ /** @deprecated 0.52 — `ImageGrid`, which shortens its file names with it (API-4); removed in 0.53 */
541
+ splitFileName,
542
+ } from "./components/image-grid";
505
543
  export * from "./components/lightbox";
506
544
  export * from "./components/button-group";
507
545
  export * from "./components/table";
@@ -533,8 +571,11 @@ export {
533
571
  toast,
534
572
  Toaster,
535
573
  DEFAULT_TOAST_LABELS,
574
+ /** @deprecated 0.52 — `toast()`, which times a toast with an action by it (API-4); removed in 0.53 */
536
575
  TOAST_ACTION_DURATION,
576
+ /** @deprecated 0.52 — `<Toaster>`, whose default `offset` it is (API-4); removed in 0.53 */
537
577
  TOASTER_OFFSET_TOP,
578
+ /** @deprecated 0.52 — `<Toaster>`, whose default `offset` it is (API-4); removed in 0.53 */
538
579
  TOASTER_OFFSET_BOTTOM,
539
580
  } from "./components/toast";
540
581
  export type {
@@ -626,6 +667,8 @@ export {
626
667
  isDateFormatPreference,
627
668
  resolveDateFormat,
628
669
  formatDateWithPreference,
670
+ // 0.52 (refactor audit 2026-10-30, DUP-2): a timestamp, the preference's date and the language's clock.
671
+ formatDateTimeWithPreference,
629
672
  dateFormatSample,
630
673
  dateFormatterFor,
631
674
  } from "./lib/date-format";
@@ -639,6 +682,7 @@ export {
639
682
  // 0.47.0 (keksdose N17): a hand-built table's actions heading and cell.
640
683
  RowActionsHead,
641
684
  ROW_ACTIONS_CELL_CLASS,
685
+ /** @deprecated 0.52 — `RowActionsHead`, which draws it (API-4); removed in 0.53 */
642
686
  ROW_ACTIONS_HEAD_CLASS,
643
687
  } from "./components/row-actions";
644
688
  export type {
@@ -660,6 +704,7 @@ export * from "./components/one-time-code-input";
660
704
  export * from "./components/language-select";
661
705
  export * from "./components/tile-radio";
662
706
  export * from "./components/inline-edit-field";
707
+ // 0.52: deprecated, removed in 0.53 (MOD-5; tagged in the module).
663
708
  export * from "./components/sign-chip";
664
709
  export * from "./components/country-select";
665
710
  export * from "./components/iban-input";
@@ -814,10 +859,12 @@ export type { DataExportSettingProps, DataExportLabels, DataExportFile } from ".
814
859
  // 0.30.0 (docs/user-admin-harmonization.md): the admin user list and its actions, and the
815
860
  // invitations panel. Callbacks only; the confirmation level is the server's.
816
861
  export {
862
+ /** @deprecated 0.52 — `useUserRosterColumns`, the same columns in the provider's words (API-4); removed in 0.53 */
817
863
  userRosterColumns,
818
864
  useUserRosterColumns,
819
865
  UserIdentityCell,
820
866
  UserRowActions,
867
+ /** @deprecated 0.52 — `useUserRosterColumns`, whose state cell reads it (API-4); removed in 0.53 */
821
868
  adminUserStates,
822
869
  userRosterSort,
823
870
  USER_ROSTER_SORT_KEYS,
@@ -898,7 +945,13 @@ export { adminSectionOrder } from "./admin/admin-sections";
898
945
  export type { AdminSectionPlace, AdminSectionOrderOptions, AdminKeptSection } from "./admin/admin-sections";
899
946
  export { AdminForbidden } from "./admin/admin-forbidden";
900
947
  export type { AdminForbiddenProps } from "./admin/admin-forbidden";
901
- export { AdminOverview, AttentionTile, adminWaitingCount, DEFAULT_ADMIN_ATTENTION_HREFS } from "./admin/admin-overview";
948
+ export {
949
+ AdminOverview,
950
+ AttentionTile,
951
+ adminWaitingCount,
952
+ /** @deprecated 0.52 — `AdminOverview`, which links its tiles there unless told otherwise (API-4); removed in 0.53 */
953
+ DEFAULT_ADMIN_ATTENTION_HREFS,
954
+ } from "./admin/admin-overview";
902
955
  export type {
903
956
  AdminAttention,
904
957
  AdminAttentionTile,
@@ -913,10 +966,17 @@ export type {
913
966
  export { AdminToolLinks } from "./admin/admin-tool-links";
914
967
  export type { AdminToolLink, AdminToolLinksProps } from "./admin/admin-tool-links";
915
968
  // 0.45.0 (docs/admin-harmonization.md §9.2.4): "Send a test mail to me".
916
- export { MailTestCard, DEFAULT_MAIL_TEST_CARD_LABELS, MAIL_TEST_ANCHOR, maskMailAddress } from "./admin/mail-test-card";
969
+ export {
970
+ MailTestCard,
971
+ DEFAULT_MAIL_TEST_CARD_LABELS,
972
+ MAIL_TEST_ANCHOR,
973
+ /** @deprecated 0.52 — `MailTestCard`, which masks the address itself (API-4); removed in 0.53 */
974
+ maskMailAddress,
975
+ } from "./admin/mail-test-card";
917
976
  export type { MailTestCardProps, MailTestCardLabels, MailTestAnswer } from "./admin/mail-test-card";
918
977
  // 0.33.0: the operator's plan parts (docs/billing-harmonization.md §14.12).
919
978
  export {
979
+ /** @deprecated 0.52 — `usePlanColumn`, the same column in the provider's words (API-4); removed in 0.53 */
920
980
  planColumn,
921
981
  usePlanColumn,
922
982
  PlanChangeConfirm,
@@ -947,7 +1007,13 @@ export type {
947
1007
  PlanPrices,
948
1008
  PlanPriceAnswer,
949
1009
  } from "./billing/plan-price";
950
- export { PlanCard, PlanPicker, GrantWarningConfirm, planRelation } from "./billing/plan-card";
1010
+ export {
1011
+ PlanCard,
1012
+ PlanPicker,
1013
+ GrantWarningConfirm,
1014
+ /** @deprecated 0.52 — `PlanPicker`, which marks each card's relation itself (API-4); removed in 0.53 */
1015
+ planRelation,
1016
+ } from "./billing/plan-card";
951
1017
  export type {
952
1018
  BillingPlan,
953
1019
  PlanRelation,
@@ -983,13 +1049,19 @@ export {
983
1049
  } from "./billing/checkout-return";
984
1050
  export {
985
1051
  checkoutFingerprint,
1052
+ /** @deprecated 0.52 — `useCheckoutProcessing`, which asks it (API-4); removed in 0.53 */
986
1053
  checkoutLanded,
987
1054
  noteCheckoutStarted,
988
1055
  useCheckoutProcessing,
989
1056
  } from "./billing/checkout-processing";
990
1057
  export type { CheckoutOverview, CheckoutProcessingOptions } from "./billing/checkout-processing";
991
1058
  // The link to the pay page and Paddle's locale (§14.4); the page itself ships as dist/pay/.
992
- export { PAY_PAGE_LANG_PARAM, paddleLocale, payPageUrl } from "./billing/pay-page";
1059
+ export {
1060
+ /** @deprecated 0.52 — `payPageUrl`, which writes it (API-4); removed in 0.53 */
1061
+ PAY_PAGE_LANG_PARAM,
1062
+ paddleLocale,
1063
+ payPageUrl,
1064
+ } from "./billing/pay-page";
993
1065
  export type { PaddleEnvironment } from "./billing/pay-page";
994
1066
  // 0.39 (§15.2.6): the apps every pay page serves, by their `billing_app` tag.
995
1067
  export { PAY_PAGE_APPS } from "./billing/pay-page";
@@ -1039,7 +1111,11 @@ export type {
1039
1111
  ResolveAccountLanguageInput,
1040
1112
  ResolvedAccountLanguage,
1041
1113
  } from "./settings/use-account-language";
1042
- export { useAccountAppearance, resolveAccountAppearance } from "./settings/use-account-appearance";
1114
+ export {
1115
+ useAccountAppearance,
1116
+ /** @deprecated 0.52 — `useAccountAppearance`, which resolves the same three values (API-4); removed in 0.53 */
1117
+ resolveAccountAppearance,
1118
+ } from "./settings/use-account-appearance";
1043
1119
  export type {
1044
1120
  AppearanceSource,
1045
1121
  AccountAppearanceFields,
@@ -1090,6 +1166,8 @@ export {
1090
1166
  notifyPushSubscriptionChanged,
1091
1167
  pushSupported,
1092
1168
  PushDeviceError,
1169
+ // 0.52 (§10.6, refactor audit 2026-10-30 FLW-2): an explicit sign-out releases this device's push.
1170
+ releaseThisDevicePush,
1093
1171
  } from "./notifications/use-push-device";
1094
1172
  export type {
1095
1173
  PushDevice,
@@ -1114,7 +1192,11 @@ export type {
1114
1192
  } from "./notifications/push-worker";
1115
1193
  export { PushDeviceSetting } from "./notifications/push-device-setting";
1116
1194
  export type { PushDeviceSettingProps, PushDeviceAction } from "./notifications/push-device-setting";
1117
- export { PushDevicesSetting, describeUserAgent } from "./notifications/push-devices-setting";
1195
+ export {
1196
+ PushDevicesSetting,
1197
+ /** @deprecated 0.52 — `PushDevicesSetting`, which names each device with it (API-4); removed in 0.53 */
1198
+ describeUserAgent,
1199
+ } from "./notifications/push-devices-setting";
1118
1200
  export type { PushDevicesSettingProps } from "./notifications/push-devices-setting";
1119
1201
  export { UnsubscribePanel, unsubscribeTokenType } from "./notifications/unsubscribe-panel";
1120
1202
  export type { UnsubscribePanelProps } from "./notifications/unsubscribe-panel";
@@ -1161,7 +1243,15 @@ export { DEFAULT_DEMO_LABELS, useDemoLabels } from "./demo/demo-labels";
1161
1243
  export type { DemoLabels } from "./demo/demo-labels";
1162
1244
  export { isDemoSession } from "./demo/demo-session";
1163
1245
  export type { DemoModel, DemoSessionUser } from "./demo/demo-session";
1164
- export { useDemoCountdown, demoCountdown, DEMO_WARNING_MINUTES, DEMO_MINUTES_ONLY } from "./demo/demo-countdown";
1246
+ export {
1247
+ useDemoCountdown,
1248
+ /** @deprecated 0.52 — `useDemoCountdown`, the same countdown; its `now` option for a test (API-4); removed in 0.53 */
1249
+ demoCountdown,
1250
+ /** @deprecated 0.52 — `useDemoCountdown`, whose `warning` turns on then (API-4); removed in 0.53 */
1251
+ DEMO_WARNING_MINUTES,
1252
+ /** @deprecated 0.52 — `useDemoCountdown`, whose `lastHour` turns on then (API-4); removed in 0.53 */
1253
+ DEMO_MINUTES_ONLY,
1254
+ } from "./demo/demo-countdown";
1165
1255
  export type { DemoCountdown, DemoCountdownOptions, DemoExpiry } from "./demo/demo-countdown";
1166
1256
  export { DemoStart } from "./demo/demo-start";
1167
1257
  export type { DemoStartProps } from "./demo/demo-start";
@@ -2,6 +2,7 @@ import { useEffect } from "react";
2
2
  import type { ReactNode } from "react";
3
3
  import { Navigate, Outlet, useLocation } from "react-router";
4
4
 
5
+ import { matchesPathPattern, routerPathname } from "../lib/path-pattern";
5
6
  import { readStored, removeStored, writeStored } from "../lib/safe-storage";
6
7
  import type { LandingSession } from "./landing-actions";
7
8
  import { LoadingState } from "../components/loading-state";
@@ -61,7 +62,9 @@ export function safeNextPath(raw: string | null | undefined): string | null {
61
62
  /* ── The last visited page (§3.2) ────────────────────────────────────────── */
62
63
 
63
64
  /** A path to leave out: a string is the path and everything under it (`/demo` is
64
- * `/demo` and `/demo/ended`; `/` is only `/`), a RegExp is tested on the pathname. */
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). */
65
68
  export type PathPattern = string | RegExp;
66
69
 
67
70
  /**
@@ -85,16 +88,17 @@ export const DEFAULT_LAST_VISITED_EXCLUDES: readonly PathPattern[] = Object.free
85
88
  "/terms",
86
89
  ]);
87
90
 
88
- function matchesPath(pathname: string, pattern: PathPattern): boolean {
89
- if (typeof pattern !== "string") return new RegExp(pattern.source, pattern.flags.replace("g", "")).test(pathname);
90
- if (pattern === "/") return pathname === "/";
91
- const base = pattern.endsWith("/") ? pattern.slice(0, -1) : pattern;
92
- return pathname === base || pathname.startsWith(`${base}/`);
93
- }
94
-
95
- /** Whether `pathname` is one of the defaults or the app's `exclude`. */
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
+ */
96
98
  function isExcluded(pathname: string, exclude: readonly PathPattern[]): boolean {
97
- return [...DEFAULT_LAST_VISITED_EXCLUDES, ...exclude].some((pattern) => matchesPath(pathname, pattern));
99
+ const path = routerPathname(pathname);
100
+ const named = (pattern: PathPattern) => matchesPathPattern(path, pattern);
101
+ return DEFAULT_LAST_VISITED_EXCLUDES.some(named) || exclude.some(named);
98
102
  }
99
103
 
100
104
  export interface LastVisitedPageOptions {
@@ -0,0 +1,52 @@
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
+ }
@@ -1,5 +1,8 @@
1
1
  import { formatLocaleOf } from "../i18n/languages";
2
2
  import type { KitDateFormatter } from "../i18n/kit-labels";
3
+ import { pad, toLocalIso } from "./dates";
4
+ import { dateFormatter } from "./intl-cache";
5
+ import { isBareIsoDay } from "./iso-day";
3
6
 
4
7
  /**
5
8
  * The date-format preference (0.46, lifted from keksdose's `date-format-store.ts`,
@@ -56,6 +59,15 @@ export interface DateFormatOptions {
56
59
  /** Name the day of the week too, in the interface language ("Mo., 01.08.2026"). A date
57
60
  * in a COLUMN carries it; a date in a SENTENCE does not (keksdose dev#546). */
58
61
  weekday?: boolean;
62
+ /**
63
+ * 0.52: the IANA zone a TIMESTAMP's day and clock are read in ("Europe/Zurich") — pass
64
+ * the `<UiKitProvider timeZone>` (`useKitTimeZone()`), so an app's own column says what
65
+ * the kit's components say for the same instant. Left out: the device's. A bare
66
+ * "YYYY-MM-DD" ignores it: a calendar day is the day it names in every zone. A zone
67
+ * `Intl` refuses reads as the device's. The renderers read it; {@link resolveDateFormat}
68
+ * does not.
69
+ */
70
+ timeZone?: string;
59
71
  }
60
72
 
61
73
  /**
@@ -80,9 +92,6 @@ export function resolveDateFormat(
80
92
  return { locale: preference, options: { year: "numeric", month: "2-digit", day: "2-digit" }, ...weekday };
81
93
  }
82
94
 
83
- /** A bare calendar day: no time, no zone. */
84
- const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
85
-
86
95
  /**
87
96
  * `dateText`, already rendered under the preference, with the day's NAME around it in
88
97
  * `locale` (the language's). Not "weekday alone + comma": German says "So" alone and
@@ -93,7 +102,7 @@ const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
93
102
  */
94
103
  function withWeekday(date: Date, dateText: string, locale: string | undefined, options: Intl.DateTimeFormatOptions) {
95
104
  const isDatePart = (p: Intl.DateTimeFormatPart) => p.type === "day" || p.type === "month" || p.type === "year";
96
- const parts = new Intl.DateTimeFormat(locale, { weekday: "short", ...options }).formatToParts(date);
105
+ const parts = dateFormatter(locale, { weekday: "short", ...options }).formatToParts(date);
97
106
  const first = parts.findIndex(isDatePart);
98
107
  if (first === -1) return dateText;
99
108
  let last = first;
@@ -108,8 +117,9 @@ function withWeekday(date: Date, dateText: string, locale: string | undefined, o
108
117
  * A date under the preference: `""` for no value, the input itself when it does not
109
118
  * parse. A bare "YYYY-MM-DD" is the calendar day it names in every zone (formatted in
110
119
  * UTC, undoing `new Date`'s UTC-midnight parse — west of Greenwich it read a day early);
111
- * a timestamp is an instant and stays in the reader's zone. The weekday, when asked for,
112
- * is rendered in the same zone, so a Sunday is never captioned Saturday.
120
+ * a timestamp is an instant, read in `options.timeZone`, else the reader's zone. The
121
+ * weekday, when asked for, is rendered in the same zone, so a Sunday is never captioned
122
+ * Saturday.
113
123
  */
114
124
  export function formatDateWithPreference(
115
125
  value: string | Date | null | undefined,
@@ -119,17 +129,83 @@ export function formatDateWithPreference(
119
129
  ): string {
120
130
  if (!value) return "";
121
131
  const resolved = resolveDateFormat(preference, language, options);
122
- const dateOnly = typeof value === "string" && DATE_ONLY.test(value);
132
+ const dateOnly = isBareIsoDay(value);
123
133
  const date = typeof value === "string" ? new Date(value) : value;
124
134
  if (Number.isNaN(date.getTime())) return String(value);
125
- const intl: Intl.DateTimeFormatOptions = dateOnly ? { ...resolved.options, timeZone: "UTC" } : resolved.options;
126
- try {
127
- const text = date.toLocaleDateString(resolved.locale, intl);
135
+ const render = (timeZone: string | undefined) => {
136
+ const intl: Intl.DateTimeFormatOptions = timeZone ? { ...resolved.options, timeZone } : resolved.options;
137
+ // Through the shared cache (refactor audit 2026-10-30, DUP-2): a `toLocaleDateString`
138
+ // builds a formatter per call, which is why keksdose kept its own copy of this
139
+ // renderer — 392 ms per click on a 270-row register (dev#632).
140
+ const text = dateFormatter(resolved.locale, intl).format(date);
128
141
  return resolved.weekday ? withWeekday(date, text, resolved.weekday.locale, intl) : text;
129
- } catch {
130
- // A language tag `Intl` refuses: the ISO day rather than nothing (keksdose's fallback).
131
- return date.toISOString().slice(0, 10);
142
+ };
143
+ if (dateOnly) return firstAccepted([() => render("UTC")], () => value);
144
+ // A zone `Intl` refuses: the reader's own day, as `clockTime` reads the reader's own
145
+ // clock — never the UTC day `toISOString` gave, a day off around midnight (0.52 code
146
+ // review, this file).
147
+ return firstAccepted([() => render(options.timeZone), () => render(undefined)], () => toLocalIso(date));
148
+ }
149
+
150
+ /** The first of `renders` that `Intl` accepts — a language tag or a zone it refuses
151
+ * throws — else `last()`: the ISO day or the clock rather than nothing (keksdose's
152
+ * fallback). */
153
+ function firstAccepted(renders: readonly (() => string)[], last: () => string): string {
154
+ for (const render of renders) {
155
+ try {
156
+ return render();
157
+ } catch {
158
+ // Refused: the next.
159
+ }
132
160
  }
161
+ return last();
162
+ }
163
+
164
+ /**
165
+ * The clock time of `date` as the language writes it ("14:05"), two digits each: rule 3,
166
+ * a clock follows the language, never the preference — `sv-SE` is a statement about the
167
+ * order of a date's digits, not about a 12- or 24-hour clock. `language` is read through
168
+ * `formatLocaleOf`, so English is the British 24-hour clock, not "02:05 PM" in a
169
+ * German household's app. In `timeZone` when given, else the reader's.
170
+ *
171
+ * @internal Shared with the kit's own day formatter; not part of the barrel.
172
+ */
173
+ export function clockTime(date: Date, language: string | undefined, timeZone?: string): string {
174
+ const locale = language ? formatLocaleOf(language) : undefined;
175
+ const clock = (zone: string | undefined) =>
176
+ dateFormatter(locale, { hour: "2-digit", minute: "2-digit", ...(zone ? { timeZone: zone } : null) }).format(date);
177
+ // A zone `Intl` refuses: the reader's own clock, as `isoDayIn` reads the reader's own
178
+ // day — the UTC clock `toISOString` gave printed 13:05 for 14:05 in Zurich, an hour or
179
+ // more off with no error (0.52 code review, this file).
180
+ const reader = () => `${pad(date.getHours())}:${pad(date.getMinutes())}`;
181
+ return firstAccepted([() => clock(timeZone), () => clock(undefined)], reader);
182
+ }
183
+
184
+ /**
185
+ * A timestamp under the preference (0.52, keksdose's `formatDateTimeFor`, refactor audit
186
+ * 2026-10-30, DUP-2): the date as {@link formatDateWithPreference} writes it, weekday
187
+ * when asked for, then the clock time in the LANGUAGE ({@link clockTime}): "01.08.2026,
188
+ * 14:05", "Sa., 01.08.2026, 14:05". keksdose's notification inbox and admin scheduler
189
+ * were where an explicit ISO choice did nothing until it wrote this. `""` for no value,
190
+ * the input itself when it does not parse; a bare "YYYY-MM-DD" names no moment, so it
191
+ * prints as the date alone.
192
+ *
193
+ * Day and clock in `options.timeZone` — pass the provider's (`useKitTimeZone()`): without
194
+ * it they were the device's, and an app on Zurich time read from New York printed 09:05
195
+ * in its own column where the kit's inbox printed 14:05 for the same instant (0.52 code
196
+ * review, this file).
197
+ */
198
+ export function formatDateTimeWithPreference(
199
+ value: string | Date | null | undefined,
200
+ preference: DateFormatPreference,
201
+ language: string | undefined,
202
+ options: DateFormatOptions = {},
203
+ ): string {
204
+ if (!value) return "";
205
+ if (isBareIsoDay(value)) return formatDateWithPreference(value, preference, language, options);
206
+ const date = typeof value === "string" ? new Date(value) : value;
207
+ if (Number.isNaN(date.getTime())) return String(value);
208
+ return `${formatDateWithPreference(date, preference, language, options)}, ${clockTime(date, language, options.timeZone)}`;
133
209
  }
134
210
 
135
211
  /** The sample an option is labelled with — 1 August 2026 in its shape, the shape being
@@ -0,0 +1,96 @@
1
+ import { useCallback } from "react";
2
+ import { useKitDateFormatter, useKitLocale, useKitTimeZone } from "../i18n/kit-labels";
3
+ import { toLocalIso } from "./dates";
4
+ import { clockTime } from "./date-format";
5
+ import { EMPTY_FORMATTED_VALUE, formatDate, toDate, type DateInput, type FormatDateStyle } from "./format";
6
+ import { dateFormatter } from "./intl-cache";
7
+ import { isBareIsoDay } from "./iso-day";
8
+
9
+ /**
10
+ * How a kit component prints a day — ONE ladder (refactor audit 2026-10-30, DUP-2):
11
+ *
12
+ * 1. the component's own prop (`formatDate`, `renderDate`), when the app gave one and it
13
+ * answers;
14
+ * 2. else the `<UiKitProvider formatDate>` (keksdose K12: the app's date-format
15
+ * preference), asked for the calendar day with `source: "dateMark"`;
16
+ * 3. else the kit's `formatDate` in the provider's locale AND `timeZone` (0.46).
17
+ *
18
+ * 0.46's rule — "a label that identifies a day follows the preference" — held only where
19
+ * a component wrote that ladder itself: four copies (admin's `useDayText`, AccountStateChip,
20
+ * DateMark, the feedback table), while about twelve components took their own prop or
21
+ * nothing and went straight to `lib/format`. keksdose set the provider's `formatDate` and
22
+ * still passed it into six components by hand; and the 10 that imported the raw
23
+ * `formatDate` ignored the provider's `timeZone`.
24
+ *
25
+ * @internal Not part of the barrel: the components' props are the public way in.
26
+ */
27
+
28
+ /** What a {@link DayFormatter} call may ask for. */
29
+ export interface DayTextOptions {
30
+ /**
31
+ * Name the day of the week — what the provider's formatter is told (its `weekday`).
32
+ * keksdose's rule: a date in a COLUMN carries it, a date in a SENTENCE does not
33
+ * (dev#546). Default `false`. The kit's own rendering follows `style`, not this.
34
+ */
35
+ weekday?: boolean;
36
+ /** Add the clock time, in the language (date-format rule 3): a timestamp. Default false. */
37
+ time?: boolean;
38
+ /** The kit's own rendering (step 3). Default `"medium"`, `"dateTime"` with `time`. */
39
+ style?: FormatDateStyle | Intl.DateTimeFormatOptions;
40
+ /** `false`: skip the provider (step 2) — a component's explicit style wins over it,
41
+ * as `DateMark`'s `dateStyle` does. Default `true`. */
42
+ preference?: boolean;
43
+ /** Printed for no value. Default "—". */
44
+ empty?: string;
45
+ }
46
+
47
+ /** A component's day printer: a value in, its text out. */
48
+ export type DayFormatter<V extends DateInput = DateInput> = (value: V, options?: DayTextOptions) => string;
49
+
50
+ /** The calendar day `date` falls on in `timeZone`, as "YYYY-MM-DD" — so the day the
51
+ * provider is asked for is the day the kit's own rendering would print. */
52
+ function isoDayIn(date: Date, timeZone: string | undefined): string {
53
+ if (!timeZone) return toLocalIso(date);
54
+ try {
55
+ // `en-CA` writes YYYY-MM-DD with Latin digits.
56
+ const parts = dateFormatter("en-CA", { timeZone, year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(
57
+ date,
58
+ );
59
+ const part = (type: Intl.DateTimeFormatPartTypes) => parts.find((p) => p.type === type)?.value ?? "";
60
+ return `${part("year")}-${part("month")}-${part("day")}`;
61
+ } catch {
62
+ return toLocalIso(date);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * The component's day printer, bound to its `prop`, the provider's `formatDate`, locale
68
+ * and `timeZone`. `prop` is called with the value as the component passed it, and wins
69
+ * whenever it answers non-empty. A value that does not parse is printed as it came
70
+ * (a bug upstream is better seen than hidden behind a dash).
71
+ */
72
+ export function useDayFormatter<V extends DateInput = DateInput>(
73
+ prop?: ((value: V) => string) | null,
74
+ localeProp?: string,
75
+ ): DayFormatter<V> {
76
+ const locale = useKitLocale(localeProp);
77
+ const timeZone = useKitTimeZone();
78
+ const fromProvider = useKitDateFormatter();
79
+ return useCallback<DayFormatter<V>>(
80
+ (value, options = {}) => {
81
+ const own = prop?.(value);
82
+ if (own) return own;
83
+ if (value === null || value === undefined || value === "") return options.empty ?? EMPTY_FORMATTED_VALUE;
84
+ const date = toDate(value);
85
+ if (!date) return String(value);
86
+ const bareDay = isBareIsoDay(value);
87
+ if (fromProvider && options.preference !== false) {
88
+ const iso = bareDay ? value : isoDayIn(date, timeZone);
89
+ const day = fromProvider(iso, { unit: "day", source: "dateMark", locale, weekday: options.weekday ?? false });
90
+ if (day) return options.time && !bareDay ? `${day}, ${clockTime(date, locale, timeZone)}` : day;
91
+ }
92
+ return formatDate(value, options.style ?? (options.time ? "dateTime" : "medium"), { locale, timeZone });
93
+ },
94
+ [prop, fromProvider, locale, timeZone],
95
+ );
96
+ }
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from "react";
2
+ import { hasContent } from "./presence";
3
+
4
+ /**
5
+ * The failure ladder, once: the app's words for a failure when it has any, else the
6
+ * kit's `fallback`.
7
+ *
8
+ * "Any" is {@link hasContent}, so an app's `describeError` answering `""` (nothing to say
9
+ * about this one) gets the kit's sentence. Written as `own ?? fallback` in the auth forms,
10
+ * where `""` printed an empty alert, and both ways within one file in the reviewer scope
11
+ * editor; it lived in the notification cards' parts only (refactor audit 2026-10-30,
12
+ * DUP-14).
13
+ *
14
+ * @internal Package-private — not re-exported from the barrel.
15
+ */
16
+ export function describeFailure(own: ReactNode | undefined, fallback: ReactNode): ReactNode {
17
+ return hasContent(own) ? own : fallback;
18
+ }