@eifi1/ui-kit 0.51.6 → 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 (805) hide show
  1. package/README.md +146 -26
  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 +3 -7
  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.d.ts +3 -2
  39. package/dist/auth/complete-name-dialog.js +3 -5
  40. package/dist/auth/complete-name-dialog.js.map +1 -1
  41. package/dist/auth/forgot-password-form-labels.js +1 -1
  42. package/dist/auth/forgot-password-form-labels.js.map +1 -1
  43. package/dist/auth/forgot-password-form.js +7 -2
  44. package/dist/auth/forgot-password-form.js.map +1 -1
  45. package/dist/auth/register-form-labels.js +1 -1
  46. package/dist/auth/register-form-labels.js.map +1 -1
  47. package/dist/auth/reset-password-form-labels.js +1 -1
  48. package/dist/auth/reset-password-form-labels.js.map +1 -1
  49. package/dist/auth/reset-password-form.js +5 -1
  50. package/dist/auth/reset-password-form.js.map +1 -1
  51. package/dist/auth/sign-in-form-labels.js +1 -1
  52. package/dist/auth/sign-in-form-labels.js.map +1 -1
  53. package/dist/auth/status-parts.d.ts +0 -3
  54. package/dist/auth/status-parts.js +0 -4
  55. package/dist/auth/status-parts.js.map +1 -1
  56. package/dist/auth/verify-email-labels.js +1 -1
  57. package/dist/auth/verify-email-labels.js.map +1 -1
  58. package/dist/auth/verify-email.js +7 -2
  59. package/dist/auth/verify-email.js.map +1 -1
  60. package/dist/billing/cancel-request.d.ts +11 -2
  61. package/dist/billing/cancel-request.js +15 -3
  62. package/dist/billing/cancel-request.js.map +1 -1
  63. package/dist/billing/cancel-subscription.d.ts +22 -10
  64. package/dist/billing/cancel-subscription.js +8 -11
  65. package/dist/billing/cancel-subscription.js.map +1 -1
  66. package/dist/billing/dialog-close.d.ts +29 -0
  67. package/dist/billing/dialog-close.js +8 -0
  68. package/dist/billing/dialog-close.js.map +1 -0
  69. package/dist/billing/plan-card.d.ts +14 -4
  70. package/dist/billing/plan-card.js +15 -8
  71. package/dist/billing/plan-card.js.map +1 -1
  72. package/dist/billing/plan-change-labels.d.ts +42 -0
  73. package/dist/billing/plan-change-labels.js +22 -0
  74. package/dist/billing/plan-change-labels.js.map +1 -0
  75. package/dist/billing/plan-switch.d.ts +21 -9
  76. package/dist/billing/plan-switch.js +10 -8
  77. package/dist/billing/plan-switch.js.map +1 -1
  78. package/dist/chart.d.ts +12 -0
  79. package/dist/chart.js +16 -1
  80. package/dist/chart.js.map +1 -1
  81. package/dist/components/account-chips.d.ts +5 -5
  82. package/dist/components/account-chips.js +11 -13
  83. package/dist/components/account-chips.js.map +1 -1
  84. package/dist/components/alert-banner.d.ts +16 -5
  85. package/dist/components/alert-banner.js +46 -1
  86. package/dist/components/alert-banner.js.map +1 -1
  87. package/dist/components/amount-input.d.ts +22 -4
  88. package/dist/components/amount-input.js +3 -3
  89. package/dist/components/amount-input.js.map +1 -1
  90. package/dist/components/autocomplete.js +57 -65
  91. package/dist/components/autocomplete.js.map +1 -1
  92. package/dist/components/bulk-action-bar.d.ts +12 -2
  93. package/dist/components/bulk-action-bar.js +65 -21
  94. package/dist/components/bulk-action-bar.js.map +1 -1
  95. package/dist/components/button-look.d.ts +5 -5
  96. package/dist/components/button-look.js.map +1 -1
  97. package/dist/components/button.d.ts +2 -2
  98. package/dist/components/button.js.map +1 -1
  99. package/dist/components/calculator.d.ts +21 -2
  100. package/dist/components/calculator.js +53 -14
  101. package/dist/components/calculator.js.map +1 -1
  102. package/dist/components/chart-edge.d.ts +16 -0
  103. package/dist/components/chart-edge.js +14 -1
  104. package/dist/components/chart-edge.js.map +1 -1
  105. package/dist/components/chart-figure.d.ts +13 -0
  106. package/dist/components/chart-figure.js +15 -0
  107. package/dist/components/chart-figure.js.map +1 -0
  108. package/dist/components/chart-zoom-core.js +1 -4
  109. package/dist/components/chart-zoom-core.js.map +1 -1
  110. package/dist/components/chart.d.ts +8 -1
  111. package/dist/components/chart.js +19 -10
  112. package/dist/components/chart.js.map +1 -1
  113. package/dist/components/combobox-core.d.ts +119 -7
  114. package/dist/components/combobox-core.js +151 -46
  115. package/dist/components/combobox-core.js.map +1 -1
  116. package/dist/components/combobox.d.ts +1 -1
  117. package/dist/components/combobox.js +142 -131
  118. package/dist/components/combobox.js.map +1 -1
  119. package/dist/components/copy-button.d.ts +6 -5
  120. package/dist/components/copy-button.js +5 -3
  121. package/dist/components/copy-button.js.map +1 -1
  122. package/dist/components/country-select.js +2 -2
  123. package/dist/components/country-select.js.map +1 -1
  124. package/dist/components/data-table-column-settings.d.ts +1 -1
  125. package/dist/components/data-table-column-settings.js +33 -7
  126. package/dist/components/data-table-column-settings.js.map +1 -1
  127. package/dist/components/data-table-filters.d.ts +4 -2
  128. package/dist/components/data-table-filters.js +2 -2
  129. package/dist/components/data-table-filters.js.map +1 -1
  130. package/dist/components/data-table-fit.d.ts +6 -4
  131. package/dist/components/data-table-fit.js +4 -1
  132. package/dist/components/data-table-fit.js.map +1 -1
  133. package/dist/components/data-table-groups.d.ts +1 -1
  134. package/dist/components/data-table-groups.js.map +1 -1
  135. package/dist/components/data-table-head.d.ts +1 -1
  136. package/dist/components/data-table-head.js +15 -12
  137. package/dist/components/data-table-head.js.map +1 -1
  138. package/dist/components/data-table-mobile.d.ts +36 -7
  139. package/dist/components/data-table-mobile.js +63 -31
  140. package/dist/components/data-table-mobile.js.map +1 -1
  141. package/dist/components/data-table-pagination.js +11 -6
  142. package/dist/components/data-table-pagination.js.map +1 -1
  143. package/dist/components/data-table-resize.d.ts +1 -1
  144. package/dist/components/data-table-resize.js.map +1 -1
  145. package/dist/components/data-table-row-actions.d.ts +2 -2
  146. package/dist/components/data-table-row-actions.js.map +1 -1
  147. package/dist/components/data-table-row.d.ts +6 -2
  148. package/dist/components/data-table-row.js +17 -10
  149. package/dist/components/data-table-row.js.map +1 -1
  150. package/dist/components/data-table-selection.d.ts +1 -1
  151. package/dist/components/data-table-selection.js.map +1 -1
  152. package/dist/components/data-table-shared.d.ts +10 -2
  153. package/dist/components/data-table-shared.js +18 -0
  154. package/dist/components/data-table-shared.js.map +1 -1
  155. package/dist/components/data-table-sort.d.ts +21 -2
  156. package/dist/components/data-table-sort.js +24 -0
  157. package/dist/components/data-table-sort.js.map +1 -1
  158. package/dist/components/data-table-virtual.d.ts +1 -1
  159. package/dist/components/data-table-virtual.js +18 -6
  160. package/dist/components/data-table-virtual.js.map +1 -1
  161. package/dist/components/data-table.d.ts +25 -8
  162. package/dist/components/data-table.js +154 -25
  163. package/dist/components/data-table.js.map +1 -1
  164. package/dist/components/date-field.d.ts +24 -2
  165. package/dist/components/date-field.js +33 -8
  166. package/dist/components/date-field.js.map +1 -1
  167. package/dist/components/date-picker.d.ts +15 -2
  168. package/dist/components/date-picker.js +55 -26
  169. package/dist/components/date-picker.js.map +1 -1
  170. package/dist/components/date-range-picker.d.ts +47 -20
  171. package/dist/components/date-range-picker.js +23 -7
  172. package/dist/components/date-range-picker.js.map +1 -1
  173. package/dist/components/dialog-frame.d.ts +2 -1
  174. package/dist/components/dialog-frame.js.map +1 -1
  175. package/dist/components/entity-combobox.js +4 -2
  176. package/dist/components/entity-combobox.js.map +1 -1
  177. package/dist/components/error-boundary.js +37 -30
  178. package/dist/components/error-boundary.js.map +1 -1
  179. package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
  180. package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
  181. package/dist/components/field-base-labels.js.map +1 -0
  182. package/dist/components/field-base.d.ts +4 -3
  183. package/dist/components/field-base.js +3 -3
  184. package/dist/components/field-base.js.map +1 -1
  185. package/dist/components/field-sync-labels.d.ts +1 -0
  186. package/dist/components/field-sync-labels.js.map +1 -1
  187. package/dist/components/field-sync.d.ts +23 -1
  188. package/dist/components/field-sync.js.map +1 -1
  189. package/dist/components/form-actions.js +11 -5
  190. package/dist/components/form-actions.js.map +1 -1
  191. package/dist/components/hover-menu.d.ts +3 -0
  192. package/dist/components/hover-menu.js +5 -3
  193. package/dist/components/hover-menu.js.map +1 -1
  194. package/dist/components/icon-button.js +14 -9
  195. package/dist/components/icon-button.js.map +1 -1
  196. package/dist/components/inline-confirm.d.ts +43 -0
  197. package/dist/components/inline-confirm.js +67 -0
  198. package/dist/components/inline-confirm.js.map +1 -0
  199. package/dist/components/inline-entity-combobox.d.ts +4 -3
  200. package/dist/components/inline-entity-combobox.js +150 -141
  201. package/dist/components/inline-entity-combobox.js.map +1 -1
  202. package/dist/components/input.js +1 -1
  203. package/dist/components/input.js.map +1 -1
  204. package/dist/components/jump-calendar.js +28 -112
  205. package/dist/components/jump-calendar.js.map +1 -1
  206. package/dist/components/legal-page.d.ts +3 -1
  207. package/dist/components/legal-page.js +3 -2
  208. package/dist/components/legal-page.js.map +1 -1
  209. package/dist/components/legal.d.ts +4 -2
  210. package/dist/components/legal.js.map +1 -1
  211. package/dist/components/lightbox.d.ts +2 -2
  212. package/dist/components/lightbox.js +17 -6
  213. package/dist/components/lightbox.js.map +1 -1
  214. package/dist/components/list.d.ts +6 -2
  215. package/dist/components/list.js +4 -3
  216. package/dist/components/list.js.map +1 -1
  217. package/dist/components/measured-grid.d.ts +1 -1
  218. package/dist/components/measured-grid.js +2 -1
  219. package/dist/components/measured-grid.js.map +1 -1
  220. package/dist/components/mini-calendar.js +3 -5
  221. package/dist/components/mini-calendar.js.map +1 -1
  222. package/dist/components/modal.d.ts +24 -0
  223. package/dist/components/modal.js +12 -4
  224. package/dist/components/modal.js.map +1 -1
  225. package/dist/components/money-draft.js +7 -5
  226. package/dist/components/money-draft.js.map +1 -1
  227. package/dist/components/money-field.d.ts +2 -2
  228. package/dist/components/money-field.js.map +1 -1
  229. package/dist/components/month-grid.d.ts +55 -0
  230. package/dist/components/month-grid.js +148 -0
  231. package/dist/components/month-grid.js.map +1 -0
  232. package/dist/components/month-picker.d.ts +36 -4
  233. package/dist/components/month-picker.js +123 -146
  234. package/dist/components/month-picker.js.map +1 -1
  235. package/dist/components/multi-entity-combobox.js +2 -1
  236. package/dist/components/multi-entity-combobox.js.map +1 -1
  237. package/dist/components/multi-select.d.ts +2 -2
  238. package/dist/components/multi-select.js +11 -6
  239. package/dist/components/multi-select.js.map +1 -1
  240. package/dist/components/number-field.d.ts +6 -4
  241. package/dist/components/number-field.js +3 -2
  242. package/dist/components/number-field.js.map +1 -1
  243. package/dist/components/number-input.d.ts +4 -1
  244. package/dist/components/number-input.js +3 -2
  245. package/dist/components/number-input.js.map +1 -1
  246. package/dist/components/numpad-sheet.js.map +1 -1
  247. package/dist/components/picker-sheet.js +2 -1
  248. package/dist/components/picker-sheet.js.map +1 -1
  249. package/dist/components/pie-chart-labels.d.ts +7 -0
  250. package/dist/components/pie-chart-labels.js +1 -0
  251. package/dist/components/pie-chart-labels.js.map +1 -1
  252. package/dist/components/pie-chart.d.ts +5 -3
  253. package/dist/components/pie-chart.js +7 -22
  254. package/dist/components/pie-chart.js.map +1 -1
  255. package/dist/components/popover.d.ts +3 -0
  256. package/dist/components/popover.js +7 -1
  257. package/dist/components/popover.js.map +1 -1
  258. package/dist/components/reauth-dialog.d.ts +4 -5
  259. package/dist/components/reauth-dialog.js +1 -4
  260. package/dist/components/reauth-dialog.js.map +1 -1
  261. package/dist/components/row-actions.js +2 -1
  262. package/dist/components/row-actions.js.map +1 -1
  263. package/dist/components/section-nav.d.ts +7 -0
  264. package/dist/components/section-nav.js.map +1 -1
  265. package/dist/components/series-chart-axes.d.ts +10 -3
  266. package/dist/components/series-chart-axes.js +1 -0
  267. package/dist/components/series-chart-axes.js.map +1 -1
  268. package/dist/components/series-chart-labels.d.ts +7 -4
  269. package/dist/components/series-chart-labels.js.map +1 -1
  270. package/dist/components/series-chart.d.ts +31 -7
  271. package/dist/components/series-chart.js +72 -29
  272. package/dist/components/series-chart.js.map +1 -1
  273. package/dist/components/share-card.js +3 -3
  274. package/dist/components/share-card.js.map +1 -1
  275. package/dist/components/sign-chip-labels.d.ts +1 -0
  276. package/dist/components/sign-chip-labels.js.map +1 -1
  277. package/dist/components/sign-chip.d.ts +10 -1
  278. package/dist/components/sign-chip.js.map +1 -1
  279. package/dist/components/tabs-labels.d.ts +2 -0
  280. package/dist/components/tabs-labels.js +11 -0
  281. package/dist/components/tabs-labels.js.map +1 -0
  282. package/dist/components/tabs.d.ts +1 -1
  283. package/dist/components/tabs.js +13 -11
  284. package/dist/components/tabs.js.map +1 -1
  285. package/dist/components/toggle-legend.d.ts +2 -2
  286. package/dist/components/toggle-legend.js +6 -6
  287. package/dist/components/toggle-legend.js.map +1 -1
  288. package/dist/components/translation-review-editor.d.ts +4 -2
  289. package/dist/components/translation-review-editor.js +2 -3
  290. package/dist/components/translation-review-editor.js.map +1 -1
  291. package/dist/components/translation-review.d.ts +2 -1
  292. package/dist/components/translation-review.js +2 -2
  293. package/dist/components/translation-review.js.map +1 -1
  294. package/dist/components/treemap-labels.d.ts +26 -0
  295. package/dist/components/treemap-labels.js +10 -0
  296. package/dist/components/treemap-labels.js.map +1 -0
  297. package/dist/components/treemap-layout.d.ts +62 -0
  298. package/dist/components/treemap-layout.js +126 -0
  299. package/dist/components/treemap-layout.js.map +1 -0
  300. package/dist/components/treemap.d.ts +140 -17
  301. package/dist/components/treemap.js +324 -97
  302. package/dist/components/treemap.js.map +1 -1
  303. package/dist/components/use-table-state.d.ts +5 -5
  304. package/dist/components/use-table-state.js +4 -1
  305. package/dist/components/use-table-state.js.map +1 -1
  306. package/dist/data-table.d.ts +6 -2
  307. package/dist/data-table.js +7 -2
  308. package/dist/data-table.js.map +1 -1
  309. package/dist/eslint/index.js +1 -1
  310. package/dist/eslint/role-utilities.d.ts +36 -7
  311. package/dist/eslint/role-utilities.js +42 -9
  312. package/dist/eslint/role-utilities.js.map +1 -1
  313. package/dist/feedback/feedback-dialog.d.ts +25 -16
  314. package/dist/feedback/feedback-dialog.js +6 -2
  315. package/dist/feedback/feedback-dialog.js.map +1 -1
  316. package/dist/feedback/feedback-mutation.d.ts +30 -0
  317. package/dist/feedback/feedback-mutation.js +16 -0
  318. package/dist/feedback/feedback-mutation.js.map +1 -0
  319. package/dist/feedback/feedback-page-link.d.ts +53 -0
  320. package/dist/feedback/feedback-page-link.js +37 -0
  321. package/dist/feedback/feedback-page-link.js.map +1 -0
  322. package/dist/feedback/feedback-public-list.d.ts +12 -3
  323. package/dist/feedback/feedback-public-list.js +2 -1
  324. package/dist/feedback/feedback-public-list.js.map +1 -1
  325. package/dist/feedback/feedback-replies.d.ts +3 -1
  326. package/dist/feedback/feedback-replies.js +5 -4
  327. package/dist/feedback/feedback-replies.js.map +1 -1
  328. package/dist/feedback/feedback-row-detail-labels.js +5 -0
  329. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  330. package/dist/feedback/feedback-row-detail.d.ts +64 -28
  331. package/dist/feedback/feedback-row-detail.js +30 -28
  332. package/dist/feedback/feedback-row-detail.js.map +1 -1
  333. package/dist/feedback/feedback-status-undo.d.ts +30 -11
  334. package/dist/feedback/feedback-status-undo.js +10 -15
  335. package/dist/feedback/feedback-status-undo.js.map +1 -1
  336. package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
  337. package/dist/feedback/feedback-submit-dialog.js +1 -1
  338. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  339. package/dist/feedback/feedback-submit.js +9 -3
  340. package/dist/feedback/feedback-submit.js.map +1 -1
  341. package/dist/feedback/feedback-swipe.d.ts +1 -1
  342. package/dist/feedback/feedback-swipe.js.map +1 -1
  343. package/dist/feedback/feedback-table.d.ts +21 -9
  344. package/dist/feedback/feedback-table.js +45 -25
  345. package/dist/feedback/feedback-table.js.map +1 -1
  346. package/dist/feedback/feedback-thread-labels.d.ts +2 -2
  347. package/dist/feedback/feedback-thread-labels.js.map +1 -1
  348. package/dist/feedback/feedback-thread.d.ts +24 -23
  349. package/dist/feedback/feedback-thread.js +2 -1
  350. package/dist/feedback/feedback-thread.js.map +1 -1
  351. package/dist/feedback.d.ts +34 -0
  352. package/dist/feedback.js +42 -0
  353. package/dist/feedback.js.map +1 -1
  354. package/dist/hooks/use-dismiss.js.map +1 -1
  355. package/dist/hooks/use-focus-trap.d.ts +35 -0
  356. package/dist/hooks/use-focus-trap.js +6 -4
  357. package/dist/hooks/use-focus-trap.js.map +1 -1
  358. package/dist/hooks/use-hotkey.d.ts +5 -2
  359. package/dist/hooks/use-hotkey.js +5 -4
  360. package/dist/hooks/use-hotkey.js.map +1 -1
  361. package/dist/hooks/use-long-press.d.ts +7 -4
  362. package/dist/hooks/use-long-press.js +3 -0
  363. package/dist/hooks/use-long-press.js.map +1 -1
  364. package/dist/hooks/use-media-query.js +12 -4
  365. package/dist/hooks/use-media-query.js.map +1 -1
  366. package/dist/hooks/use-mounted.d.ts +22 -0
  367. package/dist/hooks/use-mounted.js +24 -0
  368. package/dist/hooks/use-mounted.js.map +1 -0
  369. package/dist/hooks/use-overlay-history.d.ts +7 -1
  370. package/dist/hooks/use-overlay-history.js +35 -5
  371. package/dist/hooks/use-overlay-history.js.map +1 -1
  372. package/dist/i18n/defaults.js +4 -5
  373. package/dist/i18n/defaults.js.map +1 -1
  374. package/dist/i18n/german.js +7 -1
  375. package/dist/i18n/german.js.map +1 -1
  376. package/dist/i18n/kit-labels.d.ts +9 -2
  377. package/dist/i18n/kit-labels.js.map +1 -1
  378. package/dist/i18n/locales/en.js +20 -41
  379. package/dist/i18n/locales/en.js.map +3 -3
  380. package/dist/i18n/locales/es.js +7 -1
  381. package/dist/i18n/locales/es.js.map +1 -1
  382. package/dist/i18n/locales/fr.js +20 -10
  383. package/dist/i18n/locales/fr.js.map +1 -1
  384. package/dist/i18n/locales/hu.js +9 -1
  385. package/dist/i18n/locales/hu.js.map +1 -1
  386. package/dist/i18n/locales/it.js +7 -1
  387. package/dist/i18n/locales/it.js.map +1 -1
  388. package/dist/i18n/locales/zh.js +8 -1
  389. package/dist/i18n/locales/zh.js.map +1 -1
  390. package/dist/i18n/review.js +5 -0
  391. package/dist/i18n/review.js.map +1 -1
  392. package/dist/index.d.ts +64 -17
  393. package/dist/index.js +77 -12
  394. package/dist/index.js.map +1 -1
  395. package/dist/landing/routing.d.ts +3 -1
  396. package/dist/landing/routing.js +4 -7
  397. package/dist/landing/routing.js.map +1 -1
  398. package/dist/lib/broadcast.d.ts +17 -0
  399. package/dist/lib/broadcast.js +30 -0
  400. package/dist/lib/broadcast.js.map +1 -0
  401. package/dist/lib/calc.d.ts +7 -1
  402. package/dist/lib/calc.js +3 -1
  403. package/dist/lib/calc.js.map +1 -1
  404. package/dist/lib/clipboard-minus.d.ts +2 -2
  405. package/dist/lib/clipboard-minus.js +1 -1
  406. package/dist/lib/clipboard-minus.js.map +1 -1
  407. package/dist/lib/date-format.d.ts +37 -2
  408. package/dist/lib/date-format.js +34 -8
  409. package/dist/lib/date-format.js.map +1 -1
  410. package/dist/lib/day-format.d.ts +46 -0
  411. package/dist/lib/day-format.js +46 -0
  412. package/dist/lib/day-format.js.map +1 -0
  413. package/dist/lib/decimal-marks.d.ts +7 -1
  414. package/dist/lib/decimal-marks.js +5 -2
  415. package/dist/lib/decimal-marks.js.map +1 -1
  416. package/dist/lib/describe-failure.d.ts +14 -0
  417. package/dist/lib/describe-failure.js +9 -0
  418. package/dist/lib/describe-failure.js.map +1 -0
  419. package/dist/lib/direction.d.ts +16 -0
  420. package/dist/lib/direction.js +9 -1
  421. package/dist/lib/direction.js.map +1 -1
  422. package/dist/lib/focus-left.d.ts +63 -0
  423. package/dist/lib/focus-left.js +67 -0
  424. package/dist/lib/focus-left.js.map +1 -0
  425. package/dist/lib/format.d.ts +5 -3
  426. package/dist/lib/format.js +16 -13
  427. package/dist/lib/format.js.map +1 -1
  428. package/dist/lib/http-status.d.ts +24 -0
  429. package/dist/lib/http-status.js +14 -0
  430. package/dist/lib/http-status.js.map +1 -0
  431. package/dist/lib/intl-cache.d.ts +14 -0
  432. package/dist/lib/intl-cache.js +15 -0
  433. package/dist/lib/intl-cache.js.map +1 -0
  434. package/dist/lib/isin.d.ts +10 -0
  435. package/dist/lib/isin.js.map +1 -1
  436. package/dist/lib/iso-day.d.ts +11 -0
  437. package/dist/lib/iso-day.js +8 -0
  438. package/dist/lib/iso-day.js.map +1 -0
  439. package/dist/lib/lazy-with-fallback.d.ts +31 -0
  440. package/dist/lib/lazy-with-fallback.js +40 -0
  441. package/dist/lib/lazy-with-fallback.js.map +1 -0
  442. package/dist/lib/path-pattern.d.ts +34 -0
  443. package/dist/lib/path-pattern.js +24 -0
  444. package/dist/lib/path-pattern.js.map +1 -0
  445. package/dist/lib/reduced-motion.d.ts +2 -1
  446. package/dist/lib/reduced-motion.js.map +1 -1
  447. package/dist/lib/round.d.ts +2 -1
  448. package/dist/lib/round.js +2 -1
  449. package/dist/lib/round.js.map +1 -1
  450. package/dist/lib/safe-storage.d.ts +24 -5
  451. package/dist/lib/safe-storage.js +27 -2
  452. package/dist/lib/safe-storage.js.map +1 -1
  453. package/dist/lib/session-refresh.js +1 -1
  454. package/dist/lib/session-refresh.js.map +1 -1
  455. package/dist/lib/share-format.d.ts +13 -0
  456. package/dist/lib/share-format.js +10 -0
  457. package/dist/lib/share-format.js.map +1 -0
  458. package/dist/lib/text-case.d.ts +17 -0
  459. package/dist/lib/text-case.js +8 -0
  460. package/dist/lib/text-case.js.map +1 -0
  461. package/dist/lib/text-match.d.ts +38 -0
  462. package/dist/lib/text-match.js +24 -2
  463. package/dist/lib/text-match.js.map +1 -1
  464. package/dist/lib/thenable.d.ts +13 -0
  465. package/dist/lib/thenable.js +8 -0
  466. package/dist/lib/thenable.js.map +1 -0
  467. package/dist/lib/translation-review.d.ts +7 -2
  468. package/dist/lib/translation-review.js +4 -4
  469. package/dist/lib/translation-review.js.map +1 -1
  470. package/dist/notifications/device-zone-report.js +1 -1
  471. package/dist/notifications/device-zone-report.js.map +1 -1
  472. package/dist/notifications/notification-bell.d.ts +2 -1
  473. package/dist/notifications/notification-bell.js +3 -3
  474. package/dist/notifications/notification-bell.js.map +1 -1
  475. package/dist/notifications/notification-inbox.d.ts +10 -6
  476. package/dist/notifications/notification-inbox.js +26 -48
  477. package/dist/notifications/notification-inbox.js.map +1 -1
  478. package/dist/notifications/notification-parts.d.ts +3 -2
  479. package/dist/notifications/notification-parts.js +1 -3
  480. package/dist/notifications/notification-parts.js.map +1 -1
  481. package/dist/notifications/notification-types-setting.js +1 -1
  482. package/dist/notifications/notification-types-setting.js.map +1 -1
  483. package/dist/notifications/notifications-labels.d.ts +6 -0
  484. package/dist/notifications/notifications-labels.js +1 -0
  485. package/dist/notifications/notifications-labels.js.map +1 -1
  486. package/dist/notifications/push-device-setting.js +1 -1
  487. package/dist/notifications/push-device-setting.js.map +1 -1
  488. package/dist/notifications/push-devices-setting.d.ts +2 -1
  489. package/dist/notifications/push-devices-setting.js +27 -49
  490. package/dist/notifications/push-devices-setting.js.map +1 -1
  491. package/dist/notifications/quiet-hours-setting.d.ts +10 -3
  492. package/dist/notifications/quiet-hours-setting.js +65 -26
  493. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  494. package/dist/notifications/unsubscribe-panel.js +4 -7
  495. package/dist/notifications/unsubscribe-panel.js.map +1 -1
  496. package/dist/notifications/use-push-device.d.ts +39 -1
  497. package/dist/notifications/use-push-device.js +28 -7
  498. package/dist/notifications/use-push-device.js.map +1 -1
  499. package/dist/offline/query-persistence.d.ts +3 -1
  500. package/dist/offline/query-persistence.js +19 -2
  501. package/dist/offline/query-persistence.js.map +1 -1
  502. package/dist/rhf/fields.d.ts +11 -4
  503. package/dist/rhf/fields.js.map +1 -1
  504. package/dist/search/command-palette.js +1 -1
  505. package/dist/search/command-palette.js.map +1 -1
  506. package/dist/search/global-search.js +19 -9
  507. package/dist/search/global-search.js.map +1 -1
  508. package/dist/search/use-command-key.d.ts +12 -1
  509. package/dist/search/use-command-key.js +3 -12
  510. package/dist/search/use-command-key.js.map +1 -1
  511. package/dist/search.d.ts +7 -0
  512. package/dist/search.js +10 -0
  513. package/dist/search.js.map +1 -1
  514. package/dist/settings/use-settings-focus.js +1 -0
  515. package/dist/settings/use-settings-focus.js.map +1 -1
  516. package/dist/shell/account-menu-language.d.ts +21 -5
  517. package/dist/shell/account-menu-language.js +3 -1
  518. package/dist/shell/account-menu-language.js.map +1 -1
  519. package/dist/shell/account-menu-text-size.d.ts +26 -9
  520. package/dist/shell/account-menu-text-size.js +3 -2
  521. package/dist/shell/account-menu-text-size.js.map +1 -1
  522. package/dist/shell/dev-menu.js +5 -18
  523. package/dist/shell/dev-menu.js.map +1 -1
  524. package/dist/shell/role-switcher.d.ts +7 -0
  525. package/dist/shell/role-switcher.js.map +1 -1
  526. package/dist/shell/top-bar-actions.d.ts +1 -1
  527. package/dist/shell/top-bar-actions.js.map +1 -1
  528. package/dist/shell/top-bar-parts-labels.d.ts +0 -2
  529. package/dist/shell/top-bar-parts-labels.js +0 -1
  530. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  531. package/dist/shell.d.ts +27 -8
  532. package/dist/shell.js +28 -7
  533. package/dist/shell.js.map +1 -1
  534. package/dist/sync/engine.d.ts +30 -4
  535. package/dist/sync/engine.js +172 -52
  536. package/dist/sync/engine.js.map +1 -1
  537. package/dist/sync.d.ts +6 -2
  538. package/dist/sync.js +6 -1
  539. package/dist/sync.js.map +1 -1
  540. package/dist/testing/css-variables.js +3 -8
  541. package/dist/testing/css-variables.js.map +1 -1
  542. package/dist/theme/contrast.d.ts +2 -1
  543. package/dist/theme/contrast.js +3 -8
  544. package/dist/theme/contrast.js.map +1 -1
  545. package/dist/theme/palette-store.js +6 -6
  546. package/dist/theme/palette-store.js.map +1 -1
  547. package/dist/theme/text-size.js +3 -8
  548. package/dist/theme/text-size.js.map +1 -1
  549. package/dist/theme/theme-store.js +3 -6
  550. package/dist/theme/theme-store.js.map +1 -1
  551. package/dist/tour/tour-catalogue.d.ts +7 -4
  552. package/dist/tour/tour-catalogue.js +12 -10
  553. package/dist/tour/tour-catalogue.js.map +1 -1
  554. package/dist/tour/tour-dock.d.ts +0 -2
  555. package/dist/tour/tour-dock.js +0 -2
  556. package/dist/tour/tour-dock.js.map +1 -1
  557. package/dist/tour/tour-gates.d.ts +4 -0
  558. package/dist/tour/tour-gates.js +14 -0
  559. package/dist/tour/tour-gates.js.map +1 -1
  560. package/dist/tour/tour-overlay.d.ts +27 -0
  561. package/dist/tour/tour-overlay.js +741 -0
  562. package/dist/tour/tour-overlay.js.map +1 -0
  563. package/dist/tour/tour.d.ts +16 -4
  564. package/dist/tour/tour.js +62 -778
  565. package/dist/tour/tour.js.map +1 -1
  566. package/dist/tour/use-tour-progress.js +1 -1
  567. package/dist/tour/use-tour-progress.js.map +1 -1
  568. package/dist/tour/use-tour-url-sync.js +2 -2
  569. package/dist/tour/use-tour-url-sync.js.map +1 -1
  570. package/dist/wizard/stepper-nav.d.ts +5 -1
  571. package/dist/wizard/stepper-nav.js.map +1 -1
  572. package/dist/wizard/types.d.ts +6 -2
  573. package/dist/wizard/types.js.map +1 -1
  574. package/dist/wizard/use-wizard.d.ts +3 -1
  575. package/dist/wizard/use-wizard.js.map +1 -1
  576. package/dist/wizard/validation.d.ts +3 -1
  577. package/dist/wizard/validation.js.map +1 -1
  578. package/package.json +12 -8
  579. package/src/account/account-parts.ts +5 -25
  580. package/src/account/data-export-setting-labels.ts +1 -1
  581. package/src/account/delete-account-setting-labels.ts +1 -1
  582. package/src/account/email-change-setting-labels.ts +1 -1
  583. package/src/account/passkeys-setting.tsx +60 -38
  584. package/src/account/sessions-setting.tsx +18 -12
  585. package/src/admin/admin-action-confirm.tsx +5 -10
  586. package/src/admin/admin-parts.ts +11 -25
  587. package/src/admin/mail-test-card-labels.ts +1 -1
  588. package/src/admin/plan-change-labels.ts +5 -23
  589. package/src/admin/plan-change.tsx +7 -44
  590. package/src/admin/reviewer-scope-editor.tsx +3 -3
  591. package/src/auth/auth-errors-labels.ts +23 -0
  592. package/src/auth/auth-errors.ts +11 -38
  593. package/src/auth/complete-name-dialog.tsx +9 -8
  594. package/src/auth/forgot-password-form-labels.ts +1 -1
  595. package/src/auth/forgot-password-form.tsx +11 -6
  596. package/src/auth/register-form-labels.ts +1 -1
  597. package/src/auth/reset-password-form-labels.ts +1 -1
  598. package/src/auth/reset-password-form.tsx +8 -4
  599. package/src/auth/sign-in-form-labels.ts +1 -1
  600. package/src/auth/status-parts.tsx +0 -6
  601. package/src/auth/verify-email-labels.ts +1 -1
  602. package/src/auth/verify-email.tsx +11 -6
  603. package/src/billing/cancel-request.ts +28 -6
  604. package/src/billing/cancel-subscription.tsx +29 -22
  605. package/src/billing/dialog-close.ts +34 -0
  606. package/src/billing/plan-card.tsx +36 -11
  607. package/src/billing/plan-change-labels.ts +66 -0
  608. package/src/billing/plan-switch.tsx +31 -20
  609. package/src/chart.ts +21 -3
  610. package/src/components/account-chips.tsx +20 -23
  611. package/src/components/alert-banner.tsx +82 -5
  612. package/src/components/amount-input.tsx +32 -14
  613. package/src/components/autocomplete.tsx +64 -70
  614. package/src/components/bulk-action-bar.tsx +70 -2
  615. package/src/components/button-look.ts +5 -5
  616. package/src/components/button.tsx +2 -2
  617. package/src/components/calculator.tsx +98 -17
  618. package/src/components/chart-edge.ts +34 -1
  619. package/src/components/chart-figure.tsx +35 -0
  620. package/src/components/chart-zoom-core.tsx +6 -5
  621. package/src/components/chart.tsx +26 -5
  622. package/src/components/combobox-core.tsx +303 -69
  623. package/src/components/combobox.tsx +184 -155
  624. package/src/components/copy-button.tsx +34 -23
  625. package/src/components/country-select.tsx +16 -11
  626. package/src/components/data-table-column-settings.tsx +52 -10
  627. package/src/components/data-table-filters.ts +6 -4
  628. package/src/components/data-table-fit.ts +19 -5
  629. package/src/components/data-table-groups.tsx +1 -1
  630. package/src/components/data-table-head.tsx +32 -22
  631. package/src/components/data-table-mobile.tsx +110 -27
  632. package/src/components/data-table-pagination.tsx +21 -6
  633. package/src/components/data-table-resize.ts +1 -1
  634. package/src/components/data-table-row-actions.tsx +3 -3
  635. package/src/components/data-table-row.tsx +25 -14
  636. package/src/components/data-table-selection.ts +1 -1
  637. package/src/components/data-table-shared.tsx +33 -1
  638. package/src/components/data-table-sort.ts +57 -2
  639. package/src/components/data-table-virtual.ts +32 -8
  640. package/src/components/data-table.tsx +267 -41
  641. package/src/components/date-field.tsx +65 -8
  642. package/src/components/date-picker.tsx +125 -48
  643. package/src/components/date-range-picker.tsx +82 -31
  644. package/src/components/dialog-frame.tsx +2 -1
  645. package/src/components/entity-combobox.tsx +4 -1
  646. package/src/components/error-boundary.tsx +53 -39
  647. package/src/components/field-base-labels.ts +20 -0
  648. package/src/components/field-base.tsx +13 -7
  649. package/src/components/field-sync-labels.ts +1 -0
  650. package/src/components/field-sync.tsx +23 -1
  651. package/src/components/form-actions.tsx +20 -5
  652. package/src/components/hover-menu.tsx +18 -8
  653. package/src/components/icon-button.tsx +14 -9
  654. package/src/components/inline-confirm.tsx +116 -0
  655. package/src/components/inline-entity-combobox.tsx +198 -152
  656. package/src/components/input.tsx +1 -1
  657. package/src/components/jump-calendar.tsx +30 -146
  658. package/src/components/legal-page.tsx +10 -7
  659. package/src/components/legal.tsx +4 -2
  660. package/src/components/lightbox.tsx +21 -8
  661. package/src/components/list.tsx +14 -5
  662. package/src/components/measured-grid.tsx +8 -4
  663. package/src/components/mini-calendar.tsx +6 -5
  664. package/src/components/modal.tsx +45 -4
  665. package/src/components/money-draft.ts +16 -5
  666. package/src/components/money-field.tsx +2 -2
  667. package/src/components/month-grid.tsx +229 -0
  668. package/src/components/month-picker.tsx +192 -200
  669. package/src/components/multi-entity-combobox.tsx +1 -0
  670. package/src/components/multi-select.tsx +21 -9
  671. package/src/components/number-field.tsx +14 -7
  672. package/src/components/number-input.tsx +9 -3
  673. package/src/components/numpad-sheet.tsx +4 -3
  674. package/src/components/picker-sheet.tsx +12 -9
  675. package/src/components/pie-chart-labels.ts +8 -0
  676. package/src/components/pie-chart.tsx +22 -28
  677. package/src/components/popover.tsx +18 -1
  678. package/src/components/reauth-dialog.tsx +6 -10
  679. package/src/components/row-actions.tsx +2 -1
  680. package/src/components/section-nav.tsx +7 -0
  681. package/src/components/series-chart-axes.ts +11 -3
  682. package/src/components/series-chart-labels.ts +7 -4
  683. package/src/components/series-chart.tsx +178 -69
  684. package/src/components/share-card.tsx +6 -6
  685. package/src/components/sign-chip-labels.ts +1 -0
  686. package/src/components/sign-chip.tsx +10 -1
  687. package/src/components/tabs-labels.ts +13 -0
  688. package/src/components/tabs.tsx +35 -19
  689. package/src/components/toggle-legend.tsx +16 -11
  690. package/src/components/translation-review-editor.tsx +6 -5
  691. package/src/components/translation-review.tsx +4 -3
  692. package/src/components/treemap-labels.ts +39 -0
  693. package/src/components/treemap-layout.ts +210 -0
  694. package/src/components/treemap.tsx +722 -133
  695. package/src/components/use-table-state.ts +12 -9
  696. package/src/data-table.ts +9 -2
  697. package/src/eslint/role-utilities.ts +97 -19
  698. package/src/feedback/feedback-dialog.tsx +30 -19
  699. package/src/feedback/feedback-mutation.ts +41 -0
  700. package/src/feedback/feedback-page-link.ts +90 -0
  701. package/src/feedback/feedback-public-list.tsx +17 -5
  702. package/src/feedback/feedback-replies.tsx +13 -6
  703. package/src/feedback/feedback-row-detail-labels.ts +5 -0
  704. package/src/feedback/feedback-row-detail.tsx +103 -67
  705. package/src/feedback/feedback-status-undo.ts +41 -27
  706. package/src/feedback/feedback-submit-dialog.tsx +2 -2
  707. package/src/feedback/feedback-submit.tsx +21 -7
  708. package/src/feedback/feedback-swipe.tsx +1 -1
  709. package/src/feedback/feedback-table.tsx +86 -38
  710. package/src/feedback/feedback-thread-labels.ts +2 -2
  711. package/src/feedback/feedback-thread.tsx +27 -25
  712. package/src/feedback.ts +42 -0
  713. package/src/hooks/use-dismiss.ts +3 -2
  714. package/src/hooks/use-focus-trap.ts +8 -24
  715. package/src/hooks/use-hotkey.ts +24 -7
  716. package/src/hooks/use-long-press.ts +16 -2
  717. package/src/hooks/use-media-query.ts +20 -4
  718. package/src/hooks/use-mounted.ts +39 -0
  719. package/src/hooks/use-overlay-history.ts +70 -5
  720. package/src/i18n/defaults.ts +4 -5
  721. package/src/i18n/german.ts +8 -2
  722. package/src/i18n/kit-labels.tsx +9 -2
  723. package/src/i18n/locales/es.ts +8 -2
  724. package/src/i18n/locales/fr.ts +21 -13
  725. package/src/i18n/locales/hu.ts +10 -2
  726. package/src/i18n/locales/it.ts +8 -2
  727. package/src/i18n/locales/zh.ts +9 -2
  728. package/src/i18n/review.ts +5 -0
  729. package/src/index.ts +103 -13
  730. package/src/landing/routing.tsx +14 -10
  731. package/src/lib/broadcast.ts +52 -0
  732. package/src/lib/calc.ts +13 -2
  733. package/src/lib/clipboard-minus.ts +14 -4
  734. package/src/lib/date-format.ts +89 -13
  735. package/src/lib/day-format.ts +96 -0
  736. package/src/lib/decimal-marks.ts +12 -3
  737. package/src/lib/describe-failure.ts +18 -0
  738. package/src/lib/direction.ts +39 -0
  739. package/src/lib/focus-left.ts +156 -0
  740. package/src/lib/format.ts +34 -19
  741. package/src/lib/http-status.ts +38 -0
  742. package/src/lib/intl-cache.ts +25 -0
  743. package/src/lib/isin.ts +10 -0
  744. package/src/lib/iso-day.ts +13 -0
  745. package/src/lib/lazy-with-fallback.ts +82 -0
  746. package/src/lib/path-pattern.ts +55 -0
  747. package/src/lib/reduced-motion.ts +2 -1
  748. package/src/lib/round.ts +7 -2
  749. package/src/lib/safe-storage.ts +48 -6
  750. package/src/lib/session-refresh.ts +1 -1
  751. package/src/lib/share-format.ts +18 -0
  752. package/src/lib/text-case.ts +19 -0
  753. package/src/lib/text-match.ts +69 -2
  754. package/src/lib/thenable.ts +19 -0
  755. package/src/lib/translation-review.ts +13 -5
  756. package/src/notifications/device-zone-report.ts +1 -1
  757. package/src/notifications/notification-bell.tsx +7 -4
  758. package/src/notifications/notification-inbox.tsx +40 -58
  759. package/src/notifications/notification-parts.tsx +3 -4
  760. package/src/notifications/notification-types-setting.tsx +1 -1
  761. package/src/notifications/notifications-labels.ts +7 -0
  762. package/src/notifications/push-device-setting.tsx +1 -1
  763. package/src/notifications/push-devices-setting.tsx +30 -55
  764. package/src/notifications/quiet-hours-setting.tsx +93 -31
  765. package/src/notifications/unsubscribe-panel.tsx +4 -7
  766. package/src/notifications/use-push-device.ts +76 -10
  767. package/src/offline/query-persistence.ts +35 -3
  768. package/src/rhf/fields.tsx +11 -4
  769. package/src/search/command-palette.tsx +2 -4
  770. package/src/search/global-search.tsx +36 -15
  771. package/src/search/use-command-key.ts +13 -12
  772. package/src/search.ts +9 -0
  773. package/src/settings/use-settings-focus.ts +3 -0
  774. package/src/shell/account-menu-language.tsx +27 -5
  775. package/src/shell/account-menu-text-size.tsx +32 -10
  776. package/src/shell/dev-menu.tsx +7 -21
  777. package/src/shell/role-switcher.tsx +7 -0
  778. package/src/shell/top-bar-actions.tsx +1 -1
  779. package/src/shell/top-bar-parts-labels.ts +0 -3
  780. package/src/shell.ts +40 -9
  781. package/src/sync/engine.ts +339 -61
  782. package/src/sync.ts +8 -1
  783. package/src/testing/css-variables.ts +8 -9
  784. package/src/theme/contrast.ts +8 -9
  785. package/src/theme/palette-store.ts +9 -9
  786. package/src/theme/text-size.ts +6 -8
  787. package/src/theme/theme-store.ts +7 -9
  788. package/src/tour/tour-catalogue.tsx +26 -15
  789. package/src/tour/tour-dock.ts +0 -2
  790. package/src/tour/tour-gates.ts +23 -0
  791. package/src/tour/tour-overlay.tsx +1170 -0
  792. package/src/tour/tour.tsx +116 -1193
  793. package/src/tour/use-tour-progress.ts +1 -1
  794. package/src/tour/use-tour-url-sync.ts +7 -3
  795. package/src/wizard/stepper-nav.tsx +3 -1
  796. package/src/wizard/types.ts +11 -2
  797. package/src/wizard/use-wizard.ts +2 -1
  798. package/src/wizard/validation.ts +8 -2
  799. package/tokens.css +2 -1
  800. package/dist/components/ui-labels.js.map +0 -1
  801. package/dist/shell/dev-switchers.d.ts +0 -6
  802. package/dist/shell/dev-switchers.js +0 -12
  803. package/dist/shell/dev-switchers.js.map +0 -1
  804. package/src/components/ui-labels.ts +0 -24
  805. package/src/shell/dev-switchers.tsx +0 -18
