@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,6 +1,6 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
2
2
  import { readStored, removeStored, writeStored } from "../lib/safe-storage";
3
- import { httpStatusOf } from "../auth/auth-errors";
3
+ import { httpStatusOf } from "../lib/http-status";
4
4
  import { isTourDone, type TourCompletions } from "./tour-info";
5
5
 
6
6
  /**
@@ -35,8 +35,10 @@ import { useTourGateRelease } from "../tour/tour-gates";
35
35
  * `onDone` — are all set on `useWizard`. What is set HERE is how the Finish button
36
36
  * looks and what wraps it, because that is presentation and usually depends on
37
37
  * state the app holds (a "replace everything" toggle, a write lock — `finishCommit`).
38
+ *
39
+ * `TData`'s constraint is `UseWizardOptions`' (its mapped half is for `Parameters<>`).
38
40
  */
39
- export function StepperNav<TData extends Record<string, unknown>>({
41
+ export function StepperNav<TData extends object & { [K in keyof TData]: unknown }>({
40
42
  wizard,
41
43
  children,
42
44
  title,
@@ -61,7 +61,16 @@ export interface WizardStepConfig {
61
61
  */
62
62
  export type WizardUrlSync = boolean | { param?: string };
63
63
 
64
- export interface UseWizardOptions<TData extends Record<string, unknown>> {
64
+ // `TData extends object`, not `Record<string, unknown>` (0.52, API-2, refactor audit
65
+ // 2026-10-30): an `interface` has no index signature and failed the old constraint, so
66
+ // kastlan gave 13 wizard data interfaces one — which made every key legal, a misspelt one
67
+ // in `updateData` included. The wizard reads only `keyof TData`.
68
+ // The mapped half constrains nothing (every object type satisfies it): it is there for
69
+ // `Parameters<typeof useWizard>` / `ReturnType<typeof useWizard>`, which read the
70
+ // constraint, and `object` has no keys — a wrapper's `data.amount` stopped type-checking
71
+ // (0.52 code review). With it they read an indexable record, as under 0.51. The same on
72
+ // `UseWizardReturn`, `useWizard`, `StepperNav` and `requiredFieldsValidator`.
73
+ export interface UseWizardOptions<TData extends object & { [K in keyof TData]: unknown }> {
65
74
  steps: WizardStepConfig[];
66
75
  initialData?: Partial<TData>;
67
76
  onComplete?: (data: TData) => void | Promise<void>;
@@ -125,7 +134,7 @@ export interface WizardFinishResult {
125
134
  ok: boolean;
126
135
  error?: string;
127
136
  }
128
- export interface UseWizardReturn<TData extends Record<string, unknown>> {
137
+ export interface UseWizardReturn<TData extends object & { [K in keyof TData]: unknown }> {
129
138
  // Navigation
130
139
  currentStepIndex: number;
131
140
  currentStep: WizardStepConfig;
@@ -142,7 +142,8 @@ function createReducer<TData>(stepCount: number) {
142
142
  };
143
143
  }
144
144
 
145
- export function useWizard<TData extends Record<string, unknown>>(
145
+ // The constraint's mapped half: see `UseWizardOptions` (Parameters<> and ReturnType<> read it).
146
+ export function useWizard<TData extends object & { [K in keyof TData]: unknown }>(
146
147
  options: UseWizardOptions<TData>,
147
148
  ): UseWizardReturn<TData> {
148
149
  const {
@@ -18,9 +18,15 @@ export interface RequiredFieldSpec<T> {
18
18
  * rate in range) pass a `valid` predicate. The message is caller-supplied so
19
19
  * each page keeps its own namespace (e.g. `t("common:validation.required")`).
20
20
  */
21
- export function requiredFieldsValidator<T extends Record<string, unknown>>(
21
+ // `T extends object` (0.52, API-2) so a wizard's data may be an interface. The mapped half
22
+ // constrains nothing (every object type satisfies it): it is there for
23
+ // `Parameters<typeof requiredFieldsValidator>`, which reads the constraint — `keyof object`
24
+ // is `never`, so a wrapper typed that way refused every `{ key }` (0.52 code review). With
25
+ // it the constraint reads as an indexable record, as 0.51's `Record<string, unknown>` did.
26
+ export function requiredFieldsValidator<T extends object & { [K in keyof T]: unknown }>(
22
27
  data: T,
23
- fields: RequiredFieldSpec<T>[],
28
+ // `readonly` (0.52, API-7): a field list held `as const` passes without a copy.
29
+ fields: readonly RequiredFieldSpec<T>[],
24
30
  defaultMessage: string,
25
31
  ): ValidateResult {
26
32
  const errors: FieldErrors = {};
package/tokens.css CHANGED
@@ -397,13 +397,13 @@ html[data-text-size="xlarge"] {
397
397
  was: beside red-700 that orange read as a second error colour, and "unsaved" has
398
398
  to look like a caution, not an alarm. Light, it is amber-600's hue and chroma at a
399
399
  SOLVED lightness (3.1:1 on the worst surface). Below 4.5:1, so it is not a TEXT
400
- colour: `FieldSyncIndicator` prints its words in `--text-secondary` beside it.
400
+ colour: a state's words go in `--text-secondary` beside it.
401
401
 
402
402
  GREEN AND RED ARE THE CLASSIC CVD-UNSAFE PAIR, and the rest of this file goes out
403
403
  of its way to avoid it — the money trio is teal/amber/violet for exactly this
404
404
  reason. They are used here because the states were specified in these colours, so
405
- `FieldSyncIndicator` gives every state its own ICON as well and colour is never
406
- the only signal. Do not drop the icons. */
405
+ every state needs its own ICON as well and colour is never the only signal (as
406
+ FieldSyncIndicator, which drew them until 0.53, gave it). Do not drop the icons. */
407
407
  --status-synced: #166534; /* green-800 — persisted */
408
408
  --status-pending: #1d4ed8; /* blue-700 — in flight */
409
409
  --status-edited: #bf6800; /* solved — dirty, not yet saved */
@@ -871,7 +871,7 @@ html[data-text-size="xlarge"] {
871
871
  * counts a `[var(--role)]` class, and a `ring-[length:var(--…)]` width, for any token that
872
872
  * has a utility here and allows none (`ROLE_BUDGET` 0). What stays `[var()]` has no
873
873
  * utility on purpose: the chart colours (lookup tables of `--chart-N`), `--status-*`
874
- * (FieldSync's own four), and the cross-property one-offs (`bg-[var(--border)]` as a
874
+ * (the field-sync four), and the cross-property one-offs (`bg-[var(--border)]` as a
875
875
  * divider, `ring-[var(--text-primary)]`) — a utility there would undo the property
876
876
  * scoping above. `check:tailwind` asserts one per namespace survives a build, and the
877
877
  * README's "Styling" table is generated from this block (`scripts/gen-styling-inventory.mjs`).
@@ -1109,7 +1109,8 @@ body,
1109
1109
  fresh-start checkbox (feedback #264). */
1110
1110
  @layer base {
1111
1111
  :where(input[type="checkbox"], input[type="radio"]) {
1112
- accent-color: var(--brand); /* unified indigo brand accent (theme-aware) */
1112
+ /* The brand of the active preset or the app (indigo only in the default), theme-aware. */
1113
+ accent-color: var(--brand);
1113
1114
  }
1114
1115
  }
1115
1116
 
@@ -1,2 +0,0 @@
1
- import type { FieldSyncLabels } from "./field-sync.js";
2
- export declare const DEFAULT_FIELD_SYNC_LABELS: FieldSyncLabels;
@@ -1,12 +0,0 @@
1
- "use client";
2
- const DEFAULT_FIELD_SYNC_LABELS = {
3
- synced: "Saved",
4
- edited: "Unsaved changes",
5
- pending: "Saving\u2026",
6
- error: "Could not save",
7
- retry: "Retry"
8
- };
9
- export {
10
- DEFAULT_FIELD_SYNC_LABELS
11
- };
12
- //# sourceMappingURL=field-sync-labels.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/field-sync-labels.ts"],"sourcesContent":["// The English words of ./field-sync, in a module with no component code: the English\n// catalogue (src/i18n/defaults.ts) imports them without the component, so `en` loads as one\n// chunk like the other languages (0.34, KS U8). ./field-sync re-exports them.\n\nimport type { FieldSyncLabels } from \"./field-sync\";\n\nexport const DEFAULT_FIELD_SYNC_LABELS: FieldSyncLabels = {\n synced: \"Saved\",\n edited: \"Unsaved changes\",\n pending: \"Saving…\",\n error: \"Could not save\",\n retry: \"Retry\",\n};\n"],"mappings":";AAMO,MAAM,4BAA6C;AAAA,EACxD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AACT;","names":[]}
@@ -1,164 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import { type LabelOverride } from "../i18n/kit-labels.js";
3
- import { DEFAULT_FIELD_SYNC_LABELS } from "./field-sync-labels.js";
4
- /**
5
- * Sync state for a field backed by a database row.
6
- *
7
- * The four states a value can be in between the keyboard and the server:
8
- *
9
- * synced the draft equals what was last persisted
10
- * edited the draft differs and nothing has been sent yet
11
- * pending a save is in flight
12
- * error the last save was rejected; `error` carries why
13
- *
14
- * `useFieldSync` is the engine and holds no opinion about markup;
15
- * `FieldSyncIndicator` is the affordance and holds no state. They are separate
16
- * because the state is useful without the dot — a form can disable its submit
17
- * button while any field is `pending`, and a router can block navigation while
18
- * any field is `edited`.
19
- */
20
- export type FieldSyncState = "synced" | "edited" | "pending" | "error";
21
- export interface FieldSyncLabels {
22
- synced: string;
23
- edited: string;
24
- pending: string;
25
- /** Shown when the failure carries no message of its own. */
26
- error: string;
27
- retry: string;
28
- }
29
- export { DEFAULT_FIELD_SYNC_LABELS };
30
- export interface UseFieldSyncOptions<T> {
31
- /** What the database currently holds. Changing it re-seeds a CLEAN field. */
32
- value: T;
33
- /** Persist `next`. Reject — or throw — to put the field in `error`. */
34
- onSave: (next: T) => Promise<void> | void;
35
- /**
36
- * Quiet period before an edit saves itself, in ms. Default `0`: no auto-save at
37
- * all, so `save()` is the only way to persist — called on blur by `FieldSyncRow`,
38
- * and on Enter by the caller. Saving after a pause in typing wrote half-finished
39
- * values to the database whenever somebody stopped to think; pass a positive
40
- * number only for a field where that is genuinely wanted.
41
- */
42
- debounceMs?: number;
43
- /** How to tell two values apart. Defaults to `Object.is`. */
44
- equals?: (a: T, b: T) => boolean;
45
- /** Called once per rejected save, with whatever `onSave` threw. */
46
- onError?: (error: Error) => void;
47
- }
48
- export interface UseFieldSyncReturn<T> {
49
- /** The draft — bind this to the input, not the `value` option. */
50
- value: T;
51
- setValue: (next: T) => void;
52
- state: FieldSyncState;
53
- /** Non-null exactly when `state === "error"`. */
54
- error: Error | null;
55
- /** True whenever the draft differs from the last persisted value. */
56
- dirty: boolean;
57
- /** Persist now, cancelling any pending debounce. A no-op on a clean field. */
58
- save: () => void;
59
- /** Send the current draft again after a failure. */
60
- retry: () => void;
61
- /** Throw the draft away and go back to the last persisted value. */
62
- reset: () => void;
63
- }
64
- /**
65
- * Track one database-backed field: a local draft, a debounced save, and the state
66
- * of the round trip.
67
- *
68
- * Four things this handles that a `useState` + `useEffect` in a page does not:
69
- *
70
- * 1. **An edit during a save is never lost.** A save in flight is not cancelled
71
- * and not raced — when it settles, the draft is compared again and sent once
72
- * more if it moved. Cancelling instead would drop a keystroke that arrived
73
- * mid-flight; firing immediately would let two writes land out of order.
74
- * 2. **The server value is only adopted when the field is clean.** An external
75
- * refresh that overwrote what somebody was typing would be a data-loss bug, so
76
- * a dirty draft wins and keeps winning until it is saved or reset.
77
- * 3. **Nothing is set after unmount.** The save resolves into a component that
78
- * may be gone — a row scrolled out of a virtualised table, a closed dialog.
79
- * 4. **`onSave` is read through a ref**, so an inline arrow — which every call
80
- * site will pass — does not restart the debounce on every render.
81
- */
82
- export declare function useFieldSync<T>({ value, onSave, debounceMs, equals, onError, }: UseFieldSyncOptions<T>): UseFieldSyncReturn<T>;
83
- export interface FieldSyncIndicatorProps {
84
- state: FieldSyncState;
85
- /** The failure. Its message becomes the tooltip when `state === "error"`. */
86
- error?: Error | null;
87
- /** Override any of the five English defaults. */
88
- labels?: LabelOverride<FieldSyncLabels>;
89
- /** Render the label beside the icon instead of only in the tooltip. Always on at
90
- * Large and Extra large (0.32, docs/text-size-harmonization.md §4 "No fact only in a
91
- * tooltip"): the reader who asked for bigger type gets the words, not a 14 px glyph
92
- * and a bubble. */
93
- showLabel?: boolean;
94
- /** When given, the error state renders a retry button after the icon. */
95
- onRetry?: () => void;
96
- className?: string;
97
- }
98
- /**
99
- * The affordance for {@link useFieldSync}: a coloured icon, and the reason on hover.
100
- *
101
- * **Every state has its own icon, and that is not decoration.** The four colours
102
- * include the green/red pair, which is the one combination this package's palette
103
- * otherwise refuses (see the note in `tokens.css`) because red-green colour blindness
104
- * affects roughly one man in twelve. The icon is what carries the meaning for them,
105
- * and what carries it into a greyscale print or a screenshot. WCAG 1.4.1 is the same
106
- * requirement stated formally.
107
- *
108
- * The state is also announced: the wrapper is a polite live region, so a screen
109
- * reader hears "Saving…" then "Saved" without the user going looking. `error` is
110
- * assertive instead — a failed write is worth interrupting for.
111
- */
112
- export declare function FieldSyncIndicator({ state, error, labels, showLabel, onRetry, className, }: FieldSyncIndicatorProps): import("react").JSX.Element;
113
- /**
114
- * The field's own frame, coloured by state — applied from the WRAPPER to whatever
115
- * native control sits inside it, so {@link FieldSyncRow} works with any of the kit's
116
- * inputs (and a caller's own) without each one growing a `syncState` prop.
117
- *
118
- * Border AND a 1px ring, for the reason {@link FIELD_INVALID} gives: a lone 1px
119
- * border loses a vertical edge to sub-pixel spread at 125% display scaling. The
120
- * `:focus` twins are what keep the state visible while the reader is typing —
121
- * the base field class's `focus:` brand colour is `(0,2,0)` and would otherwise win
122
- * over a descendant selector exactly when the field is in use.
123
- *
124
- * `synced` is green, but {@link FieldSyncRow} paints it only for a moment after a
125
- * save lands — a form of eight permanently green boxes says nothing the absence of
126
- * colour does not.
127
- *
128
- * Every class is a literal so Tailwind's scanner can see it.
129
- */
130
- export declare const FIELD_SYNC_FRAME: Record<FieldSyncState, string>;
131
- /** How long the green "saved" frame and check stay after a save lands, in ms. */
132
- export declare const FIELD_SYNC_SAVED_MS = 1500;
133
- export interface FieldSyncRowProps<T> extends Omit<FieldSyncIndicatorProps, "state" | "error" | "showLabel"> {
134
- sync: UseFieldSyncReturn<T>;
135
- children: ReactNode;
136
- /** Call `sync.save()` when focus leaves the field. Default true — together with the
137
- * hook's default `debounceMs: 0` this is "save on blur": nothing is written while
138
- * the reader is still typing, however long they pause. */
139
- saveOnBlur?: boolean;
140
- /** How long the saved confirmation shows. Default {@link FIELD_SYNC_SAVED_MS}. */
141
- savedMs?: number;
142
- }
143
- /**
144
- * A field wearing its sync state — as its FRAME COLOUR and an ICON AT THE END OF THE
145
- * FIELD, so the field never changes size (a helper line appearing under it moved
146
- * everything below it on every save):
147
- *
148
- * edited amber frame, pencil — changed, not yet saved
149
- * pending blue frame, spinning circle — for as long as the save is in flight
150
- * synced green frame, check — for {@link FIELD_SYNC_SAVED_MS} after a
151
- * save lands, then an ordinary field again
152
- * error red frame, alert mark — hover or focus the mark for the reason;
153
- * click it to retry
154
- *
155
- * It saves when focus LEAVES the field (`saveOnBlur`), not after a pause in typing: a
156
- * database write in the middle of a word is a write nobody asked for. Enter in a
157
- * single-line field is the caller's to wire to `sync.save`.
158
- *
159
- * Colour is never the only signal: every state has its own icon, and the state text is
160
- * always in the DOM as a live region — polite for the ordinary states, assertive for
161
- * a failure. The input gets end padding for the icon whether or not one is showing,
162
- * so the text never reflows when the state changes.
163
- */
164
- export declare function FieldSyncRow<T>({ sync, children, className, labels, onRetry, saveOnBlur, savedMs, }: FieldSyncRowProps<T>): import("react").JSX.Element;
@@ -1,269 +0,0 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useRef, useState } from "react";
4
- import { AlertCircle, Check, Loader2, Pencil, PencilLine } from "lucide-react";
5
- import { cn } from "../lib/cn.js";
6
- import { Tooltip } from "./tooltip.js";
7
- import { FOCUS_RING } from "./focus-ring.js";
8
- import { useKitLabels } from "../i18n/kit-labels.js";
9
- import { useLargeText } from "../hooks/use-large-text.js";
10
- import { DEFAULT_FIELD_SYNC_LABELS } from "./field-sync-labels.js";
11
- function toError(cause) {
12
- if (cause instanceof Error) return cause;
13
- return new Error(typeof cause === "string" ? cause : "", { cause });
14
- }
15
- function useFieldSync({
16
- value,
17
- onSave,
18
- debounceMs = 0,
19
- equals = Object.is,
20
- onError
21
- }) {
22
- const [draft, setDraft] = useState(value);
23
- const [state, setState] = useState("synced");
24
- const [error, setError] = useState(null);
25
- const savedRef = useRef(value);
26
- const draftRef = useRef(value);
27
- const inFlightRef = useRef(false);
28
- const timerRef = useRef(null);
29
- const mountedRef = useRef(true);
30
- const onSaveRef = useRef(onSave);
31
- const onErrorRef = useRef(onError);
32
- const equalsRef = useRef(equals);
33
- useEffect(() => {
34
- onSaveRef.current = onSave;
35
- onErrorRef.current = onError;
36
- equalsRef.current = equals;
37
- });
38
- useEffect(() => {
39
- mountedRef.current = true;
40
- return () => {
41
- mountedRef.current = false;
42
- if (timerRef.current) clearTimeout(timerRef.current);
43
- };
44
- }, []);
45
- const flush = useCallback(() => {
46
- const run = async () => {
47
- if (inFlightRef.current) return;
48
- const next = draftRef.current;
49
- if (equalsRef.current(next, savedRef.current)) return;
50
- inFlightRef.current = true;
51
- setState("pending");
52
- setError(null);
53
- try {
54
- await onSaveRef.current(next);
55
- savedRef.current = next;
56
- inFlightRef.current = false;
57
- if (!mountedRef.current) return;
58
- if (equalsRef.current(draftRef.current, next)) {
59
- setState("synced");
60
- } else {
61
- setState("edited");
62
- void run();
63
- }
64
- } catch (cause) {
65
- inFlightRef.current = false;
66
- const err = toError(cause);
67
- onErrorRef.current?.(err);
68
- if (!mountedRef.current) return;
69
- setState("error");
70
- setError(err);
71
- }
72
- };
73
- return run();
74
- }, []);
75
- const setValue = useCallback(
76
- (next) => {
77
- draftRef.current = next;
78
- setDraft(next);
79
- if (timerRef.current) clearTimeout(timerRef.current);
80
- if (equalsRef.current(next, savedRef.current)) {
81
- setState(inFlightRef.current ? "pending" : "synced");
82
- setError(null);
83
- return;
84
- }
85
- setState("edited");
86
- setError(null);
87
- if (debounceMs > 0) timerRef.current = setTimeout(() => void flush(), debounceMs);
88
- },
89
- [debounceMs, flush]
90
- );
91
- const save = useCallback(() => {
92
- if (timerRef.current) clearTimeout(timerRef.current);
93
- void flush();
94
- }, [flush]);
95
- const retry = save;
96
- const reset = useCallback(() => {
97
- if (timerRef.current) clearTimeout(timerRef.current);
98
- draftRef.current = savedRef.current;
99
- setDraft(savedRef.current);
100
- setState(inFlightRef.current ? "pending" : "synced");
101
- setError(null);
102
- }, []);
103
- const dirty = state !== "synced";
104
- useEffect(() => {
105
- if (inFlightRef.current) return;
106
- if (!equalsRef.current(draftRef.current, savedRef.current)) return;
107
- if (equalsRef.current(value, savedRef.current)) return;
108
- savedRef.current = value;
109
- draftRef.current = value;
110
- setDraft(value);
111
- setState("synced");
112
- setError(null);
113
- }, [value]);
114
- return { value: draft, setValue, state, error, dirty, save, retry, reset };
115
- }
116
- const STATE_STYLE = {
117
- synced: { color: "var(--status-synced)", Icon: Check },
118
- edited: { color: "var(--status-edited)", Icon: Pencil },
119
- pending: { color: "var(--status-pending)", Icon: Loader2 },
120
- error: { color: "var(--status-error)", Icon: AlertCircle }
121
- };
122
- function FieldSyncIndicator({
123
- state,
124
- error,
125
- labels,
126
- showLabel = false,
127
- onRetry,
128
- className
129
- }) {
130
- const l = useKitLabels("fieldSync", DEFAULT_FIELD_SYNC_LABELS, labels);
131
- const large = useLargeText();
132
- showLabel = showLabel || large;
133
- const { color, Icon } = STATE_STYLE[state];
134
- const text = state === "error" ? error?.message?.trim() ? error.message : l.error : l[state];
135
- return /* @__PURE__ */ jsxs(
136
- "span",
137
- {
138
- className: cn("inline-flex items-center gap-1.5 text-xs text-secondary", className),
139
- role: state === "error" ? "alert" : "status",
140
- "aria-live": state === "error" ? "assertive" : "polite",
141
- children: [
142
- /* @__PURE__ */ jsx(Tooltip, { label: showLabel ? void 0 : text, redact: state === "error", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
143
- /* @__PURE__ */ jsx(
144
- Icon,
145
- {
146
- "aria-hidden": true,
147
- style: { color },
148
- className: cn("size-3.5 shrink-0", state === "pending" && "animate-spin")
149
- }
150
- ),
151
- /* @__PURE__ */ jsx("span", { className: showLabel ? void 0 : "sr-only", children: text })
152
- ] }) }),
153
- state === "error" && onRetry && /* @__PURE__ */ jsx(
154
- "button",
155
- {
156
- type: "button",
157
- onClick: onRetry,
158
- className: cn(
159
- "rounded underline underline-offset-2 hover:no-underline focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
160
- FOCUS_RING
161
- ),
162
- style: { color },
163
- children: l.retry
164
- }
165
- )
166
- ]
167
- }
168
- );
169
- }
170
- const FIELD_SYNC_FRAME = {
171
- synced: "[&_:is(input,select,textarea)]:border-[var(--status-synced)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-synced)] [&_:is(input,select,textarea):focus]:border-[var(--status-synced)] [&_:is(input,select,textarea):focus]:ring-[var(--status-synced)]",
172
- edited: "[&_:is(input,select,textarea)]:border-[var(--status-edited)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-edited)] [&_:is(input,select,textarea):focus]:border-[var(--status-edited)] [&_:is(input,select,textarea):focus]:ring-[var(--status-edited)]",
173
- pending: "[&_:is(input,select,textarea)]:border-[var(--status-pending)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-pending)] [&_:is(input,select,textarea):focus]:border-[var(--status-pending)] [&_:is(input,select,textarea):focus]:ring-[var(--status-pending)]",
174
- error: "[&_:is(input,select,textarea)]:border-[var(--status-error)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-error)] [&_:is(input,select,textarea):focus]:border-[var(--status-error)] [&_:is(input,select,textarea):focus]:ring-[var(--status-error)]"
175
- };
176
- const FIELD_SYNC_SAVED_MS = 1500;
177
- function FieldSyncRow({
178
- sync,
179
- children,
180
- className,
181
- labels,
182
- onRetry,
183
- saveOnBlur = true,
184
- savedMs = FIELD_SYNC_SAVED_MS
185
- }) {
186
- const l = useKitLabels("fieldSync", DEFAULT_FIELD_SYNC_LABELS, labels);
187
- const { state, error } = sync;
188
- const isError = state === "error";
189
- const text = isError ? error?.message?.trim() ? error.message : l.error : l[state];
190
- const retry = onRetry ?? sync.retry;
191
- const [previous, setPrevious] = useState(state);
192
- const [justSaved, setJustSaved] = useState(false);
193
- if (state !== previous) {
194
- setPrevious(state);
195
- setJustSaved(state === "synced" && previous === "pending");
196
- }
197
- useEffect(() => {
198
- if (!justSaved) return;
199
- const t = setTimeout(() => setJustSaved(false), savedMs);
200
- return () => clearTimeout(t);
201
- }, [justSaved, savedMs]);
202
- const shown = state === "synced" ? justSaved ? "synced" : null : state;
203
- return (
204
- /* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- not an interaction:
205
- `onBlur` listens for focus leaving the row's own controls (which are the
206
- interactive elements) to save; the wrapper itself is never focused. */
207
- /* @__PURE__ */ jsxs(
208
- "div",
209
- {
210
- "data-field-sync": state,
211
- className: cn(
212
- // `relative` for the icon and for the sr-only live region's containing block.
213
- "relative [&_:is(input,select,textarea)]:pe-9",
214
- shown && FIELD_SYNC_FRAME[shown],
215
- className
216
- ),
217
- onBlur: saveOnBlur ? (e) => {
218
- if (!e.currentTarget.contains(e.relatedTarget)) sync.save();
219
- } : void 0,
220
- children: [
221
- children,
222
- /* @__PURE__ */ jsxs("span", { className: "pointer-events-none absolute inset-y-0 end-0 flex items-center pe-3", children: [
223
- state === "edited" && /* @__PURE__ */ jsx(PencilLine, { "aria-hidden": true, className: "size-4 text-[var(--status-edited)]" }),
224
- state === "pending" && /* @__PURE__ */ jsx(
225
- Loader2,
226
- {
227
- "aria-hidden": true,
228
- className: "size-4 animate-spin text-[var(--status-pending)] motion-reduce:animate-none"
229
- }
230
- ),
231
- state === "synced" && /* @__PURE__ */ jsx(
232
- Check,
233
- {
234
- "aria-hidden": true,
235
- className: cn(
236
- "size-4 text-[var(--status-synced)] transition-opacity duration-500 motion-reduce:transition-none",
237
- justSaved ? "opacity-100" : "opacity-0"
238
- )
239
- }
240
- ),
241
- isError && /* @__PURE__ */ jsx(Tooltip, { label: text, portal: true, redact: true, children: /* @__PURE__ */ jsx(
242
- "button",
243
- {
244
- type: "button",
245
- onClick: retry,
246
- "aria-label": l.retry,
247
- className: cn(
248
- "pointer-events-auto flex rounded-full text-[var(--status-error)] focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
249
- FOCUS_RING
250
- ),
251
- children: /* @__PURE__ */ jsx(AlertCircle, { "aria-hidden": true, className: "size-4" })
252
- }
253
- ) })
254
- ] }),
255
- /* @__PURE__ */ jsx("span", { role: isError ? "alert" : "status", "aria-live": isError ? "assertive" : "polite", className: "sr-only", children: shown === null ? "" : text })
256
- ]
257
- }
258
- )
259
- );
260
- }
261
- export {
262
- DEFAULT_FIELD_SYNC_LABELS,
263
- FIELD_SYNC_FRAME,
264
- FIELD_SYNC_SAVED_MS,
265
- FieldSyncIndicator,
266
- FieldSyncRow,
267
- useFieldSync
268
- };
269
- //# sourceMappingURL=field-sync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/field-sync.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { AlertCircle, Check, Loader2, Pencil, PencilLine } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { Tooltip } from \"./tooltip\";\nimport { FOCUS_RING } from \"./focus-ring\";\nimport { useKitLabels, type LabelOverride } from \"../i18n/kit-labels\";\nimport { useLargeText } from \"../hooks/use-large-text\";\nimport { DEFAULT_FIELD_SYNC_LABELS } from \"./field-sync-labels\";\n\n/**\n * Sync state for a field backed by a database row.\n *\n * The four states a value can be in between the keyboard and the server:\n *\n * synced the draft equals what was last persisted\n * edited the draft differs and nothing has been sent yet\n * pending a save is in flight\n * error the last save was rejected; `error` carries why\n *\n * `useFieldSync` is the engine and holds no opinion about markup;\n * `FieldSyncIndicator` is the affordance and holds no state. They are separate\n * because the state is useful without the dot — a form can disable its submit\n * button while any field is `pending`, and a router can block navigation while\n * any field is `edited`.\n */\nexport type FieldSyncState = \"synced\" | \"edited\" | \"pending\" | \"error\";\n\nexport interface FieldSyncLabels {\n synced: string;\n edited: string;\n pending: string;\n /** Shown when the failure carries no message of its own. */\n error: string;\n retry: string;\n}\n\n// Defined in ./field-sync-labels, which holds no component code (0.34, KS U8).\nexport { DEFAULT_FIELD_SYNC_LABELS };\n\nexport interface UseFieldSyncOptions<T> {\n /** What the database currently holds. Changing it re-seeds a CLEAN field. */\n value: T;\n /** Persist `next`. Reject — or throw — to put the field in `error`. */\n onSave: (next: T) => Promise<void> | void;\n /**\n * Quiet period before an edit saves itself, in ms. Default `0`: no auto-save at\n * all, so `save()` is the only way to persist — called on blur by `FieldSyncRow`,\n * and on Enter by the caller. Saving after a pause in typing wrote half-finished\n * values to the database whenever somebody stopped to think; pass a positive\n * number only for a field where that is genuinely wanted.\n */\n debounceMs?: number;\n /** How to tell two values apart. Defaults to `Object.is`. */\n equals?: (a: T, b: T) => boolean;\n /** Called once per rejected save, with whatever `onSave` threw. */\n onError?: (error: Error) => void;\n}\n\nexport interface UseFieldSyncReturn<T> {\n /** The draft — bind this to the input, not the `value` option. */\n value: T;\n setValue: (next: T) => void;\n state: FieldSyncState;\n /** Non-null exactly when `state === \"error\"`. */\n error: Error | null;\n /** True whenever the draft differs from the last persisted value. */\n dirty: boolean;\n /** Persist now, cancelling any pending debounce. A no-op on a clean field. */\n save: () => void;\n /** Send the current draft again after a failure. */\n retry: () => void;\n /** Throw the draft away and go back to the last persisted value. */\n reset: () => void;\n}\n\nfunction toError(cause: unknown): Error {\n if (cause instanceof Error) return cause;\n // An EMPTY message for a rejection that carried none, not an English one: the\n // indicator shows `error.message` when there is one and the translated\n // `fieldSync.error` otherwise, so a fallback message here was an English sentence\n // that outranked the app's own translation. The original value stays on `cause`\n // for whoever logs it from `onError`.\n return new Error(typeof cause === \"string\" ? cause : \"\", { cause });\n}\n\n/**\n * Track one database-backed field: a local draft, a debounced save, and the state\n * of the round trip.\n *\n * Four things this handles that a `useState` + `useEffect` in a page does not:\n *\n * 1. **An edit during a save is never lost.** A save in flight is not cancelled\n * and not raced — when it settles, the draft is compared again and sent once\n * more if it moved. Cancelling instead would drop a keystroke that arrived\n * mid-flight; firing immediately would let two writes land out of order.\n * 2. **The server value is only adopted when the field is clean.** An external\n * refresh that overwrote what somebody was typing would be a data-loss bug, so\n * a dirty draft wins and keeps winning until it is saved or reset.\n * 3. **Nothing is set after unmount.** The save resolves into a component that\n * may be gone — a row scrolled out of a virtualised table, a closed dialog.\n * 4. **`onSave` is read through a ref**, so an inline arrow — which every call\n * site will pass — does not restart the debounce on every render.\n */\nexport function useFieldSync<T>({\n value,\n onSave,\n debounceMs = 0,\n equals = Object.is,\n onError,\n}: UseFieldSyncOptions<T>): UseFieldSyncReturn<T> {\n const [draft, setDraft] = useState<T>(value);\n const [state, setState] = useState<FieldSyncState>(\"synced\");\n const [error, setError] = useState<Error | null>(null);\n\n // The last value known to be on the server. Not state: it changes together with\n // `state` inside the save, and a second render for it would be a wasted one.\n const savedRef = useRef<T>(value);\n const draftRef = useRef<T>(value);\n const inFlightRef = useRef(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const mountedRef = useRef(true);\n\n // Latest-ref for the callbacks and comparators, so a caller passing inline\n // functions (all of them) does not invalidate the timer on every render.\n const onSaveRef = useRef(onSave);\n const onErrorRef = useRef(onError);\n const equalsRef = useRef(equals);\n useEffect(() => {\n onSaveRef.current = onSave;\n onErrorRef.current = onError;\n equalsRef.current = equals;\n });\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n if (timerRef.current) clearTimeout(timerRef.current);\n };\n }, []);\n\n // A named inner function so the settle path can start the next round by calling it\n // again; a `useCallback` cannot refer to its own binding while it is being built.\n const flush = useCallback(() => {\n const run = async (): Promise<void> => {\n if (inFlightRef.current) return; // the settle path below picks the new draft up\n const next = draftRef.current;\n if (equalsRef.current(next, savedRef.current)) return;\n\n inFlightRef.current = true;\n setState(\"pending\");\n setError(null);\n try {\n await onSaveRef.current(next);\n savedRef.current = next;\n inFlightRef.current = false;\n if (!mountedRef.current) return;\n // The draft may have moved while this was in the air. Compare against what is\n // on screen NOW, not against what was sent.\n if (equalsRef.current(draftRef.current, next)) {\n setState(\"synced\");\n } else {\n setState(\"edited\");\n void run();\n }\n } catch (cause) {\n inFlightRef.current = false;\n const err = toError(cause);\n onErrorRef.current?.(err);\n if (!mountedRef.current) return;\n setState(\"error\");\n setError(err);\n }\n };\n return run();\n }, []);\n\n const setValue = useCallback(\n (next: T) => {\n draftRef.current = next;\n setDraft(next);\n if (timerRef.current) clearTimeout(timerRef.current);\n\n if (equalsRef.current(next, savedRef.current)) {\n // Typed back to what the server already has. Nothing to send, and an error\n // from the previous attempt no longer describes anything.\n setState(inFlightRef.current ? \"pending\" : \"synced\");\n setError(null);\n return;\n }\n\n setState(\"edited\");\n setError(null);\n if (debounceMs > 0) timerRef.current = setTimeout(() => void flush(), debounceMs);\n },\n [debounceMs, flush],\n );\n\n const save = useCallback(() => {\n if (timerRef.current) clearTimeout(timerRef.current);\n void flush();\n }, [flush]);\n\n const retry = save;\n\n const reset = useCallback(() => {\n if (timerRef.current) clearTimeout(timerRef.current);\n draftRef.current = savedRef.current;\n setDraft(savedRef.current);\n setState(inFlightRef.current ? \"pending\" : \"synced\");\n setError(null);\n }, []);\n\n // Anything that is not `synced` has something not yet on the server: `edited` and\n // `error` obviously, and `pending` too — the write is in the air, not landed.\n // Derived from state rather than by comparing against `savedRef` during render,\n // because a ref read here would not re-render when the comparison's answer changes.\n const dirty = state !== \"synced\";\n\n // Adopt a new server value ONLY when there is nothing local to lose.\n useEffect(() => {\n if (inFlightRef.current) return;\n if (!equalsRef.current(draftRef.current, savedRef.current)) return; // dirty: keep it\n if (equalsRef.current(value, savedRef.current)) return; // unchanged\n savedRef.current = value;\n draftRef.current = value;\n setDraft(value);\n setState(\"synced\");\n setError(null);\n }, [value]);\n\n return { value: draft, setValue, state, error, dirty, save, retry, reset };\n}\n\nconst STATE_STYLE: Record<FieldSyncState, { color: string; Icon: typeof Check }> = {\n synced: { color: \"var(--status-synced)\", Icon: Check },\n edited: { color: \"var(--status-edited)\", Icon: Pencil },\n pending: { color: \"var(--status-pending)\", Icon: Loader2 },\n error: { color: \"var(--status-error)\", Icon: AlertCircle },\n};\n\nexport interface FieldSyncIndicatorProps {\n state: FieldSyncState;\n /** The failure. Its message becomes the tooltip when `state === \"error\"`. */\n error?: Error | null;\n /** Override any of the five English defaults. */\n labels?: LabelOverride<FieldSyncLabels>;\n /** Render the label beside the icon instead of only in the tooltip. Always on at\n * Large and Extra large (0.32, docs/text-size-harmonization.md §4 \"No fact only in a\n * tooltip\"): the reader who asked for bigger type gets the words, not a 14 px glyph\n * and a bubble. */\n showLabel?: boolean;\n /** When given, the error state renders a retry button after the icon. */\n onRetry?: () => void;\n className?: string;\n}\n\n/**\n * The affordance for {@link useFieldSync}: a coloured icon, and the reason on hover.\n *\n * **Every state has its own icon, and that is not decoration.** The four colours\n * include the green/red pair, which is the one combination this package's palette\n * otherwise refuses (see the note in `tokens.css`) because red-green colour blindness\n * affects roughly one man in twelve. The icon is what carries the meaning for them,\n * and what carries it into a greyscale print or a screenshot. WCAG 1.4.1 is the same\n * requirement stated formally.\n *\n * The state is also announced: the wrapper is a polite live region, so a screen\n * reader hears \"Saving…\" then \"Saved\" without the user going looking. `error` is\n * assertive instead — a failed write is worth interrupting for.\n */\nexport function FieldSyncIndicator({\n state,\n error,\n labels,\n showLabel = false,\n onRetry,\n className,\n}: FieldSyncIndicatorProps) {\n const l = useKitLabels(\"fieldSync\", DEFAULT_FIELD_SYNC_LABELS, labels);\n const large = useLargeText();\n showLabel = showLabel || large;\n const { color, Icon } = STATE_STYLE[state];\n const text = state === \"error\" ? (error?.message?.trim() ? error.message : l.error) : l[state];\n\n return (\n <span\n // The ICON carries the status colour; the words are `--text-secondary`, because\n // the amber of `edited` is a graphic colour (3:1), not a text colour (4.5:1).\n className={cn(\"inline-flex items-center gap-1.5 text-xs text-secondary\", className)}\n // Polite for the three ordinary states so save chatter does not interrupt\n // typing; assertive for a failure, which the user has to know about now.\n role={state === \"error\" ? \"alert\" : \"status\"}\n aria-live={state === \"error\" ? \"assertive\" : \"polite\"}\n >\n <Tooltip label={showLabel ? undefined : text} redact={state === \"error\"}>\n <span className=\"inline-flex items-center gap-1.5\">\n <Icon\n aria-hidden\n style={{ color }}\n className={cn(\"size-3.5 shrink-0\", state === \"pending\" && \"animate-spin\")}\n />\n {/* Always in the DOM, so the live region has something to announce even\n when the label is visually a tooltip. */}\n <span className={showLabel ? undefined : \"sr-only\"}>{text}</span>\n </span>\n </Tooltip>\n {state === \"error\" && onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n // The kit's focus frame (0.32, §5), stood off the word.\n className={cn(\n \"rounded underline underline-offset-2 hover:no-underline focus-visible:ring-offset-2 focus-visible:ring-offset-surface\",\n FOCUS_RING,\n )}\n style={{ color }}\n >\n {l.retry}\n </button>\n )}\n </span>\n );\n}\n\n/**\n * The field's own frame, coloured by state — applied from the WRAPPER to whatever\n * native control sits inside it, so {@link FieldSyncRow} works with any of the kit's\n * inputs (and a caller's own) without each one growing a `syncState` prop.\n *\n * Border AND a 1px ring, for the reason {@link FIELD_INVALID} gives: a lone 1px\n * border loses a vertical edge to sub-pixel spread at 125% display scaling. The\n * `:focus` twins are what keep the state visible while the reader is typing —\n * the base field class's `focus:` brand colour is `(0,2,0)` and would otherwise win\n * over a descendant selector exactly when the field is in use.\n *\n * `synced` is green, but {@link FieldSyncRow} paints it only for a moment after a\n * save lands — a form of eight permanently green boxes says nothing the absence of\n * colour does not.\n *\n * Every class is a literal so Tailwind's scanner can see it.\n */\nexport const FIELD_SYNC_FRAME: Record<FieldSyncState, string> = {\n synced:\n \"[&_:is(input,select,textarea)]:border-[var(--status-synced)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-synced)] [&_:is(input,select,textarea):focus]:border-[var(--status-synced)] [&_:is(input,select,textarea):focus]:ring-[var(--status-synced)]\",\n edited:\n \"[&_:is(input,select,textarea)]:border-[var(--status-edited)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-edited)] [&_:is(input,select,textarea):focus]:border-[var(--status-edited)] [&_:is(input,select,textarea):focus]:ring-[var(--status-edited)]\",\n pending:\n \"[&_:is(input,select,textarea)]:border-[var(--status-pending)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-pending)] [&_:is(input,select,textarea):focus]:border-[var(--status-pending)] [&_:is(input,select,textarea):focus]:ring-[var(--status-pending)]\",\n error:\n \"[&_:is(input,select,textarea)]:border-[var(--status-error)] [&_:is(input,select,textarea)]:ring-1 [&_:is(input,select,textarea)]:ring-[var(--status-error)] [&_:is(input,select,textarea):focus]:border-[var(--status-error)] [&_:is(input,select,textarea):focus]:ring-[var(--status-error)]\",\n};\n\n/** How long the green \"saved\" frame and check stay after a save lands, in ms. */\nexport const FIELD_SYNC_SAVED_MS = 1500;\n\nexport interface FieldSyncRowProps<T> extends Omit<FieldSyncIndicatorProps, \"state\" | \"error\" | \"showLabel\"> {\n sync: UseFieldSyncReturn<T>;\n children: ReactNode;\n /** Call `sync.save()` when focus leaves the field. Default true — together with the\n * hook's default `debounceMs: 0` this is \"save on blur\": nothing is written while\n * the reader is still typing, however long they pause. */\n saveOnBlur?: boolean;\n /** How long the saved confirmation shows. Default {@link FIELD_SYNC_SAVED_MS}. */\n savedMs?: number;\n}\n\n/**\n * A field wearing its sync state — as its FRAME COLOUR and an ICON AT THE END OF THE\n * FIELD, so the field never changes size (a helper line appearing under it moved\n * everything below it on every save):\n *\n * edited amber frame, pencil — changed, not yet saved\n * pending blue frame, spinning circle — for as long as the save is in flight\n * synced green frame, check — for {@link FIELD_SYNC_SAVED_MS} after a\n * save lands, then an ordinary field again\n * error red frame, alert mark — hover or focus the mark for the reason;\n * click it to retry\n *\n * It saves when focus LEAVES the field (`saveOnBlur`), not after a pause in typing: a\n * database write in the middle of a word is a write nobody asked for. Enter in a\n * single-line field is the caller's to wire to `sync.save`.\n *\n * Colour is never the only signal: every state has its own icon, and the state text is\n * always in the DOM as a live region — polite for the ordinary states, assertive for\n * a failure. The input gets end padding for the icon whether or not one is showing,\n * so the text never reflows when the state changes.\n */\nexport function FieldSyncRow<T>({\n sync,\n children,\n className,\n labels,\n onRetry,\n saveOnBlur = true,\n savedMs = FIELD_SYNC_SAVED_MS,\n}: FieldSyncRowProps<T>) {\n const l = useKitLabels(\"fieldSync\", DEFAULT_FIELD_SYNC_LABELS, labels);\n const { state, error } = sync;\n const isError = state === \"error\";\n const text = isError ? (error?.message?.trim() ? error.message : l.error) : l[state];\n const retry = onRetry ?? sync.retry;\n\n // The saved confirmation: on only for the moment after a save lands. Keyed on the\n // TRANSITION pending → synced, so a field that starts synced shows nothing. The\n // transition is seen while rendering, against the previous state; the effect only\n // owns the timer that turns it off again.\n const [previous, setPrevious] = useState(state);\n const [justSaved, setJustSaved] = useState(false);\n if (state !== previous) {\n setPrevious(state);\n setJustSaved(state === \"synced\" && previous === \"pending\");\n }\n useEffect(() => {\n if (!justSaved) return;\n const t = setTimeout(() => setJustSaved(false), savedMs);\n return () => clearTimeout(t);\n }, [justSaved, savedMs]);\n const shown: FieldSyncState | null = state === \"synced\" ? (justSaved ? \"synced\" : null) : state;\n\n return (\n /* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- not an interaction:\n `onBlur` listens for focus leaving the row's own controls (which are the\n interactive elements) to save; the wrapper itself is never focused. */\n <div\n data-field-sync={state}\n className={cn(\n // `relative` for the icon and for the sr-only live region's containing block.\n \"relative [&_:is(input,select,textarea)]:pe-9\",\n shown && FIELD_SYNC_FRAME[shown],\n className,\n )}\n onBlur={\n saveOnBlur\n ? (e) => {\n // Focus moving between two controls INSIDE the row is not leaving it.\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) sync.save();\n }\n : undefined\n }\n >\n {children}\n <span className=\"pointer-events-none absolute inset-y-0 end-0 flex items-center pe-3\">\n {state === \"edited\" && <PencilLine aria-hidden className=\"size-4 text-[var(--status-edited)]\" />}\n {state === \"pending\" && (\n <Loader2\n aria-hidden\n className=\"size-4 animate-spin text-[var(--status-pending)] motion-reduce:animate-none\"\n />\n )}\n {state === \"synced\" && (\n <Check\n aria-hidden\n className={cn(\n \"size-4 text-[var(--status-synced)] transition-opacity duration-500 motion-reduce:transition-none\",\n justSaved ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n )}\n {isError && (\n <Tooltip label={text} portal redact>\n <button\n type=\"button\"\n onClick={retry}\n aria-label={l.retry}\n className={cn(\n \"pointer-events-auto flex rounded-full text-[var(--status-error)] focus-visible:ring-offset-2 focus-visible:ring-offset-surface\",\n FOCUS_RING,\n )}\n >\n <AlertCircle aria-hidden className=\"size-4\" />\n </button>\n </Tooltip>\n )}\n </span>\n <span role={isError ? \"alert\" : \"status\"} aria-live={isError ? \"assertive\" : \"polite\"} className=\"sr-only\">\n {shown === null ? \"\" : text}\n </span>\n </div>\n );\n}\n"],"mappings":"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","names":[]}