@eifi1/ui-kit 0.51.7 → 0.53.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 (775) hide show
  1. package/README.md +178 -67
  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 +10 -7
  60. package/dist/billing/cancel-subscription.js +6 -6
  61. package/dist/billing/cancel-subscription.js.map +1 -1
  62. package/dist/billing/plan-card.d.ts +5 -3
  63. package/dist/billing/plan-card.js +7 -8
  64. package/dist/billing/plan-card.js.map +1 -1
  65. package/dist/billing/plan-change-labels.d.ts +42 -0
  66. package/dist/billing/plan-change-labels.js +22 -0
  67. package/dist/billing/plan-change-labels.js.map +1 -0
  68. package/dist/billing/plan-switch.d.ts +9 -6
  69. package/dist/billing/plan-switch.js +7 -5
  70. package/dist/billing/plan-switch.js.map +1 -1
  71. package/dist/chart.d.ts +4 -3
  72. package/dist/chart.js +72 -4
  73. package/dist/chart.js.map +1 -1
  74. package/dist/components/account-chips.d.ts +5 -5
  75. package/dist/components/account-chips.js +11 -13
  76. package/dist/components/account-chips.js.map +1 -1
  77. package/dist/components/alert-banner.d.ts +16 -5
  78. package/dist/components/alert-banner.js +46 -1
  79. package/dist/components/alert-banner.js.map +1 -1
  80. package/dist/components/amount-input.d.ts +13 -0
  81. package/dist/components/amount-input.js +1 -0
  82. package/dist/components/amount-input.js.map +1 -1
  83. package/dist/components/autocomplete.js +57 -65
  84. package/dist/components/autocomplete.js.map +1 -1
  85. package/dist/components/bulk-action-bar.d.ts +12 -2
  86. package/dist/components/bulk-action-bar.js +65 -21
  87. package/dist/components/bulk-action-bar.js.map +1 -1
  88. package/dist/components/button-look.d.ts +5 -5
  89. package/dist/components/button-look.js.map +1 -1
  90. package/dist/components/button.d.ts +2 -2
  91. package/dist/components/button.js.map +1 -1
  92. package/dist/components/chart-edge.d.ts +16 -0
  93. package/dist/components/chart-edge.js +14 -1
  94. package/dist/components/chart-edge.js.map +1 -1
  95. package/dist/components/chart-figure.d.ts +13 -0
  96. package/dist/components/chart-figure.js +15 -0
  97. package/dist/components/chart-figure.js.map +1 -0
  98. package/dist/components/chart-zoom-core.js +1 -4
  99. package/dist/components/chart-zoom-core.js.map +1 -1
  100. package/dist/components/chart.d.ts +8 -1
  101. package/dist/components/chart.js +19 -10
  102. package/dist/components/chart.js.map +1 -1
  103. package/dist/components/combobox-core.d.ts +111 -2
  104. package/dist/components/combobox-core.js +148 -42
  105. package/dist/components/combobox-core.js.map +1 -1
  106. package/dist/components/combobox.d.ts +1 -1
  107. package/dist/components/combobox.js +141 -130
  108. package/dist/components/combobox.js.map +1 -1
  109. package/dist/components/copy-button.d.ts +6 -5
  110. package/dist/components/copy-button.js +5 -3
  111. package/dist/components/copy-button.js.map +1 -1
  112. package/dist/components/country-select.js +2 -2
  113. package/dist/components/country-select.js.map +1 -1
  114. package/dist/components/data-table-column-settings.d.ts +1 -1
  115. package/dist/components/data-table-column-settings.js +33 -7
  116. package/dist/components/data-table-column-settings.js.map +1 -1
  117. package/dist/components/data-table-filters.d.ts +4 -2
  118. package/dist/components/data-table-filters.js +2 -2
  119. package/dist/components/data-table-filters.js.map +1 -1
  120. package/dist/components/data-table-fit.d.ts +6 -4
  121. package/dist/components/data-table-fit.js +4 -1
  122. package/dist/components/data-table-fit.js.map +1 -1
  123. package/dist/components/data-table-groups.d.ts +1 -1
  124. package/dist/components/data-table-groups.js.map +1 -1
  125. package/dist/components/data-table-head.d.ts +1 -1
  126. package/dist/components/data-table-head.js +15 -12
  127. package/dist/components/data-table-head.js.map +1 -1
  128. package/dist/components/data-table-mobile.d.ts +12 -7
  129. package/dist/components/data-table-mobile.js +43 -30
  130. package/dist/components/data-table-mobile.js.map +1 -1
  131. package/dist/components/data-table-pagination.js +11 -6
  132. package/dist/components/data-table-pagination.js.map +1 -1
  133. package/dist/components/data-table-resize.d.ts +1 -1
  134. package/dist/components/data-table-resize.js.map +1 -1
  135. package/dist/components/data-table-row-actions.d.ts +2 -2
  136. package/dist/components/data-table-row-actions.js.map +1 -1
  137. package/dist/components/data-table-row.d.ts +6 -2
  138. package/dist/components/data-table-row.js +17 -10
  139. package/dist/components/data-table-row.js.map +1 -1
  140. package/dist/components/data-table-selection.d.ts +1 -1
  141. package/dist/components/data-table-selection.js.map +1 -1
  142. package/dist/components/data-table-shared.d.ts +10 -2
  143. package/dist/components/data-table-shared.js +18 -0
  144. package/dist/components/data-table-shared.js.map +1 -1
  145. package/dist/components/data-table-sort.d.ts +21 -2
  146. package/dist/components/data-table-sort.js +24 -0
  147. package/dist/components/data-table-sort.js.map +1 -1
  148. package/dist/components/data-table-virtual.d.ts +1 -1
  149. package/dist/components/data-table-virtual.js +18 -6
  150. package/dist/components/data-table-virtual.js.map +1 -1
  151. package/dist/components/data-table.d.ts +13 -4
  152. package/dist/components/data-table.js +139 -36
  153. package/dist/components/data-table.js.map +1 -1
  154. package/dist/components/date-field.d.ts +25 -3
  155. package/dist/components/date-field.js +33 -8
  156. package/dist/components/date-field.js.map +1 -1
  157. package/dist/components/date-picker.d.ts +16 -3
  158. package/dist/components/date-picker.js +55 -26
  159. package/dist/components/date-picker.js.map +1 -1
  160. package/dist/components/date-range-picker.d.ts +38 -24
  161. package/dist/components/date-range-picker.js +23 -7
  162. package/dist/components/date-range-picker.js.map +1 -1
  163. package/dist/components/error-boundary.js +37 -30
  164. package/dist/components/error-boundary.js.map +1 -1
  165. package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
  166. package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
  167. package/dist/components/field-base-labels.js.map +1 -0
  168. package/dist/components/field-base.d.ts +4 -3
  169. package/dist/components/field-base.js +3 -3
  170. package/dist/components/field-base.js.map +1 -1
  171. package/dist/components/form-actions.js +11 -5
  172. package/dist/components/form-actions.js.map +1 -1
  173. package/dist/components/hover-menu.d.ts +3 -0
  174. package/dist/components/hover-menu.js +5 -3
  175. package/dist/components/hover-menu.js.map +1 -1
  176. package/dist/components/icon-button.js +14 -9
  177. package/dist/components/icon-button.js.map +1 -1
  178. package/dist/components/inline-confirm.d.ts +43 -0
  179. package/dist/components/inline-confirm.js +67 -0
  180. package/dist/components/inline-confirm.js.map +1 -0
  181. package/dist/components/inline-entity-combobox.d.ts +4 -3
  182. package/dist/components/inline-entity-combobox.js +148 -140
  183. package/dist/components/inline-entity-combobox.js.map +1 -1
  184. package/dist/components/input.js +1 -1
  185. package/dist/components/input.js.map +1 -1
  186. package/dist/components/jump-calendar.js +28 -112
  187. package/dist/components/jump-calendar.js.map +1 -1
  188. package/dist/components/legal-page.d.ts +3 -1
  189. package/dist/components/legal-page.js +3 -2
  190. package/dist/components/legal-page.js.map +1 -1
  191. package/dist/components/legal.d.ts +4 -2
  192. package/dist/components/legal.js.map +1 -1
  193. package/dist/components/lightbox.d.ts +2 -2
  194. package/dist/components/lightbox.js +17 -6
  195. package/dist/components/lightbox.js.map +1 -1
  196. package/dist/components/list.d.ts +6 -2
  197. package/dist/components/list.js +3 -2
  198. package/dist/components/list.js.map +1 -1
  199. package/dist/components/measured-grid.d.ts +1 -1
  200. package/dist/components/measured-grid.js +2 -1
  201. package/dist/components/measured-grid.js.map +1 -1
  202. package/dist/components/mini-calendar.js +3 -5
  203. package/dist/components/mini-calendar.js.map +1 -1
  204. package/dist/components/modal.js +3 -1
  205. package/dist/components/modal.js.map +1 -1
  206. package/dist/components/month-grid.d.ts +55 -0
  207. package/dist/components/month-grid.js +148 -0
  208. package/dist/components/month-grid.js.map +1 -0
  209. package/dist/components/month-picker.d.ts +36 -4
  210. package/dist/components/month-picker.js +123 -146
  211. package/dist/components/month-picker.js.map +1 -1
  212. package/dist/components/multi-select.d.ts +2 -2
  213. package/dist/components/multi-select.js +11 -6
  214. package/dist/components/multi-select.js.map +1 -1
  215. package/dist/components/nav-pills.d.ts +1 -1
  216. package/dist/components/nav-pills.js.map +1 -1
  217. package/dist/components/picker-sheet.js +2 -1
  218. package/dist/components/picker-sheet.js.map +1 -1
  219. package/dist/components/pie-chart-labels.d.ts +7 -0
  220. package/dist/components/pie-chart-labels.js +1 -0
  221. package/dist/components/pie-chart-labels.js.map +1 -1
  222. package/dist/components/pie-chart.d.ts +5 -3
  223. package/dist/components/pie-chart.js +7 -22
  224. package/dist/components/pie-chart.js.map +1 -1
  225. package/dist/components/popover.d.ts +3 -0
  226. package/dist/components/popover.js +7 -1
  227. package/dist/components/popover.js.map +1 -1
  228. package/dist/components/row-actions.js +2 -1
  229. package/dist/components/row-actions.js.map +1 -1
  230. package/dist/components/series-chart-axes.d.ts +4 -4
  231. package/dist/components/series-chart-axes.js.map +1 -1
  232. package/dist/components/series-chart-labels.d.ts +7 -4
  233. package/dist/components/series-chart-labels.js.map +1 -1
  234. package/dist/components/series-chart.d.ts +92 -23
  235. package/dist/components/series-chart.js +74 -30
  236. package/dist/components/series-chart.js.map +1 -1
  237. package/dist/components/share-card.js +3 -3
  238. package/dist/components/share-card.js.map +1 -1
  239. package/dist/components/tabs-labels.d.ts +2 -0
  240. package/dist/components/tabs-labels.js +11 -0
  241. package/dist/components/tabs-labels.js.map +1 -0
  242. package/dist/components/tabs.d.ts +1 -1
  243. package/dist/components/tabs.js +1 -1
  244. package/dist/components/tabs.js.map +1 -1
  245. package/dist/components/toggle-legend.d.ts +2 -2
  246. package/dist/components/toggle-legend.js +6 -6
  247. package/dist/components/toggle-legend.js.map +1 -1
  248. package/dist/components/translation-review-editor.d.ts +4 -2
  249. package/dist/components/translation-review-editor.js +2 -3
  250. package/dist/components/translation-review-editor.js.map +1 -1
  251. package/dist/components/translation-review.d.ts +2 -1
  252. package/dist/components/translation-review.js +2 -2
  253. package/dist/components/translation-review.js.map +1 -1
  254. package/dist/components/treemap-labels.d.ts +31 -0
  255. package/dist/components/treemap-labels.js +10 -0
  256. package/dist/components/treemap-labels.js.map +1 -0
  257. package/dist/components/treemap-layout.d.ts +62 -0
  258. package/dist/components/treemap-layout.js +126 -0
  259. package/dist/components/treemap-layout.js.map +1 -0
  260. package/dist/components/treemap.d.ts +167 -19
  261. package/dist/components/treemap.js +340 -100
  262. package/dist/components/treemap.js.map +1 -1
  263. package/dist/components/use-table-state.d.ts +5 -5
  264. package/dist/components/use-table-state.js +4 -1
  265. package/dist/components/use-table-state.js.map +1 -1
  266. package/dist/data-table.d.ts +1 -2
  267. package/dist/data-table.js +1 -4
  268. package/dist/data-table.js.map +1 -1
  269. package/dist/demo/demo-countdown.d.ts +0 -5
  270. package/dist/demo/demo-countdown.js +0 -4
  271. package/dist/demo/demo-countdown.js.map +1 -1
  272. package/dist/eslint/index.js +1 -1
  273. package/dist/eslint/role-utilities.d.ts +36 -7
  274. package/dist/eslint/role-utilities.js +42 -9
  275. package/dist/eslint/role-utilities.js.map +1 -1
  276. package/dist/feedback/feedback-dialog.d.ts +25 -16
  277. package/dist/feedback/feedback-dialog.js +6 -2
  278. package/dist/feedback/feedback-dialog.js.map +1 -1
  279. package/dist/feedback/feedback-mutation.d.ts +18 -0
  280. package/dist/feedback/feedback-mutation.js +8 -0
  281. package/dist/feedback/feedback-mutation.js.map +1 -0
  282. package/dist/feedback/feedback-page-link.d.ts +53 -0
  283. package/dist/feedback/feedback-page-link.js +37 -0
  284. package/dist/feedback/feedback-page-link.js.map +1 -0
  285. package/dist/feedback/feedback-public-list.d.ts +8 -4
  286. package/dist/feedback/feedback-public-list.js +2 -2
  287. package/dist/feedback/feedback-public-list.js.map +1 -1
  288. package/dist/feedback/feedback-replies.d.ts +3 -1
  289. package/dist/feedback/feedback-replies.js +5 -4
  290. package/dist/feedback/feedback-replies.js.map +1 -1
  291. package/dist/feedback/feedback-row-detail-labels.js +0 -3
  292. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  293. package/dist/feedback/feedback-row-detail.d.ts +33 -44
  294. package/dist/feedback/feedback-row-detail.js +28 -34
  295. package/dist/feedback/feedback-row-detail.js.map +1 -1
  296. package/dist/feedback/feedback-status-undo.d.ts +17 -14
  297. package/dist/feedback/feedback-status-undo.js +10 -15
  298. package/dist/feedback/feedback-status-undo.js.map +1 -1
  299. package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
  300. package/dist/feedback/feedback-submit-dialog.js +1 -1
  301. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  302. package/dist/feedback/feedback-submit.js +9 -3
  303. package/dist/feedback/feedback-submit.js.map +1 -1
  304. package/dist/feedback/feedback-swipe.d.ts +1 -1
  305. package/dist/feedback/feedback-swipe.js.map +1 -1
  306. package/dist/feedback/feedback-table.d.ts +21 -9
  307. package/dist/feedback/feedback-table.js +45 -25
  308. package/dist/feedback/feedback-table.js.map +1 -1
  309. package/dist/feedback/feedback-thread-labels.d.ts +2 -2
  310. package/dist/feedback/feedback-thread-labels.js.map +1 -1
  311. package/dist/feedback/feedback-thread.d.ts +15 -23
  312. package/dist/feedback/feedback-thread.js +2 -1
  313. package/dist/feedback/feedback-thread.js.map +1 -1
  314. package/dist/feedback.d.ts +6 -6
  315. package/dist/feedback.js +90 -6
  316. package/dist/feedback.js.map +1 -1
  317. package/dist/hooks/use-focus-trap.d.ts +35 -0
  318. package/dist/hooks/use-focus-trap.js +6 -4
  319. package/dist/hooks/use-focus-trap.js.map +1 -1
  320. package/dist/hooks/use-hotkey.d.ts +5 -2
  321. package/dist/hooks/use-hotkey.js +5 -4
  322. package/dist/hooks/use-hotkey.js.map +1 -1
  323. package/dist/hooks/use-long-press.d.ts +7 -4
  324. package/dist/hooks/use-long-press.js +3 -0
  325. package/dist/hooks/use-long-press.js.map +1 -1
  326. package/dist/hooks/use-media-query.js +12 -4
  327. package/dist/hooks/use-media-query.js.map +1 -1
  328. package/dist/hooks/use-mounted.d.ts +22 -0
  329. package/dist/hooks/use-mounted.js +24 -0
  330. package/dist/hooks/use-mounted.js.map +1 -0
  331. package/dist/hooks/use-overlay-history.js +19 -3
  332. package/dist/hooks/use-overlay-history.js.map +1 -1
  333. package/dist/i18n/defaults.js +4 -9
  334. package/dist/i18n/defaults.js.map +1 -1
  335. package/dist/i18n/german.js +7 -18
  336. package/dist/i18n/german.js.map +1 -1
  337. package/dist/i18n/kit-labels.d.ts +9 -11
  338. package/dist/i18n/kit-labels.js.map +1 -1
  339. package/dist/i18n/locales/en.js +15 -64
  340. package/dist/i18n/locales/en.js.map +3 -3
  341. package/dist/i18n/locales/es.js +7 -18
  342. package/dist/i18n/locales/es.js.map +1 -1
  343. package/dist/i18n/locales/fr.js +20 -27
  344. package/dist/i18n/locales/fr.js.map +1 -1
  345. package/dist/i18n/locales/hu.js +9 -18
  346. package/dist/i18n/locales/hu.js.map +1 -1
  347. package/dist/i18n/locales/it.js +7 -19
  348. package/dist/i18n/locales/it.js.map +1 -1
  349. package/dist/i18n/locales/zh.js +8 -18
  350. package/dist/i18n/locales/zh.js.map +1 -1
  351. package/dist/i18n/review.js +12 -2
  352. package/dist/i18n/review.js.map +1 -1
  353. package/dist/i18n/shared-labels.js +0 -1
  354. package/dist/i18n/shared-labels.js.map +1 -1
  355. package/dist/index.d.ts +21 -23
  356. package/dist/index.js +50 -65
  357. package/dist/index.js.map +1 -1
  358. package/dist/landing/routing.d.ts +3 -1
  359. package/dist/landing/routing.js +4 -7
  360. package/dist/landing/routing.js.map +1 -1
  361. package/dist/lib/broadcast.d.ts +17 -0
  362. package/dist/lib/broadcast.js +30 -0
  363. package/dist/lib/broadcast.js.map +1 -0
  364. package/dist/lib/date-format.d.ts +37 -2
  365. package/dist/lib/date-format.js +34 -8
  366. package/dist/lib/date-format.js.map +1 -1
  367. package/dist/lib/day-format.d.ts +46 -0
  368. package/dist/lib/day-format.js +46 -0
  369. package/dist/lib/day-format.js.map +1 -0
  370. package/dist/lib/describe-failure.d.ts +14 -0
  371. package/dist/lib/describe-failure.js +9 -0
  372. package/dist/lib/describe-failure.js.map +1 -0
  373. package/dist/lib/direction.d.ts +16 -0
  374. package/dist/lib/direction.js +9 -1
  375. package/dist/lib/direction.js.map +1 -1
  376. package/dist/lib/focus-left.d.ts +63 -0
  377. package/dist/lib/focus-left.js +67 -0
  378. package/dist/lib/focus-left.js.map +1 -0
  379. package/dist/lib/format.js +5 -14
  380. package/dist/lib/format.js.map +1 -1
  381. package/dist/lib/http-status.d.ts +24 -0
  382. package/dist/lib/http-status.js +14 -0
  383. package/dist/lib/http-status.js.map +1 -0
  384. package/dist/lib/intl-cache.d.ts +14 -0
  385. package/dist/lib/intl-cache.js +15 -0
  386. package/dist/lib/intl-cache.js.map +1 -0
  387. package/dist/lib/iso-day.d.ts +11 -0
  388. package/dist/lib/iso-day.js +8 -0
  389. package/dist/lib/iso-day.js.map +1 -0
  390. package/dist/lib/lazy-with-fallback.d.ts +31 -0
  391. package/dist/lib/lazy-with-fallback.js +40 -0
  392. package/dist/lib/lazy-with-fallback.js.map +1 -0
  393. package/dist/lib/path-pattern.d.ts +34 -0
  394. package/dist/lib/path-pattern.js +24 -0
  395. package/dist/lib/path-pattern.js.map +1 -0
  396. package/dist/lib/reduced-motion.d.ts +2 -1
  397. package/dist/lib/reduced-motion.js.map +1 -1
  398. package/dist/lib/round.d.ts +2 -1
  399. package/dist/lib/round.js +2 -1
  400. package/dist/lib/round.js.map +1 -1
  401. package/dist/lib/safe-storage.d.ts +24 -5
  402. package/dist/lib/safe-storage.js +27 -2
  403. package/dist/lib/safe-storage.js.map +1 -1
  404. package/dist/lib/session-refresh.js +1 -1
  405. package/dist/lib/session-refresh.js.map +1 -1
  406. package/dist/lib/share-format.d.ts +13 -0
  407. package/dist/lib/share-format.js +10 -0
  408. package/dist/lib/share-format.js.map +1 -0
  409. package/dist/lib/text-case.d.ts +17 -0
  410. package/dist/lib/text-case.js +8 -0
  411. package/dist/lib/text-case.js.map +1 -0
  412. package/dist/lib/text-match.d.ts +29 -0
  413. package/dist/lib/text-match.js +20 -2
  414. package/dist/lib/text-match.js.map +1 -1
  415. package/dist/lib/thenable.d.ts +13 -0
  416. package/dist/lib/thenable.js +8 -0
  417. package/dist/lib/thenable.js.map +1 -0
  418. package/dist/lib/translation-review.d.ts +7 -2
  419. package/dist/lib/translation-review.js +4 -4
  420. package/dist/lib/translation-review.js.map +1 -1
  421. package/dist/notifications/device-zone-report.js +1 -1
  422. package/dist/notifications/device-zone-report.js.map +1 -1
  423. package/dist/notifications/notification-bell.d.ts +2 -1
  424. package/dist/notifications/notification-bell.js +3 -3
  425. package/dist/notifications/notification-bell.js.map +1 -1
  426. package/dist/notifications/notification-inbox.d.ts +10 -6
  427. package/dist/notifications/notification-inbox.js +26 -48
  428. package/dist/notifications/notification-inbox.js.map +1 -1
  429. package/dist/notifications/notification-parts.d.ts +3 -2
  430. package/dist/notifications/notification-parts.js +1 -3
  431. package/dist/notifications/notification-parts.js.map +1 -1
  432. package/dist/notifications/notification-types-setting.js +1 -1
  433. package/dist/notifications/notification-types-setting.js.map +1 -1
  434. package/dist/notifications/notifications-labels.d.ts +6 -0
  435. package/dist/notifications/notifications-labels.js +1 -0
  436. package/dist/notifications/notifications-labels.js.map +1 -1
  437. package/dist/notifications/push-device-setting.js +1 -1
  438. package/dist/notifications/push-device-setting.js.map +1 -1
  439. package/dist/notifications/push-devices-setting.d.ts +2 -1
  440. package/dist/notifications/push-devices-setting.js +27 -49
  441. package/dist/notifications/push-devices-setting.js.map +1 -1
  442. package/dist/notifications/quiet-hours-setting.d.ts +10 -3
  443. package/dist/notifications/quiet-hours-setting.js +65 -26
  444. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  445. package/dist/notifications/unsubscribe-panel.js +4 -7
  446. package/dist/notifications/unsubscribe-panel.js.map +1 -1
  447. package/dist/notifications/use-push-device.d.ts +39 -1
  448. package/dist/notifications/use-push-device.js +28 -7
  449. package/dist/notifications/use-push-device.js.map +1 -1
  450. package/dist/offline/query-persistence.d.ts +3 -1
  451. package/dist/offline/query-persistence.js +19 -2
  452. package/dist/offline/query-persistence.js.map +1 -1
  453. package/dist/rhf/fields.d.ts +11 -4
  454. package/dist/rhf/fields.js.map +1 -1
  455. package/dist/search/command-palette.js +1 -1
  456. package/dist/search/command-palette.js.map +1 -1
  457. package/dist/search/global-search.js +19 -9
  458. package/dist/search/global-search.js.map +1 -1
  459. package/dist/search/search-index.d.ts +0 -6
  460. package/dist/search/search-index.js +0 -4
  461. package/dist/search/search-index.js.map +1 -1
  462. package/dist/search/use-command-key.d.ts +12 -1
  463. package/dist/search/use-command-key.js +3 -12
  464. package/dist/search/use-command-key.js.map +1 -1
  465. package/dist/search.d.ts +1 -1
  466. package/dist/search.js +6 -1
  467. package/dist/search.js.map +1 -1
  468. package/dist/settings/use-settings-focus.js +1 -0
  469. package/dist/settings/use-settings-focus.js.map +1 -1
  470. package/dist/shell/account-menu-language.d.ts +5 -3
  471. package/dist/shell/account-menu-language.js +2 -2
  472. package/dist/shell/account-menu-language.js.map +1 -1
  473. package/dist/shell/account-menu-text-size.d.ts +9 -6
  474. package/dist/shell/account-menu-text-size.js +2 -2
  475. package/dist/shell/account-menu-text-size.js.map +1 -1
  476. package/dist/shell/app-shell.d.ts +0 -10
  477. package/dist/shell/app-shell.js +1 -7
  478. package/dist/shell/app-shell.js.map +1 -1
  479. package/dist/shell/company-switcher.d.ts +1 -1
  480. package/dist/shell/company-switcher.js.map +1 -1
  481. package/dist/shell/dev-menu.d.ts +1 -1
  482. package/dist/shell/dev-menu.js +5 -18
  483. package/dist/shell/dev-menu.js.map +1 -1
  484. package/dist/shell/top-bar-actions.d.ts +1 -1
  485. package/dist/shell/top-bar-actions.js.map +1 -1
  486. package/dist/shell/top-bar-parts-labels.d.ts +1 -3
  487. package/dist/shell/top-bar-parts-labels.js +0 -1
  488. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  489. package/dist/shell.d.ts +7 -10
  490. package/dist/shell.js +14 -23
  491. package/dist/shell.js.map +1 -1
  492. package/dist/sync/engine.d.ts +30 -4
  493. package/dist/sync/engine.js +172 -52
  494. package/dist/sync/engine.js.map +1 -1
  495. package/dist/sync.d.ts +2 -2
  496. package/dist/sync.js +2 -10
  497. package/dist/sync.js.map +1 -1
  498. package/dist/testing/css-variables.js +3 -8
  499. package/dist/testing/css-variables.js.map +1 -1
  500. package/dist/theme/chart-palette.d.ts +0 -5
  501. package/dist/theme/chart-palette.js +0 -2
  502. package/dist/theme/chart-palette.js.map +1 -1
  503. package/dist/theme/contrast.d.ts +2 -1
  504. package/dist/theme/contrast.js +3 -8
  505. package/dist/theme/contrast.js.map +1 -1
  506. package/dist/theme/palette-store.js +6 -6
  507. package/dist/theme/palette-store.js.map +1 -1
  508. package/dist/theme/text-size.js +3 -8
  509. package/dist/theme/text-size.js.map +1 -1
  510. package/dist/theme/theme-store.js +3 -6
  511. package/dist/theme/theme-store.js.map +1 -1
  512. package/dist/tour/tour-catalogue.d.ts +7 -4
  513. package/dist/tour/tour-catalogue.js +12 -10
  514. package/dist/tour/tour-catalogue.js.map +1 -1
  515. package/dist/tour/tour-dock.d.ts +0 -2
  516. package/dist/tour/tour-dock.js +0 -2
  517. package/dist/tour/tour-dock.js.map +1 -1
  518. package/dist/tour/tour-gates.d.ts +4 -0
  519. package/dist/tour/tour-gates.js +14 -0
  520. package/dist/tour/tour-gates.js.map +1 -1
  521. package/dist/tour/tour-overlay.d.ts +27 -0
  522. package/dist/tour/tour-overlay.js +741 -0
  523. package/dist/tour/tour-overlay.js.map +1 -0
  524. package/dist/tour/tour.d.ts +13 -3
  525. package/dist/tour/tour.js +59 -781
  526. package/dist/tour/tour.js.map +1 -1
  527. package/dist/tour/use-tour-progress.js +1 -1
  528. package/dist/tour/use-tour-progress.js.map +1 -1
  529. package/dist/wizard/stepper-nav.d.ts +5 -1
  530. package/dist/wizard/stepper-nav.js.map +1 -1
  531. package/dist/wizard/types.d.ts +6 -2
  532. package/dist/wizard/types.js.map +1 -1
  533. package/dist/wizard/use-wizard.d.ts +3 -1
  534. package/dist/wizard/use-wizard.js.map +1 -1
  535. package/dist/wizard/validation.d.ts +3 -1
  536. package/dist/wizard/validation.js.map +1 -1
  537. package/package.json +10 -6
  538. package/src/account/account-parts.ts +5 -25
  539. package/src/account/data-export-setting-labels.ts +1 -1
  540. package/src/account/delete-account-setting-labels.ts +1 -1
  541. package/src/account/email-change-setting-labels.ts +1 -1
  542. package/src/account/passkeys-setting.tsx +60 -38
  543. package/src/account/sessions-setting.tsx +18 -12
  544. package/src/admin/admin-action-confirm.tsx +1 -5
  545. package/src/admin/admin-parts.ts +11 -25
  546. package/src/admin/mail-test-card-labels.ts +1 -1
  547. package/src/admin/plan-change-labels.ts +5 -23
  548. package/src/admin/plan-change.tsx +7 -44
  549. package/src/admin/reviewer-scope-editor.tsx +3 -3
  550. package/src/auth/auth-errors-labels.ts +23 -0
  551. package/src/auth/auth-errors.ts +11 -38
  552. package/src/auth/complete-name-dialog.tsx +4 -1
  553. package/src/auth/forgot-password-form-labels.ts +1 -1
  554. package/src/auth/forgot-password-form.tsx +11 -6
  555. package/src/auth/register-form-labels.ts +1 -1
  556. package/src/auth/reset-password-form-labels.ts +1 -1
  557. package/src/auth/reset-password-form.tsx +8 -4
  558. package/src/auth/sign-in-form-labels.ts +1 -1
  559. package/src/auth/status-parts.tsx +0 -6
  560. package/src/auth/verify-email-labels.ts +1 -1
  561. package/src/auth/verify-email.tsx +11 -6
  562. package/src/billing/cancel-subscription.tsx +15 -12
  563. package/src/billing/plan-card.tsx +18 -10
  564. package/src/billing/plan-change-labels.ts +66 -0
  565. package/src/billing/plan-switch.tsx +15 -12
  566. package/src/chart.ts +73 -6
  567. package/src/components/account-chips.tsx +20 -23
  568. package/src/components/alert-banner.tsx +82 -5
  569. package/src/components/amount-input.tsx +18 -7
  570. package/src/components/autocomplete.tsx +64 -70
  571. package/src/components/bulk-action-bar.tsx +70 -2
  572. package/src/components/button-look.ts +5 -5
  573. package/src/components/button.tsx +2 -2
  574. package/src/components/chart-edge.ts +34 -1
  575. package/src/components/chart-figure.tsx +35 -0
  576. package/src/components/chart-zoom-core.tsx +6 -5
  577. package/src/components/chart.tsx +26 -5
  578. package/src/components/combobox-core.tsx +293 -62
  579. package/src/components/combobox.tsx +183 -153
  580. package/src/components/copy-button.tsx +34 -23
  581. package/src/components/country-select.tsx +16 -11
  582. package/src/components/data-table-column-settings.tsx +52 -10
  583. package/src/components/data-table-filters.ts +6 -4
  584. package/src/components/data-table-fit.ts +19 -5
  585. package/src/components/data-table-groups.tsx +1 -1
  586. package/src/components/data-table-head.tsx +32 -22
  587. package/src/components/data-table-mobile.tsx +61 -26
  588. package/src/components/data-table-pagination.tsx +21 -6
  589. package/src/components/data-table-resize.ts +1 -1
  590. package/src/components/data-table-row-actions.tsx +3 -3
  591. package/src/components/data-table-row.tsx +25 -14
  592. package/src/components/data-table-selection.ts +1 -1
  593. package/src/components/data-table-shared.tsx +33 -1
  594. package/src/components/data-table-sort.ts +57 -2
  595. package/src/components/data-table-virtual.ts +32 -8
  596. package/src/components/data-table.tsx +239 -68
  597. package/src/components/date-field.tsx +66 -9
  598. package/src/components/date-picker.tsx +125 -49
  599. package/src/components/date-range-picker.tsx +71 -36
  600. package/src/components/error-boundary.tsx +53 -39
  601. package/src/components/field-base-labels.ts +20 -0
  602. package/src/components/field-base.tsx +13 -7
  603. package/src/components/form-actions.tsx +20 -5
  604. package/src/components/hover-menu.tsx +18 -8
  605. package/src/components/icon-button.tsx +14 -9
  606. package/src/components/inline-confirm.tsx +116 -0
  607. package/src/components/inline-entity-combobox.tsx +197 -153
  608. package/src/components/input.tsx +1 -1
  609. package/src/components/jump-calendar.tsx +30 -146
  610. package/src/components/legal-page.tsx +10 -7
  611. package/src/components/legal.tsx +4 -2
  612. package/src/components/lightbox.tsx +21 -8
  613. package/src/components/list.tsx +10 -4
  614. package/src/components/measured-grid.tsx +8 -4
  615. package/src/components/mini-calendar.tsx +6 -5
  616. package/src/components/modal.tsx +6 -1
  617. package/src/components/month-grid.tsx +229 -0
  618. package/src/components/month-picker.tsx +192 -200
  619. package/src/components/multi-select.tsx +21 -9
  620. package/src/components/nav-pills.tsx +1 -1
  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/series-chart-axes.ts +9 -4
  627. package/src/components/series-chart-labels.ts +7 -4
  628. package/src/components/series-chart.tsx +253 -87
  629. package/src/components/share-card.tsx +6 -6
  630. package/src/components/tabs-labels.ts +13 -0
  631. package/src/components/tabs.tsx +2 -2
  632. package/src/components/toggle-legend.tsx +16 -11
  633. package/src/components/translation-review-editor.tsx +6 -5
  634. package/src/components/translation-review.tsx +4 -3
  635. package/src/components/treemap-labels.ts +47 -0
  636. package/src/components/treemap-layout.ts +210 -0
  637. package/src/components/treemap.tsx +780 -138
  638. package/src/components/use-table-state.ts +12 -9
  639. package/src/data-table.ts +1 -4
  640. package/src/demo/demo-countdown.ts +3 -8
  641. package/src/eslint/role-utilities.ts +97 -19
  642. package/src/feedback/feedback-dialog.tsx +30 -19
  643. package/src/feedback/feedback-mutation.ts +20 -0
  644. package/src/feedback/feedback-page-link.ts +90 -0
  645. package/src/feedback/feedback-public-list.tsx +13 -7
  646. package/src/feedback/feedback-replies.tsx +13 -6
  647. package/src/feedback/feedback-row-detail-labels.ts +0 -3
  648. package/src/feedback/feedback-row-detail.tsx +70 -84
  649. package/src/feedback/feedback-status-undo.ts +28 -28
  650. package/src/feedback/feedback-submit-dialog.tsx +2 -2
  651. package/src/feedback/feedback-submit.tsx +21 -7
  652. package/src/feedback/feedback-swipe.tsx +1 -1
  653. package/src/feedback/feedback-table.tsx +86 -38
  654. package/src/feedback/feedback-thread-labels.ts +2 -2
  655. package/src/feedback/feedback-thread.tsx +18 -26
  656. package/src/feedback.ts +89 -6
  657. package/src/hooks/use-focus-trap.ts +8 -24
  658. package/src/hooks/use-hotkey.ts +24 -7
  659. package/src/hooks/use-long-press.ts +16 -2
  660. package/src/hooks/use-media-query.ts +20 -4
  661. package/src/hooks/use-mounted.ts +39 -0
  662. package/src/hooks/use-overlay-history.ts +32 -3
  663. package/src/i18n/defaults.ts +4 -9
  664. package/src/i18n/german.ts +8 -19
  665. package/src/i18n/kit-labels.tsx +9 -11
  666. package/src/i18n/locales/es.ts +8 -19
  667. package/src/i18n/locales/fr.ts +21 -30
  668. package/src/i18n/locales/hu.ts +10 -19
  669. package/src/i18n/locales/it.ts +8 -20
  670. package/src/i18n/locales/zh.ts +9 -19
  671. package/src/i18n/review.ts +12 -2
  672. package/src/i18n/shared-labels.ts +0 -1
  673. package/src/index.ts +57 -49
  674. package/src/landing/routing.tsx +14 -10
  675. package/src/lib/broadcast.ts +52 -0
  676. package/src/lib/date-format.ts +89 -13
  677. package/src/lib/day-format.ts +96 -0
  678. package/src/lib/describe-failure.ts +18 -0
  679. package/src/lib/direction.ts +39 -0
  680. package/src/lib/focus-left.ts +156 -0
  681. package/src/lib/format.ts +5 -17
  682. package/src/lib/http-status.ts +38 -0
  683. package/src/lib/intl-cache.ts +25 -0
  684. package/src/lib/iso-day.ts +13 -0
  685. package/src/lib/lazy-with-fallback.ts +82 -0
  686. package/src/lib/path-pattern.ts +55 -0
  687. package/src/lib/reduced-motion.ts +2 -1
  688. package/src/lib/round.ts +7 -2
  689. package/src/lib/safe-storage.ts +48 -6
  690. package/src/lib/session-refresh.ts +1 -1
  691. package/src/lib/share-format.ts +18 -0
  692. package/src/lib/text-case.ts +19 -0
  693. package/src/lib/text-match.ts +57 -2
  694. package/src/lib/thenable.ts +19 -0
  695. package/src/lib/translation-review.ts +13 -5
  696. package/src/notifications/device-zone-report.ts +1 -1
  697. package/src/notifications/notification-bell.tsx +7 -4
  698. package/src/notifications/notification-inbox.tsx +40 -58
  699. package/src/notifications/notification-parts.tsx +3 -4
  700. package/src/notifications/notification-types-setting.tsx +1 -1
  701. package/src/notifications/notifications-labels.ts +7 -0
  702. package/src/notifications/push-device-setting.tsx +1 -1
  703. package/src/notifications/push-devices-setting.tsx +30 -55
  704. package/src/notifications/quiet-hours-setting.tsx +93 -31
  705. package/src/notifications/unsubscribe-panel.tsx +4 -7
  706. package/src/notifications/use-push-device.ts +76 -10
  707. package/src/offline/query-persistence.ts +35 -3
  708. package/src/rhf/fields.tsx +11 -4
  709. package/src/search/command-palette.tsx +2 -4
  710. package/src/search/global-search.tsx +36 -15
  711. package/src/search/search-index.ts +0 -15
  712. package/src/search/use-command-key.ts +13 -12
  713. package/src/search.ts +10 -1
  714. package/src/settings/use-settings-focus.ts +3 -0
  715. package/src/shell/account-menu-language.tsx +6 -4
  716. package/src/shell/account-menu-text-size.tsx +10 -7
  717. package/src/shell/app-shell.tsx +0 -13
  718. package/src/shell/company-switcher.tsx +1 -1
  719. package/src/shell/dev-menu.tsx +8 -22
  720. package/src/shell/top-bar-actions.tsx +1 -1
  721. package/src/shell/top-bar-parts-labels.ts +1 -4
  722. package/src/shell.ts +21 -17
  723. package/src/sync/engine.ts +339 -61
  724. package/src/sync.ts +2 -8
  725. package/src/testing/css-variables.ts +8 -9
  726. package/src/theme/chart-palette.ts +0 -2
  727. package/src/theme/contrast.ts +8 -9
  728. package/src/theme/palette-store.ts +9 -9
  729. package/src/theme/text-size.ts +6 -8
  730. package/src/theme/theme-store.ts +7 -9
  731. package/src/tour/tour-catalogue.tsx +26 -15
  732. package/src/tour/tour-dock.ts +0 -2
  733. package/src/tour/tour-gates.ts +23 -0
  734. package/src/tour/tour-overlay.tsx +1170 -0
  735. package/src/tour/tour.tsx +108 -1202
  736. package/src/tour/use-tour-progress.ts +1 -1
  737. package/src/wizard/stepper-nav.tsx +3 -1
  738. package/src/wizard/types.ts +11 -2
  739. package/src/wizard/use-wizard.ts +2 -1
  740. package/src/wizard/validation.ts +8 -2
  741. package/tokens.css +6 -5
  742. package/dist/components/field-sync-labels.d.ts +0 -2
  743. package/dist/components/field-sync-labels.js +0 -12
  744. package/dist/components/field-sync-labels.js.map +0 -1
  745. package/dist/components/field-sync.d.ts +0 -164
  746. package/dist/components/field-sync.js +0 -269
  747. package/dist/components/field-sync.js.map +0 -1
  748. package/dist/components/section-nav.d.ts +0 -37
  749. package/dist/components/section-nav.js +0 -33
  750. package/dist/components/section-nav.js.map +0 -1
  751. package/dist/components/sign-chip-labels.d.ts +0 -2
  752. package/dist/components/sign-chip-labels.js +0 -11
  753. package/dist/components/sign-chip-labels.js.map +0 -1
  754. package/dist/components/sign-chip.d.ts +0 -68
  755. package/dist/components/sign-chip.js +0 -47
  756. package/dist/components/sign-chip.js.map +0 -1
  757. package/dist/components/ui-labels.js.map +0 -1
  758. package/dist/lib/isin.d.ts +0 -28
  759. package/dist/lib/isin.js +0 -36
  760. package/dist/lib/isin.js.map +0 -1
  761. package/dist/shell/dev-switchers.d.ts +0 -6
  762. package/dist/shell/dev-switchers.js +0 -12
  763. package/dist/shell/dev-switchers.js.map +0 -1
  764. package/dist/shell/role-switcher.d.ts +0 -21
  765. package/dist/shell/role-switcher.js +0 -31
  766. package/dist/shell/role-switcher.js.map +0 -1
  767. package/src/components/field-sync-labels.ts +0 -13
  768. package/src/components/field-sync.tsx +0 -482
  769. package/src/components/section-nav.tsx +0 -65
  770. package/src/components/sign-chip-labels.ts +0 -12
  771. package/src/components/sign-chip.tsx +0 -124
  772. package/src/components/ui-labels.ts +0 -24
  773. package/src/lib/isin.ts +0 -62
  774. package/src/shell/dev-switchers.tsx +0 -18
  775. package/src/shell/role-switcher.tsx +0 -46