@@ -11,7 +11,7 @@ import { DialogFrame } from "../components/dialog-frame";
11
11
  import { COMMIT_EXCEPT_BILLING } from "../components/write-lock";
12
12
  import { CARD_DESCRIPTION_CLASS } from "../settings/settings-card-classes";
13
13
  import { SettingsCardTitle } from "../settings/settings-heading";
14
- import { useMounted } from "../account/account-parts";
14
+ import { useMounted } from "../hooks/use-mounted";
15
15
  import { describeFailure, FailureLine, useNotificationsLabels } from "./notification-parts";
16
16
  import type { NotificationsLabels } from "./notifications-labels";
17
17
  import { PushDeviceError } from "./use-push-device";
@@ -1,21 +1,23 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import type { ComponentPropsWithRef, KeyboardEvent, ReactNode } from "react";
1
+ import { useRef, useState } from "react";
2
+ import type { ComponentPropsWithRef, ReactNode } from "react";
3
3
  import { MonitorSmartphone } from "lucide-react";
4
4
 
5
- import { useKitLabels, useKitLocale, type LabelOverride } from "../i18n/kit-labels";
5
+ import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
6
6
  import { DEFAULT_COMMON_LABELS } from "../i18n/shared-labels";
7
7
  import { cn } from "../lib/cn";