@@ -1,12 +1,13 @@
1
- // The two-date range picker: presets beside the calendar, `commit="apply"` drafts, a
2
- // custom trigger. Moved out of date-picker.tsx as it was (MOD-9, refactor audit
1
+ // The two-date range picker: presets beside the calendar, `apply` drafts, a custom
2
+ // trigger. Moved out of date-picker.tsx as it was (MOD-9, refactor audit
3
3
  // 2026-10); date-picker still exports every public name here.
4
4
  import { useState } from "react";
5
5
  import type { ReactNode } from "react";
6
6
  import { cn } from "../lib/cn";
7
7
  import { useKitLocale, type DatePickerLabels } from "../i18n/kit-labels";
8
8
  import { Button } from "./button";
9
- import { FieldBox, useFieldMessages } from "./field-parts";
9
+ import { FieldBox, LockedReason, useFieldMessages, useLockReason } from "./field-parts";
10
+ import type { CommitScope } from "./write-lock";
10
11
  import { usePhoneLayout } from "../hooks/use-breakpoint";
11
12
  import {
12
13
  DateField,
@@ -39,23 +40,6 @@ export interface DateRangePickerPreset {
39
40
  to: string;
40
41
  }
41
42
 
42
- /**
43
- * When the picker hands its range to `onChange`.
44
- *
45
- * - `"immediate"` (the default, and all of 0.7): a preset click commits and closes,
46
- * and each calendar click is reported as it happens — the half-made `(from, "")`
47
- * included. The right shape for quick ranges on a filter, where one click is one
48
- * answer.
49
- * - `"apply"`: the panel works on a DRAFT. A preset ARMS the calendar instead of
50
- * committing, days can then be nudged ("last 3 months, but end it last Friday"),
51
- * and nothing reaches `onChange` until Apply — which stays disabled until both ends
52
- * exist. Cancel, Escape and an outside click discard the draft, and every open
53
- * starts again from the committed value. keksdose's report range asked for exactly
54
- * this: each commit there re-runs a whole page of charts, so an intermediate state
55
- * must never escape the panel.
56
- */
57
- export type DateRangeCommit = "immediate" | "apply";
58
-
59
43
  export interface DateRangePickerProps extends DatePickerBaseProps {
60
44
  from: string;
61
45
  to: string;
@@ -65,8 +49,9 @@ export interface DateRangePickerProps extends DatePickerBaseProps {
65
49
  onChange: (from: string, to: string, presetId?: string) => void;
66
50
  /** Separator between the two formatted dates in the trigger (default " – "). */
67
51
  separator?: string;
68
- /** Optional named ranges rendered as a start-side column (last month / YTD / …). */
69
- presets?: DateRangePickerPreset[];
52
+ /** Optional named ranges rendered as a start-side column (last month / YTD / …).
53
+ * `readonly` since 0.52 (API-7): the picker never changes the list. */
54
+ presets?: readonly DateRangePickerPreset[];
70
55
  /**
71
56
  * The active preset's `id`, controlled — e.g. straight from keksdose's `?preset=`.
72
57
  * `null` (or an id no preset has, such as `"custom"`) says "no preset": nothing in
@@ -77,8 +62,36 @@ export interface DateRangePickerProps extends DatePickerBaseProps {
77
62
  * itself; with no memory at all it falls back to the first preset whose dates match.
78
63
  */
79
64
  preset?: string | null;
80
- /** See {@link DateRangeCommit}. Default `"immediate"`. */
81
- commit?: DateRangeCommit;
65
+ /**
66
+ * When the picker hands its range to `onChange`.
67
+ *
68
+ * - Left out (the default, and all of 0.7): a preset click commits and closes, and
69
+ * each calendar click is reported as it happens — the half-made `(from, "")`
70
+ * included. The right shape for quick ranges on a filter, where one click is one
71
+ * answer.
72
+ * - `apply`: the panel works on a DRAFT. A preset ARMS the calendar instead of
73
+ * committing, days can then be nudged ("last 3 months, but end it last Friday"),
74
+ * and nothing reaches `onChange` until Apply — which stays disabled until both ends
75
+ * exist. Cancel, Escape and an outside click discard the draft, and every open
76
+ * starts again from the committed value. keksdose's report range asked for exactly
77
+ * this: each commit there re-runs a whole page of charts, so an intermediate state
78
+ * must never escape the panel.
79
+ *
80
+ * `commit="apply"` until 0.52 (refactor audit 2026-10-30, API-3): `commit` is the write
81
+ * lock's prop on every other kit control. The old spelling went in 0.53.
82
+ */
83
+ apply?: boolean;
84
+ /**
85
+ * This picker COMMITS — picking a range saves it (a report's period kept per user, a
86
+ * filter persisted as it moves). Under a locked {@link WriteLockProvider} it is locked
87
+ * the `disabledReason` way, with the lock's reason; a {@link CommitScope}, as on every
88
+ * kit control since 0.33, and on this one since 0.52 (API-3). A range inside a form with
89
+ * its own Save stays editable under the lock — leave this off there.
90
+ *
91
+ * The strings `"immediate"` and `"apply"`, the panel's mode in 0.x, went in 0.53
92
+ * (deprecated in 0.52): `apply` is the mode.
93
+ */
94
+ commit?: CommitScope;
82
95
  /**
83
96
  * Draw the trigger yourself. keksdose's report range field
84
97
  * (reports/report-range-field.tsx, "Why this is app-level") is why: its trigger
@@ -103,7 +116,7 @@ export interface DateRangePickerProps extends DatePickerBaseProps {
103
116
  */
104
117
  sheetBackCloses?: boolean;
105
118
  /**
106
- * With `commit="apply"`: a line above the calendar saying what Apply would commit —
119
+ * With `apply`: a line above the calendar saying what Apply would commit —
107
120
  * keksdose's report range writes "Custom · 1 Mar 2026 – …" there
108
121
  * (report-range-field.tsx), the one place a preset armed and then nudged by a day is
109
122
  * seen to have become "Custom", and a half-made range to still lack its end. Called
@@ -112,7 +125,7 @@ export interface DateRangePickerProps extends DatePickerBaseProps {
112
125
  * `""` until the second click. The line is a polite live region, so a screen reader
113
126
  * hears the draft change as the calendar is used.
114
127
  *
115
- * Ignored in `"immediate"` mode, where there is no draft: every click is the value.
128
+ * Ignored without `apply`, where there is no draft: every click is the value.
116
129
  */
117
130
  renderDraftSummary?: (draft: DateRangeDraftSummary) => ReactNode;
118
131
  }
@@ -218,8 +231,8 @@ function PresetColumn({
218
231
  }
219
232
 
220
233
  /**
221
- * The panel's body. A component of its own so `commit="apply"` can keep its draft in
222
- * state that is born when the panel opens: `Popover` unmounts its children on close,
234
+ * The panel's body. A component of its own so `apply` can keep its draft in state that
235
+ * is born when the panel opens: `Popover` unmounts its children on close,
223
236
  * so the draft is re-seeded from the committed value on every open, and an abandoned
224
237
  * half-selection cannot survive into the next one.
225
238
  */
@@ -229,7 +242,7 @@ function RangePanel({
229
242
  presets,
230
243
  activeId,
231
244
  controlled,
232
- commit,
245
+ drafting,
233
246
  close,
234
247
  frame,
235
248
  sheet,
@@ -243,7 +256,8 @@ function RangePanel({
243
256
  presets: readonly DateRangePickerPreset[] | undefined;
244
257
  activeId: string | null | undefined;
245
258
  controlled: boolean;
246
- commit: DateRangeCommit;
259
+ /** `apply`: the panel works on a draft. */
260
+ drafting: boolean;
247
261
  close: () => void;
248
262
  /** Where the body and the Apply row go — see `PanelFrame`. */
249
263
  frame: PanelFrame;
@@ -253,7 +267,6 @@ function RangePanel({
253
267
  labels: DatePickerLabels;
254
268
  renderDraftSummary?: DateRangePickerProps["renderDraftSummary"];
255
269
  }) {
256
- const drafting = commit === "apply";
257
270
  const [draft, setDraft] = useState<RangeDraft>({
258
271
  from,
259
272
  to,
@@ -360,8 +373,8 @@ function RangePanel({
360
373
  }
361
374
 
362
375
  /** Two-date range picker: click a start then an end; closes once both are set.
363
- * With `presets`, a column of named ranges is shown beside the calendar; with
364
- * `commit="apply"` the panel drafts and commits on Apply (see {@link DateRangeCommit}). */
376
+ * With `presets`, a column of named ranges is shown beside the calendar; with `apply`
377
+ * the panel drafts and commits on Apply (see {@link DateRangePickerProps.apply}). */
365
378
  export function DateRangePicker(props: DateRangePickerProps) {
366
379
  const {
367
380
  from,
@@ -376,7 +389,8 @@ export function DateRangePicker(props: DateRangePickerProps) {
376
389
  separator = " – ",
377
390
  presets,
378
391
  preset,
379
- commit = "immediate",
392
+ apply,
393
+ commit,
380
394
  renderTrigger,
381
395
  sheetBackCloses,
382
396
  renderDraftSummary,
@@ -386,10 +400,13 @@ export function DateRangePicker(props: DateRangePickerProps) {
386
400
  clearable,
387
401
  clearLabel,
388
402
  disabled,
403
+ disabledReason,
404
+ disabledReasonDisplay,
389
405
  invalid,
390
406
  hint,
391
407
  help,
392
408
  error,
409
+ className,
393
410
  // The trigger's (API-3).
394
411
  ref,
395
412
  ...rest
@@ -397,6 +414,9 @@ export function DateRangePicker(props: DateRangePickerProps) {
397
414
  const locale = useKitLocale(localeProp);
398
415
  const text = useDatePickerLabels(clearLabel, undefined, undefined);
399
416
  const render = useTriggerFormat("dateRangePicker", locale, formatOptions, formatValue);
417
+ const drafting = apply ?? false;
418
+ const lock = useLockReason(commit, disabledReason);
419
+ const locked = lock.locked;
400
420
  const messages = useFieldMessages({
401
421
  hint,
402
422
  help,
@@ -405,6 +425,8 @@ export function DateRangePicker(props: DateRangePickerProps) {
405
425
  invalid,
406
426
  describedBy: rest["aria-describedby"],
407
427
  ariaInvalid: rest["aria-invalid"],
428
+ // A lock's reason between the caption and the error, as on Select.
429
+ reasonId: locked && lock.reasonId,
408
430
  });
409
431
  // The preset this picker committed itself, for a caller that does not control
410
432
  // `preset`. Cleared by a hand-picked range or a clear.
@@ -417,6 +439,7 @@ export function DateRangePicker(props: DateRangePickerProps) {
417
439
  const hasPresets = Boolean(presets && presets.length > 0);
418
440
  const sheet = usePhoneLayout();
419
441
  const commitRange = (f: string, t: string, presetId: string | undefined) => {
442
+ if (locked) return;
420
443
  setOwnPreset(presetId);
421
444
  // Two arguments when no preset is involved — exactly the 0.7 call, so a caller's
422
445
  // `toHaveBeenCalledWith(from, to)` and a variadic handler see no difference.
@@ -434,6 +457,9 @@ export function DateRangePicker(props: DateRangePickerProps) {
434
457
  clearLabel={text.clear}
435
458
  panelLabel={text.rangePanel}
436
459
  disabled={disabled}
460
+ locked={locked}
461
+ // Locked, the caller's classes are the reason's frame's (below).
462
+ className={locked ? undefined : className}
437
463
  invalid={messages.isInvalid}
438
464
  // Widen so the preset column sits beside the calendar (default otherwise).
439
465
  width={hasPresets ? "27.5rem" : undefined}
@@ -463,7 +489,7 @@ export function DateRangePicker(props: DateRangePickerProps) {
463
489
  presets={presets}
464
490
  activeId={activeId}
465
491
  controlled={controlled}
466
- commit={commit}
492
+ drafting={drafting}
467
493
  close={close}
468
494
  frame={frame}
469
495
  sheet={sheet}
@@ -475,9 +501,18 @@ export function DateRangePicker(props: DateRangePickerProps) {
475
501
  )}
476
502
  </DateField>
477
503
  );
504
+ const box = withEndHint(field, label === undefined ? messages.labelHint : undefined);
478
505
  return (
479
506
  <FieldBox below={messages.below} reserve={"error" in props || "hint" in props}>
480
- {withEndHint(field, label === undefined ? messages.labelHint : undefined)}
507
+ {locked ? (
508
+ // DatePicker's frame: the line under the field, or the Tooltip with a hidden copy
509
+ // for `aria-describedby`; the outermost box, so it takes the caller's classes.
510
+ <LockedReason lock={lock} display={disabledReasonDisplay} className={cn("block", className)}>
511
+ {box}
512
+ </LockedReason>
513
+ ) : (
514
+ box
515
+ )}
481
516
  </FieldBox>
482
517
  );
483
518
  }
@@ -1,4 +1,4 @@
1
- import { Component } from "react";
1
+ import { Component, useEffect } from "react";
2
2
  import type { ErrorInfo, ReactNode } from "react";
3
3
  import { AlertTriangle, RefreshCw, WifiOff } from "lucide-react";
4
4
  import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
@@ -7,6 +7,7 @@ import { EmptyState } from "./empty-state";
7
7
  import { CopyButton } from "./copy-button";
8
8
  import { Disclosure } from "./disclosure";
9
9
  import { documentNavigation } from "../lib/document-navigation";
10
+ import { useAnnounce } from "../hooks/use-announce";
10
11
  import { DEFAULT_ERROR_BOUNDARY_LABELS } from "./error-boundary-labels";
11
12
 
12
13
  /** The words of the default fallback. */
@@ -605,6 +606,17 @@ function ErrorFallback({
605
606
  const reportText = report ? formatCrashReport(report) : null;
606
607
  const errorLine = details.message ? `${details.name}: ${details.message}` : details.name;
607
608
 
609
+ // The title and the hint, said once through an assertive region of their own (0.52,
610
+ // refactor audit 2026-10-30, DSP-17). `role="alert"` on the whole box put the actions
611
+ // in it, so each later insertion was read out as news: "Copy error report" and
612
+ // "Details" on `componentDidCatch`'s second render, "Reported as …", and on opening
613
+ // Details both stacks of the crash report. EmptyState has no wrapper for title and
614
+ // hint alone, and a region mounted with its message is often missed anyway.
615
+ const alert = useAnnounce({ politeness: "assertive" });
616
+ const { announce } = alert;
617
+ const spoken = `${title}. ${hint}`;
618
+ useEffect(() => announce(spoken), [announce, spoken]);
619
+
608
620
  const reloadButton = (
609
621
  <Button key="reload" variant={mode === "error" ? "secondary" : "default"} onClick={reloadPage}>
610
622
  {text.reload}
@@ -619,43 +631,45 @@ function ErrorFallback({
619
631
  );
620
632
 
621
633
  return (
622
- <EmptyState
623
- role="alert"
624
- tone={mode === "error" ? "danger" : undefined}
625
- headingAs={headingAs}
626
- className={className}
627
- icon={<Icon />}
628
- title={title}
629
- hint={hint}
630
- action={
631
- <>
632
- {showMessage && mode === "error" && (
633
- // A quotation, not prose: left-aligned and monospaced, so it reads as the
634
- // program's words and can be read out or screenshotted verbatim.
635
- <p
636
- data-error-message=""
637
- className="-mt-1 mb-1 basis-full whitespace-pre-wrap break-words rounded-md border border-danger-strong bg-danger-soft px-3 py-2 text-start font-mono text-xs text-primary"
638
- >
639
- {errorLine}
640
- </p>
641
- )}
642
- {filing === "filed" && (
643
- <p className="-mt-1 mb-1 basis-full text-xs">{reference ? text.reportedAs(reference) : text.reported}</p>
644
- )}
645
- {mode === "error" ? [retryButton, reloadButton] : [reloadButton, retryButton]}
646
- {copyReport && reportText !== null && filing !== "filed" && (
647
- <CopyButton variant="label" buttonVariant="ghost" label={text.copyReport} text={reportText} />
648
- )}
649
- {actions}
650
- {showDetails && reportText !== null && (
651
- <Disclosure variant="bare" title={text.details} className="basis-full text-start">
652
- <pre className="max-h-60 overflow-auto whitespace-pre-wrap break-words text-xs text-secondary">
653
- {reportText}
654
- </pre>
655
- </Disclosure>
656
- )}
657
- </>
658
- }
659
- />
634
+ <>
635
+ <span {...alert.regionProps} />
636
+ <EmptyState
637
+ tone={mode === "error" ? "danger" : undefined}
638
+ headingAs={headingAs}
639
+ className={className}
640
+ icon={<Icon />}
641
+ title={title}
642
+ hint={hint}
643
+ action={
644
+ <>
645
+ {showMessage && mode === "error" && (
646
+ // A quotation, not prose: left-aligned and monospaced, so it reads as the
647
+ // program's words and can be read out or screenshotted verbatim.
648
+ <p
649
+ data-error-message=""
650
+ className="-mt-1 mb-1 basis-full whitespace-pre-wrap break-words rounded-md border border-danger-strong bg-danger-soft px-3 py-2 text-start font-mono text-xs text-primary"
651
+ >
652
+ {errorLine}
653
+ </p>
654
+ )}
655
+ {filing === "filed" && (
656
+ <p className="-mt-1 mb-1 basis-full text-xs">{reference ? text.reportedAs(reference) : text.reported}</p>
657
+ )}
658
+ {mode === "error" ? [retryButton, reloadButton] : [reloadButton, retryButton]}
659
+ {copyReport && reportText !== null && filing !== "filed" && (
660
+ <CopyButton variant="label" buttonVariant="ghost" label={text.copyReport} text={reportText} />
661
+ )}
662
+ {actions}
663
+ {showDetails && reportText !== null && (
664
+ <Disclosure variant="bare" title={text.details} className="basis-full text-start">
665
+ <pre className="max-h-60 overflow-auto whitespace-pre-wrap break-words text-xs text-secondary">
666
+ {reportText}
667
+ </pre>
668
+ </Disclosure>
669
+ )}
670
+ </>
671
+ }
672
+ />
673
+ </>
660
674
  );
661
675
  }
@@ -0,0 +1,20 @@
1
+ // The English words of ./field-base, in a module with no component code: the English
2
+ // catalogue (src/i18n/defaults.ts) imports them without the component, so `en` loads as one
3
+ // chunk like the other languages (0.34, KS U8). ./field-base re-exports them.
4
+ //
5
+ // Until 0.52 they shared ui-labels.ts with the tabs' words, named after the ui.tsx that
6
+ // 0.34 split up (MOD-7, refactor audit 2026-10-30): one labels module per component now,
7
+ // as every other `*-labels.ts` is.
8
+
9
+ import type { CharacterCountLabels, PasswordRevealLabels } from "./field-base";
10
+
11
+ export const DEFAULT_PASSWORD_REVEAL_LABELS: PasswordRevealLabels = {
12
+ show: "Show password",
13
+ hide: "Hide password",
14
+ };
15
+
16
+ export const DEFAULT_CHARACTER_COUNT_LABELS: CharacterCountLabels = {
17
+ count: (used, max) => `${used} of ${max} characters`,
18
+ remaining: (left) => (left === 1 ? "1 character left" : `${left} characters left`),
19
+ limitReached: "Character limit reached",
20
+ };
@@ -11,7 +11,7 @@ import {
11
11
  STATIC_LABEL_TYPE,
12
12
  type FieldHintParts,
13
13
  } from "./field-parts";
14
- import { DEFAULT_CHARACTER_COUNT_LABELS, DEFAULT_PASSWORD_REVEAL_LABELS } from "./ui-labels";
14
+ import { DEFAULT_CHARACTER_COUNT_LABELS, DEFAULT_PASSWORD_REVEAL_LABELS } from "./field-base-labels";
15
15
 
16
16
  /**
17
17
  * The field base: what Input, Select and Textarea — and every kit field built on the same
@@ -20,7 +20,8 @@ import { DEFAULT_CHARACTER_COUNT_LABELS, DEFAULT_PASSWORD_REVEAL_LABELS } from "
20
20
  * reveal and the character counter. The message under a wrong field is field-parts'
21
21
  * `useFieldError`, every field's.
22
22
  *
23
- * Public through ./ui by name. `FieldGroup`, the counter and the placeholder helpers are
23
+ * Public through the barrel (src/index.ts) by name. `FieldGroup`, the counter and the
24
+ * placeholder helpers are
24
25
  * the three fields' shared parts (`@internal`), as are the Select's own classes and its
25
26
  * `SelectWidthFloor` (0.51).
26
27
  */
@@ -47,7 +48,12 @@ export const FIELD_BASE =
47
48
  // doubles the line inward — FIELD_INVALID's border-plus-ring (live #295), and the
48
49
  // DatePicker stepper's fix (0.34) — so every side keeps one fully covered device
49
50
  // pixel. Inset: nothing outside the field moves or is covered.
50
- "focus:ring-1 focus:ring-inset focus:ring-brand " +
51
+ //
52
+ // Under More contrast the ring is 2px, so the line is 3px — what `--focus-ring-width`
53
+ // gives every `FOCUS_RING` there, and what `appearance.contrastHelp` promises ("thickens
54
+ // focus frames"); before 0.52 a text field kept its 2px (refactor audit 2026-10-30,
55
+ // DOC-2). Still inset, so nothing moves.
56
+ "focus:ring-1 contrast:focus:ring-2 focus:ring-inset focus:ring-brand " +
51
57
  // §10.1: at least 16 px on a touch screen, or iOS zooms the page on focus.
52
58
  FIELD_TOUCH_TEXT +
53
59
  " " +
@@ -106,9 +112,9 @@ export const FIELD_FLOATING_PAD = "pt-4 pb-1 large:py-2";
106
112
  //
107
113
  // A ring rather than `border-2`: a box-shadow adds no layout, so an invalid field
108
114
  // stays exactly the size of a valid one and nothing beside it moves when the value
109
- // arrives.
115
+ // arrives. Under More contrast the ring is 2px, as FIELD_BASE's focus line (0.52, DOC-2).
110
116
  export const FIELD_INVALID =
111
- "border-danger-strong ring-1 ring-danger-strong focus:border-[var(--danger)] focus:ring-[var(--danger)]";
117
+ "border-danger-strong ring-1 contrast:ring-2 ring-danger-strong focus:border-[var(--danger)] focus:ring-[var(--danger)]";
112
118
 
113
119
  export const FLOATING_INPUT_CLASS = cn(FIELD_BASE, FIELD_FLOATING_PAD, "peer placeholder:text-transparent");
114
120
 
@@ -504,7 +510,7 @@ export interface PasswordRevealLabels {
504
510
  hide: string;
505
511
  }
506
512
 
507
- // Defined in ./ui-labels, which holds no component code (0.34, KS U8).
513
+ // Defined in ./field-base-labels, which holds no component code (0.34, KS U8).
508
514
  export { DEFAULT_PASSWORD_REVEAL_LABELS };
509
515
 
510
516
  /**
@@ -523,7 +529,7 @@ export interface CharacterCountLabels {
523
529
  limitReached: string;
524
530
  }
525
531
 
526
- // Defined in ./ui-labels, which holds no component code (0.34, KS U8).
532
+ // Defined in ./field-base-labels, which holds no component code (0.34, KS U8).
527
533
  export { DEFAULT_CHARACTER_COUNT_LABELS };
528
534
 
529
535
  /** The length the browser's own `maxLength` counts — UTF-16 code units — so the counter
@@ -5,7 +5,9 @@ import { cn } from "../lib/cn";
5
5
  import { useKitLabels } from "../i18n/kit-labels";
6
6
  import { useBreakpoint, usePhoneLayout } from "../hooks/use-breakpoint";
7
7
  import { useLargeText } from "../hooks/use-large-text";
8
- import { isApplePlatform } from "../hooks/use-hotkey";
8
+ import { isApplePlatform, matchesHotkey, type ParsedHotkey } from "../hooks/use-hotkey";
9
+ import { isComposing } from "../lib/ime";
10
+ import { hasContent } from "../lib/presence";
9
11
  import { Button, type ButtonProps } from "./button";
10
12
  import { Spinner } from "./spinner";
11
13
  import type { ButtonSize, ButtonVariant } from "./button-look";
@@ -337,6 +339,17 @@ function shortcutScope(row: HTMLElement | null, formId: string | undefined): Ele
337
339
  return row.closest("form") ?? row.closest('[role="dialog"]') ?? row.parentElement;
338
340
  }
339
341
 
342
+ /**
343
+ * What {@link FormActionsProps.submitShortcut} answers, on every platform: Ctrl+Enter and
344
+ * Cmd+Enter with nothing else held, read by `matchesHotkey` as every kit shortcut is
345
+ * (refactor audit 2026-10-30, DUP-12). Literals, not `parseHotkey` calls: no module-scope
346
+ * call for a bundler to keep.
347
+ */
348
+ const SUBMIT_CHORDS: readonly ParsedHotkey[] = [
349
+ { ctrl: true, meta: false, shift: false, alt: false, key: "Enter" },
350
+ { ctrl: false, meta: true, shift: false, alt: false, key: "Enter" },
351
+ ];
352
+
340
353
  function isDestructiveData(value: unknown): value is FormActionsDestructive {
341
354
  return typeof value === "object" && value !== null && !isValidElement(value) && "onClick" in value;
342
355
  }
@@ -429,8 +442,9 @@ export function FormActions({
429
442
  useEffect(() => {
430
443
  if (submitShortcut !== "mod-enter") return;
431
444
  const onKeyDown = (e: KeyboardEvent) => {
432
- if (e.key !== "Enter" || !(e.ctrlKey || e.metaKey) || e.shiftKey || e.altKey) return;
433
- if (e.repeat || e.isComposing || e.defaultPrevented || !canSaveRef.current) return;
445
+ if (!SUBMIT_CHORDS.some((chord) => matchesHotkey(e, chord))) return;
446
+ // `isComposing` is lib/ime's: Safari's composition-ending Enter (keyCode 229) too.
447
+ if (e.repeat || isComposing(e) || e.defaultPrevented || !canSaveRef.current) return;
434
448
  const scope = shortcutScope(rootRef.current, form);
435
449
  if (!scope || !(e.target instanceof Node) || !scope.contains(e.target)) return;
436
450
  e.preventDefault();
@@ -442,8 +456,9 @@ export function FormActions({
442
456
  const apple = submitShortcut ? isApplePlatform() : false;
443
457
  const placement = useResolvedPlacement(placementProp);
444
458
  const bleedLength = bleed === undefined || bleed === "" ? undefined : cssLength(bleed);
445
- const hasDestructive = destructive !== undefined && destructive !== null && destructive !== false;
446
- const hasStart = startSlot !== undefined && startSlot !== null && startSlot !== false;
459
+ // `hasContent` (DUP-14): an empty string is no slot either, not an empty `me-auto` box.
460
+ const hasDestructive = isDestructiveData(destructive) || hasContent(destructive);
461
+ const hasStart = hasContent(startSlot);
447
462
  const justify = align ?? (hasDestructive || hasStart ? "between" : "end");
448
463
  const destructiveNode = !hasDestructive ? null : isDestructiveData(destructive) ? (
449
464
  <Button
@@ -18,6 +18,9 @@ export interface HoverMenuProps extends Omit<ComponentPropsWithoutRef<"div">, "c
18
18
  /** The trigger. `toggle` for a button's click; `close` for a trigger that is a LINK —
19
19
  * following it should shut a panel hover opened (TopBarActionMenu `href`). */
20
20
  trigger: (state: { open: boolean; toggle: () => void; close: () => void }) => ReactNode;
21
+ /** The menu's rows. `close` shuts the menu and, when focus is in it, puts focus on the
22
+ * trigger before returning — so a dialog the same handler opens gives it back there
23
+ * (0.52). */
21
24
  children: (close: () => void) => ReactNode;
22
25
  /**
23
26
  * Which edge of the trigger the panel lines up with, by the reading direction: `end`
@@ -177,16 +180,20 @@ export function HoverMenu({
177
180
  ) ?? null;
178
181
  const items = () => (menuRef.current ? applyMenuSemantics(menuRef.current) : []);
179
182
 
180
- // Escape closes, from anywhere — it did nothing at all before — as a layer on the kit's
181
- // Escape stack, so inside a dialog it closes the menu and not the dialog (Wave 2,
182
- // DUP-1). Focus goes back to the trigger only when it was inside the menu: a panel
183
- // opened by hover while the user is typing elsewhere must not yank the caret over
184
- // here on the way out.
185
- const layer = useDismissLayer(open, () => {
183
+ // Focus goes back to the trigger only when it was inside the menu: a panel opened by
184
+ // hover while the user is typing elsewhere must not yank the caret over here on the
185
+ // way out. At once, not after the commit: a row that closes the menu and opens a dialog
186
+ // in one handler has the dialog record its restore target during that commit's render,
187
+ // and the row it would record is about to go (refactor audit 2026-10-30, INP-2).
188
+ const closeToTrigger = () => {
186
189
  const hadFocus = wrapperRef.current?.contains(document.activeElement) ?? false;
187
190
  close();
188
191
  if (hadFocus) triggerEl()?.focus();
189
- });
192
+ };
193
+ // Escape closes, from anywhere — it did nothing at all before — as a layer on the kit's
194
+ // Escape stack, so inside a dialog it closes the menu and not the dialog (Wave 2,
195
+ // DUP-1).
196
+ const layer = useDismissLayer(open, closeToTrigger);
190
197
 
191
198
  // Upgrade the markup every render while open (the caller's rows can change), then
192
199
  // honour a pending keyboard open.
@@ -324,7 +331,10 @@ export function HoverMenu({
324
331
  panelClassName,
325
332
  )}
326
333
  >
327
- {children(close)}
334
+ {
335
+ // eslint-disable-next-line react-hooks/refs -- handed to the items' handlers: it reads the trigger and the focus when an item is chosen, never while rendering
336
+ children(closeToTrigger)
337
+ }
328
338
  </div>
329
339
  </div>
330
340
  )}
@@ -148,22 +148,27 @@ const ICON_BUTTON_TONES: Record<ColouredTone, { quiet: string; toned: string }>
148
148
  // focus ring at 1.1:1 on the light surfaces.
149
149
  toned: "text-warning hover:bg-warning-soft focus-visible:ring-warning-strong",
150
150
  },
151
+ // The ring is the tone's own text colour (0.52, refactor audit 2026-10-30, DSP-6):
152
+ // `--info-border` and `--success-border` rang at 1.2–1.4:1 on the light grounds and
153
+ // about 2:1 in dark, and More contrast re-solves neither — while `--info` / `--success`
154
+ // clear 4.5:1 and are re-solved there. The sync chip wears these two on every page.
151
155
  info: {
152
- quiet: "text-placeholder hover:bg-info-soft hover:text-info focus-visible:ring-[var(--info-border)]",
153
- toned: "text-info hover:bg-info-soft focus-visible:ring-[var(--info-border)]",
156
+ quiet: "text-placeholder hover:bg-info-soft hover:text-info focus-visible:ring-[var(--info)]",
157
+ toned: "text-info hover:bg-info-soft focus-visible:ring-[var(--info)]",
154
158
  },
155
159
  success: {
156
- quiet: "text-placeholder hover:bg-success-soft hover:text-success focus-visible:ring-[var(--success-border)]",
157
- toned: "text-success hover:bg-success-soft focus-visible:ring-[var(--success-border)]",
160
+ quiet: "text-placeholder hover:bg-success-soft hover:text-success focus-visible:ring-[var(--success)]",
161
+ toned: "text-success hover:bg-success-soft focus-visible:ring-[var(--success)]",
158
162
  },
159
- // The hover fill and the ring are MIXED from the one colour, since a custom tone
160
- // brings no `-bg` / `-border` pair of its own. The fallback is the body colour, so a
161
- // `custom` tone with no colour set is the default look rather than invisible.
163
+ // The hover fill is MIXED from the one colour, since a custom tone brings no `-bg` of
164
+ // its own; the ring is the colour at full strength (0.52, DSP-6: at 40 % it was a ring
165
+ // nobody could see). The fallback is the body colour, so a `custom` tone with no colour
166
+ // set is the default look rather than invisible.
162
167
  custom: {
163
168
  quiet:
164
- "text-placeholder hover:bg-[color-mix(in_srgb,var(--icon-button-tone,var(--text-primary))_12%,transparent)] hover:text-[var(--icon-button-tone,var(--text-primary))] focus-visible:ring-[color-mix(in_srgb,var(--icon-button-tone,var(--text-primary))_40%,transparent)]",
169
+ "text-placeholder hover:bg-[color-mix(in_srgb,var(--icon-button-tone,var(--text-primary))_12%,transparent)] hover:text-[var(--icon-button-tone,var(--text-primary))] focus-visible:ring-[var(--icon-button-tone,var(--text-primary))]",
165
170
  toned:
166
- "text-[var(--icon-button-tone,var(--text-primary))] hover:bg-[color-mix(in_srgb,var(--icon-button-tone,var(--text-primary))_12%,transparent)] focus-visible:ring-[color-mix(in_srgb,var(--icon-button-tone,var(--text-primary))_40%,transparent)]",
171
+ "text-[var(--icon-button-tone,var(--text-primary))] hover:bg-[color-mix(in_srgb,var(--icon-button-tone,var(--text-primary))_12%,transparent)] focus-visible:ring-[var(--icon-button-tone,var(--text-primary))]",
167
172
  },
168
173
  };
169
174