8
- import { formatDate } from "../lib/format";
8
+ import { useDayFormatter } from "../lib/day-format";
9
+ import { toDate } from "../lib/format";
9
10
  import { Button } from "../components/button";
10
11
  import { Card } from "../components/card";
11
12
  import { Chip } from "../components/chip";
12
13
  import { Disclosure } from "../components/disclosure";
14
+ import { InlineConfirm } from "../components/inline-confirm";
13
15
  import { Skeleton } from "../components/skeleton";
14
16
  import { Switch } from "../components/switch";
15
17
  import { COMMIT_EXCEPT_BILLING } from "../components/write-lock";
16
18
  import { CARD_DESCRIPTION_CLASS } from "../settings/settings-card-classes";
17
19
  import { SettingsCardTitle } from "../settings/settings-heading";
18
- import { settle, useMounted } from "../account/account-parts";
20
+ import { settle, useMounted } from "../hooks/use-mounted";
19
21
  import { describeFailure, FailureLine, useNotificationsLabels, useWriteOverlay } from "./notification-parts";
20
22
  import type { NotificationsLabels } from "./notifications-labels";
21
23
  import type { NotificationTypeEntry, NotificationTypesValue, PushDeviceItem } from "./notification-types";
@@ -68,7 +70,8 @@ export interface PushDevicesSettingProps<Id extends string | number = string> ex
68
70
  /** `DELETE /notifications/devices/{id}`. Asked first; refresh `devices` once it
69
71
  * resolves. */
70
72
  onRemove: (id: Id) => Promise<unknown> | void;
71
- /** The dates' text. Default: the provider's locale, medium date. */
73
+ /** The dates' text. Default: the provider's `formatDate` (the app's date preference),
74
+ * else a medium date in the provider's locale and `timeZone`. */
72
75
  formatDate?: (date: Date) => string;
73
76
  /** Overrides the provider's locale for the default format. */
74
77
  locale?: string;
@@ -140,16 +143,17 @@ export function PushDevicesSetting<Id extends string | number = string>({
140
143
  const labels = useNotificationsLabels(labelsProp);
141
144
  const mutedOverlay = useWriteOverlay<string[]>(devices);
142
145
  const common = useKitLabels("common", DEFAULT_COMMON_LABELS);
143
- const locale = useKitLocale(localeProp);
146
+ // The prop, else the provider's `formatDate` (the app's date preference), else the kit's
147
+ // in the provider's locale and `timeZone` (refactor audit 2026-10-30, DUP-2).
148
+ const day = useDayFormatter(formatDateProp, localeProp);
144
149
  const [asking, setAsking] = useState<Id | null>(null);
145
150
  const [busyId, setBusyId] = useState<Id | null>(null);
146
151
  const [failure, setFailure] = useState<ReactNode>(null);
147
152
  const mounted = useMounted();
148
153
 
149
154
  const dateText = (iso: string): string => {
150
- const date = new Date(iso);
151
- if (Number.isNaN(date.getTime())) return iso;
152
- return formatDateProp ? formatDateProp(date) : formatDate(date, "medium", { locale });
155
+ const date = toDate(iso);
156
+ return date ? day(date) : iso;
153
157
  };
154
158
 
155
159
  const remove = (device: PushDeviceItem<Id>) => {
@@ -305,53 +309,27 @@ function DeviceRow<Id extends string | number>({
305
309
  /** "Types on this device", under the row (0.46). */
306
310
  types: ReactNode;
307
311
  }) {
308
- const cancelRef = useRef<HTMLButtonElement>(null);
312
+ // Back to Remove when the confirm leaves, so focus does not fall to <body>.
309
313
  const removeRef = useRef<HTMLButtonElement>(null);
310
- // Which way the confirm closed: back to Remove, so focus does not fall to <body>.
311
- const [returning, setReturning] = useState(false);
312
- useEffect(() => {
313
- if (asking) cancelRef.current?.focus();
314
- else if (returning) removeRef.current?.focus();
315
- }, [asking, returning]);
316
-
317
- const leave = () => {
318
- setReturning(true);
319
- onCancel();
320
- };
321
- const escapeLeaves = (event: KeyboardEvent<HTMLButtonElement>) => {
322
- if (event.key === "Escape") {
323
- event.preventDefault();
324
- event.stopPropagation();
325
- leave();
326
- }
327
- };
328
314
 
329
315
  const row = { "data-push-device-id": String(device.id), "data-current": current || undefined };
330
316
 
331
317
  if (asking) {
332
318
  return (
333
- <li {...row} className="space-y-2 py-2">
334
- <p role="alert" className="text-sm">
335
- {labels.removePrompt}
336
- </p>
337
- <div className="flex flex-wrap gap-2">
338
- <Button
339
- type="button"
340
- size="sm"
341
- variant="danger"
342
- commit={COMMIT_EXCEPT_BILLING}
343
- pending={busy}
344
- aria-label={labels.removeItem(name)}
345
- onClick={onConfirm}
346
- onKeyDown={escapeLeaves}
347
- >
348
- {labels.remove}
349
- </Button>
350
- <Button ref={cancelRef} type="button" size="sm" variant="ghost" onClick={leave} onKeyDown={escapeLeaves}>
351
- {cancelLabel}
352
- </Button>
353
- </div>
354
- </li>
319
+ <InlineConfirm
320
+ as="li"
321
+ {...row}
322
+ className="py-2"
323
+ prompt={labels.removePrompt}
324
+ confirmLabel={labels.remove}
325
+ confirmName={labels.removeItem(name)}
326
+ cancelLabel={cancelLabel}
327
+ onConfirm={onConfirm}
328
+ onLeave={onCancel}
329
+ busy={busy}
330
+ commit={COMMIT_EXCEPT_BILLING}
331
+ returnFocusRef={removeRef}
332
+ />
355
333
  );
356
334
  }
357
335
 
@@ -385,10 +363,7 @@ function DeviceRow<Id extends string | number>({
385
363
  commit={COMMIT_EXCEPT_BILLING}
386
364
  disabled={blocked}
387
365
  aria-label={labels.removeItem(name)}
388
- onClick={() => {
389
- setReturning(false);
390
- onAsk();
391
- }}
366
+ onClick={onAsk}
392
367
  >
393
368
  {labels.remove}
394
369
  </Button>
@@ -1,5 +1,5 @@
1
- import { useId, useState } from "react";
2
- import type { ComponentPropsWithRef, ReactNode } from "react";
1
+ import { useEffect, useId, useRef, useState } from "react";
2
+ import type { ComponentPropsWithRef, KeyboardEvent, ReactNode } from "react";
3
3
 
4
4
  import type { LabelOverride } from "../i18n/kit-labels";
5
5
  import { cn } from "../lib/cn";
@@ -8,7 +8,7 @@ import { TimeInput } from "../components/time-input";
8
8
  import { COMMIT_EXCEPT_BILLING } from "../components/write-lock";
9
9
  import { CARD_DESCRIPTION_CLASS } from "../settings/settings-card-classes";
10
10
  import { SettingsCardTitle } from "../settings/settings-heading";
11
- import { settle, useMounted } from "../account/account-parts";
11
+ import { settle, useMounted } from "../hooks/use-mounted";
12
12
  import { describeFailure, FailureLine, useNotificationsLabels, useWriteOverlay } from "./notification-parts";
13
13
  import type { NotificationRegionLabels, NotificationsLabels } from "./notifications-labels";
14
14
  import type { NotificationSettingsPatch } from "./notification-types";
@@ -49,7 +49,9 @@ export interface QuietHoursSettingProps extends Omit<ComponentPropsWithRef<"div"
49
49
  held?: boolean;
50
50
  /**
51
51
  * Save one change — `PATCH /notifications/settings`: a time, or `null` when cleared.
52
- * Never a zone. The field shows the new value while the call runs and goes back if it
52
+ * Never a zone. Called when a time is ENTERED — the field left, or Enter, or the card
53
+ * unmounted with a time still typed — never per keystroke, and one call per field at a
54
+ * time (0.52). The field shows the new value while the call runs and goes back if it
53
55
  * rejects.
54
56
  */
55
57
  onChange: (patch: NotificationSettingsPatch) => Promise<unknown> | void;
@@ -77,8 +79,13 @@ type QuietField = "quiet_hours_start" | "quiet_hours_end";
77
79
  * only** — the zone of the device last used, else `Europe/Zurich`. The card names it
78
80
  * read-only and never sends one; there is no picker and no "Use it".
79
81
  *
80
- * - **Two times**, each saved as it is entered; a cleared time sends `null`. While only
81
- * one is set the card says so: the window fails open until both are.
82
+ * - **Two times**, each saved when it is entered — on leaving the field or on Enter, or
83
+ * when the card goes while it is still typed — and a cleared time sends `null`. While
84
+ * only one is set the card says so: the window fails open until both are.
85
+ * - **One request per field at a time** (0.52): a time entered while that field's save
86
+ * runs waits for it, and only the latest waiting one is sent. Each input event used to
87
+ * PATCH — typing "30" over 22:00's minutes sent 22:03 and 22:30, and whichever answer
88
+ * landed last stayed on the server (refactor audit 2026-10-30, FLW-4).
82
89
  * - **The zone** shows while a time is set: `zone`, else `fallbackZone`.
83
90
  *
84
91
  * Under a write lock the fields are `commit` controls exempt from billing.
@@ -103,32 +110,83 @@ export function QuietHoursSetting({
103
110
  const mounted = useMounted();
104
111
  const id = useId();
105
112
 
106
- const shown = (field: QuietField, server: string | null) =>
107
- overlay.has(field) ? (overlay.get(field) ?? null) : server;
108
- const startShown = shown("quiet_hours_start", start);
109
- const endShown = shown("quiet_hours_end", end);
113
+ // What is typed and not yet entered, per field: the field shows it, nothing is sent.
114
+ const [drafts, setDrafts] = useState<Partial<Record<QuietField, string>>>({});
115
+ // Per field: whether a save runs, and the latest time entered while it did (own key =
116
+ // one is waiting). Refs: a save's answer reads them after renders it did not see.
117
+ const running = useRef<Partial<Record<QuietField, boolean>>>({});
118
+ const waiting = useRef<Partial<Record<QuietField, string | null>>>({});
119
+
120
+ const server = (field: QuietField) => (field === "quiet_hours_start" ? start : end);
121
+ const saved = (field: QuietField) => (overlay.has(field) ? (overlay.get(field) ?? null) : server(field));
122
+ const shown = (field: QuietField) => drafts[field] ?? saved(field) ?? "";
123
+ const startShown = shown("quiet_hours_start");
124
+ const endShown = shown("quiet_hours_end");
110
125
  const accountZone = zone ?? fallbackZone;
111
126
 
112
- const save = (patch: NotificationSettingsPatch) => {
113
- const fields = Object.keys(patch) as QuietField[];
114
- setFailure(null);
115
- for (const field of fields) overlay.set(field, patch[field] ?? null);
116
- settle(() => onChange(patch)).then(
117
- () => {
118
- if (mounted.current) for (const field of fields) overlay.settle(field, true);
119
- },
120
- (error: unknown) => {
121
- if (!mounted.current) return;
122
- for (const field of fields) overlay.settle(field, false);
123
- setFailure(describeFailure(describeError?.(error), labels.failed));
124
- },
127
+ const send = (field: QuietField, value: string | null) => {
128
+ running.current[field] = true;
129
+ if (mounted.current) setFailure(null);
130
+ settle(() => onChange({ [field]: value })).then(
131
+ () => done(field, true),
132
+ (error: unknown) => done(field, false, error),
125
133
  );
126
134
  };
127
135
 
128
- const saveTime = (field: "quiet_hours_start" | "quiet_hours_end", value: string) => {
129
- const next = value || null;
130
- if (next === shown(field, field === "quiet_hours_start" ? start : end)) return;
131
- save({ [field]: next });
136
+ /** A save answered: the waiting time goes next — even after an unmount, it is what the
137
+ * person entered last — and supersedes this answer, a failure included. */
138
+ const done = (field: QuietField, ok: boolean, error?: unknown) => {
139
+ running.current[field] = false;
140
+ if (Object.prototype.hasOwnProperty.call(waiting.current, field)) {
141
+ const next = waiting.current[field] ?? null;
142
+ delete waiting.current[field];
143
+ send(field, next);
144
+ return;
145
+ }
146
+ if (!mounted.current) return;
147
+ overlay.settle(field, ok);
148
+ if (!ok) setFailure(describeFailure(describeError?.(error), labels.failed));
149
+ };
150
+
151
+ /** `draft` entered: the time it names, or `undefined` when that is what the field
152
+ * already holds and nothing is to be sent. Queued behind the field's running save. */
153
+ const save = (field: QuietField, draft: string): string | null | undefined => {
154
+ const next = draft || null;
155
+ if (next === saved(field)) return undefined;
156
+ if (running.current[field]) waiting.current[field] = next;
157
+ else send(field, next);
158
+ return next;
159
+ };
160
+
161
+ /** The typed time, entered: saved unless it is what the field already holds. */
162
+ const enter = (field: QuietField) => {
163
+ const draft = drafts[field];
164
+ if (draft === undefined) return;
165
+ setDrafts((current) => {
166
+ const rest = { ...current };
167
+ delete rest[field];
168
+ return rest;
169
+ });
170
+ const next = save(field, draft);
171
+ if (next !== undefined) overlay.set(field, next);
172
+ };
173
+
174
+ // Leaving the card is leaving the field. A focused input removed with its card fires no
175
+ // blur — Escape on the settings sheet, a shortcut that navigates — and the time it showed
176
+ // as typed was dropped (0.52 code review, quiet-hours-setting.tsx; save-on-blur is FLW-4's
177
+ // decision). So whatever is still typed is entered as the card goes. A ref to this
178
+ // render's drafts and saved values, assigned in an effect, never during render.
179
+ const leave = useRef<() => void>(() => {});
180
+ useEffect(() => {
181
+ leave.current = () => {
182
+ for (const [field, draft] of Object.entries(drafts) as [QuietField, string][]) save(field, draft);
183
+ };
184
+ });
185
+ useEffect(() => () => leave.current(), []);
186
+
187
+ const type = (field: QuietField, value: string) => setDrafts((current) => ({ ...current, [field]: value }));
188
+ const enterOnEnter = (field: QuietField, event: KeyboardEvent<HTMLInputElement>) => {
189
+ if (event.key === "Enter") enter(field);
132
190
  };
133
191
 
134
192
  const anySet = Boolean(startShown || endShown);
@@ -144,19 +202,23 @@ export function QuietHoursSetting({
144
202
  <TimeInput
145
203
  id={`${id}-start`}
146
204
  label={labels.quietFrom}
147
- value={startShown ?? ""}
205
+ value={startShown}
206
+ onValueChange={(value) => type("quiet_hours_start", value)}
207
+ onBlur={() => enter("quiet_hours_start")}
208
+ onKeyDown={(event) => enterOnEnter("quiet_hours_start", event)}
148
209
  disabled={disabled}
149
210
  commit={COMMIT_EXCEPT_BILLING}
150
- onValueChange={(value) => saveTime("quiet_hours_start", value)}
151
211
  className="w-36"
152
212
  />
153
213
  <TimeInput
154
214
  id={`${id}-end`}
155
215
  label={labels.quietUntil}
156
- value={endShown ?? ""}
216
+ value={endShown}
217
+ onValueChange={(value) => type("quiet_hours_end", value)}
218
+ onBlur={() => enter("quiet_hours_end")}
219
+ onKeyDown={(event) => enterOnEnter("quiet_hours_end", event)}
157
220
  disabled={disabled}
158
221
  commit={COMMIT_EXCEPT_BILLING}
159
- onValueChange={(value) => saveTime("quiet_hours_end", value)}
160
222
  className="w-36"
161
223
  />
162
224
  </div>
@@ -4,12 +4,13 @@ import { CheckCircle2, Link2Off } from "lucide-react";
4
4
 
5
5
  import type { LabelOverride } from "../i18n/kit-labels";
6
6
  import { cn } from "../lib/cn";
7
- import { errorBodyWithCode, httpStatusOf } from "../auth/auth-errors";
7
+ import { errorBodyWithCode } from "../auth/auth-errors";
8
+ import { httpStatusOf } from "../lib/http-status";
8
9
  import { INTRO_CLASS, OUTCOME_CLASS, STATUS_HEADING_CLASS, useFocusWhen } from "../auth/status-parts";
9
10
  import type { AuthHeadingLevel } from "../auth/status-parts";
10
11
  import { Button } from "../components/button";
11
12
  import { EmptyState } from "../components/empty-state";
12
- import { useMounted } from "../account/account-parts";
13
+ import { useMounted } from "../hooks/use-mounted";
13
14
  import { FailureLine, useNotificationsLabels } from "./notification-parts";
14
15
  import type { NotificationsLabels } from "./notifications-labels";
15
16
 
@@ -154,11 +155,7 @@ export function UnsubscribePanel({
154
155
  tone="success"
155
156
  icon={<CheckCircle2 />}
156
157
  title={shown === "stopped-these" ? labels.stoppedThese : labels.stoppedAll(appName)}
157
- hint={
158
- <>
159
- {labels.accountMail} {labels.turnBackOn}
160
- </>
161
- }
158
+ hint={labels.stoppedHint(labels.accountMail, labels.turnBackOn)}
162
159
  action={settingsLink}
163
160
  className={OUTCOME_CLASS}
164
161
  />
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useEffect, useRef, useState } from "react";
2
2
 
3
3
  import { useMediaQuery } from "../hooks/use-media-query";
4
- import { httpStatusOf } from "../auth/auth-errors";
4
+ import { httpStatusOf } from "../lib/http-status";
5
5
  import { PUSH_SUBSCRIPTION_CHANGED, keyBytes, pushSubscriptionInput as inputOf } from "./push-worker";
6
6
  import type { PushSubscriptionInput } from "./push-worker";
7
7
 
@@ -85,7 +85,8 @@ export interface PushDevice {
85
85
  * the permission was not granted or push is off on the server; rejects with a
86
86
  * {@link PushDeviceError} or the app's request's error. */
87
87
  enable: () => Promise<boolean>;
88
- /** Tell the server first, then the browser, so a dropped device stops at once. */
88
+ /** Tell the server first, then the browser, so a dropped device stops at once. At a
89
+ * sign-out, with no card mounted: {@link releaseThisDevicePush}. */
89
90
  disable: () => Promise<void>;
90
91
  sendTest: () => Promise<{ sent: number }>;
91
92
  }
@@ -152,6 +153,78 @@ async function activeRegistration(): Promise<ServiceWorkerRegistration> {
152
153
 
153
154
  const defaultEndpointTaken = (error: unknown) => httpStatusOf(error) === 409;
154
155
 
156
+ /**
157
+ * Drop this browser's subscription when the person turns push off: the server first, so a
158
+ * dropped device stops receiving even if the browser's unsubscribe fails, then the
159
+ * browser, cut at 15 s. Whether there was one. A refused server keeps the browser's
160
+ * subscription: the card says the turn-off failed, still reads on, and the person tries
161
+ * again. {@link usePushDevice}'s `disable`; a sign-out has its own
162
+ * ({@link releaseThisDevicePush}).
163
+ */
164
+ async function releaseSubscription(unregister: (endpoint: string) => Promise<unknown>): Promise<boolean> {
165
+ const registration = await activeRegistration();
166
+ const subscription = await registration.pushManager.getSubscription();
167
+ if (!subscription) return false;
168
+ await unregister(subscription.endpoint);
169
+ await within(subscription.unsubscribe(), PUSH_TIMEOUT_MS, "push_timeout");
170
+ return true;
171
+ }
172
+
173
+ /**
174
+ * Release this browser's push at an EXPLICIT sign-out (0.52, docs/notifications-
175
+ * harmonization.md §10.6; refactor audit 2026-10-30, FLW-2) — without the settings card
176
+ * mounted, which `usePushDevice().disable` needs.
177
+ *
178
+ * A sign-out left the subscription registered to the account, so the device went on
179
+ * showing that account's notifications, title and body (keksdose: invoices, bookings,
180
+ * shares), to whoever used it next — while the same sign-out wiped the mirror, the outbox
181
+ * and the query cache "for the next person on this device".
182
+ *
183
+ * Call it with the app's `unregister` (`POST /notifications/devices/unregister
184
+ * {endpoint}`) BEFORE the session is cleared, while the token is still valid:
185
+ *
186
+ * async function logOut() {
187
+ * await releaseThisDevicePush(api.unregisterDevice).catch(() => undefined);
188
+ * clear();
189
+ * }
190
+ *
191
+ * The server first, then the browser — and the browser EVEN WHEN THE SERVER REFUSED (0.52
192
+ * code review, this file): `disable`'s order left a sign-out on a flaky network, or one
193
+ * that met a 5xx, with the device still subscribed. Unsubscribed, the push service answers
194
+ * the server's next send with 410 and the server prunes the row. The browser's unsubscribe
195
+ * is cut at 15 s (`PushDeviceError("push_timeout")`). Then it tells every mounted
196
+ * {@link usePushDevice} ({@link PUSH_SUBSCRIPTION_CHANGED}).
197
+ *
198
+ * Resolves whether this browser held a subscription; `false` at once where push is
199
+ * unsupported or was never set up — no service worker registration, or none ever active
200
+ * (0.52 code review: most devices, which used to reject with `no_service_worker`, after
201
+ * 10 s for a worker stuck installing). It asks the registration, not `ready`: a
202
+ * subscription belongs to the registration, and a sign-out waits for no worker. Rejects
203
+ * as the app's request did — once the browser has let go — or with `push_timeout`. Best
204
+ * effort at a sign-out: catch it, a sign-out must not stop on push.
205
+ *
206
+ * Only an explicit sign-out (Marcel's decision 2 of the 2026-10-30 audit): a session that
207
+ * merely expired keeps its device, and whoever signs back in turns push on again.
208
+ */
209
+ export async function releaseThisDevicePush(unregister: (endpoint: string) => Promise<unknown>): Promise<boolean> {
210
+ if (!pushSupported()) return false;
211
+ try {
212
+ const registration = await navigator.serviceWorker.getRegistration();
213
+ // A worker never active holds no subscription: `subscribe` needs an active one.
214
+ if (!registration?.active) return false;
215
+ const subscription = await registration.pushManager.getSubscription();
216
+ if (!subscription) return false;
217
+ try {
218
+ await unregister(subscription.endpoint);
219
+ } finally {
220
+ await within(subscription.unsubscribe(), PUSH_TIMEOUT_MS, "push_timeout");
221
+ }
222
+ return true;
223
+ } finally {
224
+ notifyPushSubscriptionChanged();
225
+ }
226
+ }
227
+
155
228
  /**
156
229
  * This browser's push for the signed-in account. Hand it one function per endpoint
157
230
  * (§3.8); {@link PushDeviceSetting} draws it, and an app's own card may use it too.
@@ -344,14 +417,7 @@ export function usePushDevice(options: UsePushDeviceOptions): PushDevice {
344
417
  if (!supported) return;
345
418
  setBusy(true);
346
419
  try {
347
- const registration = await activeRegistration();
348
- const subscription = await registration.pushManager.getSubscription();
349
- if (subscription) {
350
- // The server first: a dropped device stops receiving even if the browser's
351
- // unsubscribe below fails.
352
- await latest.current.unregister(subscription.endpoint);
353
- await within(subscription.unsubscribe(), PUSH_TIMEOUT_MS, "push_timeout");
354
- }
420
+ await releaseSubscription((endpoint) => latest.current.unregister(endpoint));
355
421
  if (mounted.current) {
356
422
  setSubscribed(false);
357
423
  setForeignSubscription(false);
@@ -2,6 +2,7 @@ import { createAsyncStoragePersister } from "@tanstack/query-async-storage-persi
2
2
  import type { QueryClient } from "@tanstack/react-query";
3
3
  import type { PersistedClient, PersistQueryClientOptions } from "@tanstack/react-query-persist-client";
4
4
  import { del, get, keys, set } from "idb-keyval";
5
+ import { listenOn, postOnce } from "../lib/broadcast";
5
6
 
6
7
  /**
7
8
  * The persisted TanStack Query cache, keksdose's policy as a kit helper
@@ -101,7 +102,9 @@ export interface QueryPersistence {
101
102
  /** Everything `<PersistQueryClientProvider persistOptions>` needs. */
102
103
  persistOptions: Omit<PersistQueryClientOptions, "queryClient">;
103
104
  /** Sign-out: stops writing under this key, empties the in-memory cache and deletes this
104
- * key's persisted copy. Best-effort; never throws. */
105
+ * key's persisted copy. In every tab (0.52): the persistences of this key in the other tabs
106
+ * stop writing too, and delete the key once more after any save of theirs under way.
107
+ * Best-effort; never throws. */
105
108
  clear: (queryClient: QueryClient) => Promise<void>;
106
109
  /** The company switch (or any change of key without a sign-out): stops writing under this
107
110
  * key — a save already scheduled is dropped too — and empties the in-memory cache, so
@@ -223,6 +226,31 @@ export function createQueryPersistence({
223
226
  // throttled save of the emptied cache) is dropped. A restore re-arms it.
224
227
  let retired = false;
225
228
 
229
+ // 0.52 (refactor audit 2026-10-30, FLW-1): `retired` lived in this tab alone, so a sign-out
230
+ // in one tab deleted the key and another tab's persister wrote its in-memory cache straight
231
+ // back under it. While armed, a persistence listens on a channel named after its key; a
232
+ // `clear` there retires it, and it deletes the key once more — IndexedDB runs a save of its
233
+ // own already under way first. A `leave` posts nothing: another tab may still be on that
234
+ // company. Without BroadcastChannel, as before 0.52.
235
+ const across = `eifi1-query-cache:${key}`;
236
+ let unlisten: (() => void) | null = null;
237
+
238
+ const retire = () => {
239
+ retired = true;
240
+ unlisten?.();
241
+ unlisten = null;
242
+ };
243
+
244
+ const listen = () => {
245
+ unlisten ??= listenOn(across, (data) => {
246
+ if (data !== "clear") return;
247
+ retire();
248
+ Promise.resolve()
249
+ .then(() => storage.removeItem(key))
250
+ .catch(() => undefined);
251
+ });
252
+ };
253
+
226
254
  const keyAllowed = (queryKey: readonly unknown[]) =>
227
255
  !denied.has(String(queryKey[0])) && (shouldPersistKey ? shouldPersistKey(queryKey) : true);
228
256
 
@@ -313,6 +341,7 @@ export function createQueryPersistence({
313
341
  // Only the provider's restore reads: mounting this persistence again re-arms it.
314
342
  getItem: async (k) => {
315
343
  retired = false;
344
+ listen();
316
345
  return (await storage.getItem(k)) ?? null;
317
346
  },
318
347
  setItem: async (k, v) => {
@@ -329,7 +358,7 @@ export function createQueryPersistence({
329
358
  });
330
359
 
331
360
  const leave = async (queryClient: QueryClient) => {
332
- retired = true;
361
+ retire();
333
362
  try {
334
363
  queryClient.clear();
335
364
  } catch {
@@ -338,7 +367,10 @@ export function createQueryPersistence({
338
367
  };
339
368
 
340
369
  const clear = async (queryClient: QueryClient) => {
341
- retired = true;
370
+ // Retired first, so this tab's own channel is closed and does not hear its `clear`.
371
+ retire();
372
+ // Before this tab's delete: the other tabs stop writing as early as they can.
373
+ postOnce(across, "clear");
342
374
  try {
343
375
  queryClient.clear();
344
376
  await persister.removeClient();
@@ -791,7 +791,11 @@ function DateControl({
791
791
  );
792
792
  }
793
793
 
794
- /** The kit's {@link DatePicker}, holding an ISO `"YYYY-MM-DD"` string. */
794
+ /**
795
+ * The kit's {@link DatePicker}, holding an ISO `"YYYY-MM-DD"` string. `commit` and
796
+ * `disabledReason` are the picker's own (0.52, refactor audit 2026-10-30, API-3): a date
797
+ * that saves itself stays focusable under a lock and says why.
798
+ */
795
799
  export function RhfDateField<
796
800
  TFieldValues extends FieldValues = FieldValues,
797
801
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
@@ -893,9 +897,11 @@ export type RhfDateRangePickerProps<
893
897
  * pick, which would mark (and, with `mode: "onTouched"`, validate) an end the user
894
898
  * is still choosing.
895
899
  *
896
- * In `commit="immediate"` mode (the picker's default) the first calendar click is
897
- * reported on its own, so the form holds `(from, emptyValue)` until the second; with
898
- * `commit="apply"` nothing reaches the form until Apply.
900
+ * Without `apply` (the picker's default) the first calendar click is reported on its
901
+ * own, so the form holds `(from, emptyValue)` until the second; with `apply` nothing
902
+ * reaches the form until Apply. `apply` was `commit="apply"` until 0.52 (deprecated, gone
903
+ * in 0.53): `commit` is now the write lock's, as on every other binding — with
904
+ * `disabledReason`, the picker's own (refactor audit 2026-10-30, API-3).
899
905
  *
900
906
  * The common props (`label`, `hint`, `required`, `disabled`, `excludeWhenDisabled`,
901
907
  * `control`, `className`) apply to the pair; `rules` are per field.
@@ -1460,6 +1466,7 @@ function MonthControl({
1460
1466
  * lookup until 0.34, API-3), so focus-on-error lands there; the form's error paints the
1461
1467
  * trigger and is the shell's message; the hint is the shell's description; neither is
1462
1468
  * handed to the picker, so its box never changes. Picking marks the field touched.
1469
+ * `commit` and `disabledReason` are the picker's own (0.52, API-3).
1463
1470
  *
1464
1471
  * ```tsx
1465
1472
  * <RhfMonthPicker name="fiscalYear" label="Fiscal year" mode="year" valueAsNumber
@@ -10,6 +10,8 @@ import { useFocusTrap } from "../hooks/use-focus-trap";
10
10
  import { useBodyScrollLock } from "../hooks/use-body-scroll-lock";
11
11
  import { takeEscape, useDismissLayer } from "../hooks/use-dismiss";
12
12
  import { isImeEnter } from "../lib/ime";
13
+ // A provider's answer is a promise: the only case with anything to wait for.
14
+ import { isThenable } from "../lib/thenable";
13
15
  import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
14
16
  import { DEFAULT_COMMAND_PALETTE_LABELS } from "./command-palette-labels";
15
17
 
@@ -106,10 +108,6 @@ export { DEFAULT_COMMAND_PALETTE_LABELS };
106
108
  */
107
109
  export type CommandPaletteDensity = "compact" | "comfortable";
108
110
 
109
- /** A provider's answer is a promise — the only case with anything to wait for. */
110
- const isThenable = (value: unknown): value is PromiseLike<unknown> =>
111
- typeof (value as PromiseLike<unknown> | null)?.then === "function";
112
-
113
111
  /** The defaults minus `dialog`, so a resolved `dialog` means someone SUPPLIED one —
114
112
  * see the dialog's `aria-label` for why that distinction matters. */
115
113
  const { dialog: DEFAULT_DIALOG_NAME, ...DEFAULTS_WITHOUT_DIALOG } = DEFAULT_COMMAND_PALETTE_LABELS;