@eifi1/ui-kit 0.51.7 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (746) hide show
  1. package/README.md +141 -23
  2. package/dist/account/account-parts.d.ts +10 -8
  3. package/dist/account/account-parts.js +1 -18
  4. package/dist/account/account-parts.js.map +1 -1
  5. package/dist/account/data-export-setting-labels.js +1 -1
  6. package/dist/account/data-export-setting-labels.js.map +1 -1
  7. package/dist/account/delete-account-setting-labels.js +1 -1
  8. package/dist/account/delete-account-setting-labels.js.map +1 -1
  9. package/dist/account/email-change-setting-labels.js +1 -1
  10. package/dist/account/email-change-setting-labels.js.map +1 -1
  11. package/dist/account/passkeys-setting.d.ts +9 -2
  12. package/dist/account/passkeys-setting.js +41 -29
  13. package/dist/account/passkeys-setting.js.map +1 -1
  14. package/dist/account/sessions-setting.d.ts +3 -2
  15. package/dist/account/sessions-setting.js +10 -8
  16. package/dist/account/sessions-setting.js.map +1 -1
  17. package/dist/admin/admin-action-confirm.js +1 -3
  18. package/dist/admin/admin-action-confirm.js.map +1 -1
  19. package/dist/admin/admin-parts.d.ts +6 -3
  20. package/dist/admin/admin-parts.js +6 -21
  21. package/dist/admin/admin-parts.js.map +1 -1
  22. package/dist/admin/mail-test-card-labels.js +1 -1
  23. package/dist/admin/mail-test-card-labels.js.map +1 -1
  24. package/dist/admin/plan-change-labels.d.ts +2 -2
  25. package/dist/admin/plan-change-labels.js +1 -17
  26. package/dist/admin/plan-change-labels.js.map +1 -1
  27. package/dist/admin/plan-change.d.ts +3 -42
  28. package/dist/admin/plan-change.js +1 -1
  29. package/dist/admin/plan-change.js.map +1 -1
  30. package/dist/admin/reviewer-scope-editor.js +3 -3
  31. package/dist/admin/reviewer-scope-editor.js.map +1 -1
  32. package/dist/auth/auth-errors-labels.d.ts +11 -0
  33. package/dist/auth/auth-errors-labels.js +13 -0
  34. package/dist/auth/auth-errors-labels.js.map +1 -0
  35. package/dist/auth/auth-errors.d.ts +7 -23
  36. package/dist/auth/auth-errors.js +2 -15
  37. package/dist/auth/auth-errors.js.map +1 -1
  38. package/dist/auth/complete-name-dialog.js +2 -1
  39. package/dist/auth/complete-name-dialog.js.map +1 -1
  40. package/dist/auth/forgot-password-form-labels.js +1 -1
  41. package/dist/auth/forgot-password-form-labels.js.map +1 -1
  42. package/dist/auth/forgot-password-form.js +7 -2
  43. package/dist/auth/forgot-password-form.js.map +1 -1
  44. package/dist/auth/register-form-labels.js +1 -1
  45. package/dist/auth/register-form-labels.js.map +1 -1
  46. package/dist/auth/reset-password-form-labels.js +1 -1
  47. package/dist/auth/reset-password-form-labels.js.map +1 -1
  48. package/dist/auth/reset-password-form.js +5 -1
  49. package/dist/auth/reset-password-form.js.map +1 -1
  50. package/dist/auth/sign-in-form-labels.js +1 -1
  51. package/dist/auth/sign-in-form-labels.js.map +1 -1
  52. package/dist/auth/status-parts.d.ts +0 -3
  53. package/dist/auth/status-parts.js +0 -4
  54. package/dist/auth/status-parts.js.map +1 -1
  55. package/dist/auth/verify-email-labels.js +1 -1
  56. package/dist/auth/verify-email-labels.js.map +1 -1
  57. package/dist/auth/verify-email.js +7 -2
  58. package/dist/auth/verify-email.js.map +1 -1
  59. package/dist/billing/cancel-subscription.d.ts +20 -8
  60. package/dist/billing/cancel-subscription.js +7 -5
  61. package/dist/billing/cancel-subscription.js.map +1 -1
  62. package/dist/billing/dialog-close.d.ts +29 -0
  63. package/dist/billing/dialog-close.js +8 -0
  64. package/dist/billing/dialog-close.js.map +1 -0
  65. package/dist/billing/plan-card.d.ts +14 -4
  66. package/dist/billing/plan-card.js +15 -8
  67. package/dist/billing/plan-card.js.map +1 -1
  68. package/dist/billing/plan-change-labels.d.ts +42 -0
  69. package/dist/billing/plan-change-labels.js +22 -0
  70. package/dist/billing/plan-change-labels.js.map +1 -0
  71. package/dist/billing/plan-switch.d.ts +19 -7
  72. package/dist/billing/plan-switch.js +8 -4
  73. package/dist/billing/plan-switch.js.map +1 -1
  74. package/dist/chart.d.ts +12 -0
  75. package/dist/chart.js +16 -1
  76. package/dist/chart.js.map +1 -1
  77. package/dist/components/account-chips.d.ts +5 -5
  78. package/dist/components/account-chips.js +11 -13
  79. package/dist/components/account-chips.js.map +1 -1
  80. package/dist/components/alert-banner.d.ts +16 -5
  81. package/dist/components/alert-banner.js +46 -1
  82. package/dist/components/alert-banner.js.map +1 -1
  83. package/dist/components/amount-input.d.ts +13 -0
  84. package/dist/components/amount-input.js +1 -0
  85. package/dist/components/amount-input.js.map +1 -1
  86. package/dist/components/autocomplete.js +57 -65
  87. package/dist/components/autocomplete.js.map +1 -1
  88. package/dist/components/bulk-action-bar.d.ts +12 -2
  89. package/dist/components/bulk-action-bar.js +65 -21
  90. package/dist/components/bulk-action-bar.js.map +1 -1
  91. package/dist/components/button-look.d.ts +5 -5
  92. package/dist/components/button-look.js.map +1 -1
  93. package/dist/components/button.d.ts +2 -2
  94. package/dist/components/button.js.map +1 -1
  95. package/dist/components/chart-edge.d.ts +16 -0
  96. package/dist/components/chart-edge.js +14 -1
  97. package/dist/components/chart-edge.js.map +1 -1
  98. package/dist/components/chart-figure.d.ts +13 -0
  99. package/dist/components/chart-figure.js +15 -0
  100. package/dist/components/chart-figure.js.map +1 -0
  101. package/dist/components/chart-zoom-core.js +1 -4
  102. package/dist/components/chart-zoom-core.js.map +1 -1
  103. package/dist/components/chart.d.ts +8 -1
  104. package/dist/components/chart.js +19 -10
  105. package/dist/components/chart.js.map +1 -1
  106. package/dist/components/combobox-core.d.ts +111 -2
  107. package/dist/components/combobox-core.js +148 -42
  108. package/dist/components/combobox-core.js.map +1 -1
  109. package/dist/components/combobox.d.ts +1 -1
  110. package/dist/components/combobox.js +141 -130
  111. package/dist/components/combobox.js.map +1 -1
  112. package/dist/components/copy-button.d.ts +6 -5
  113. package/dist/components/copy-button.js +5 -3
  114. package/dist/components/copy-button.js.map +1 -1
  115. package/dist/components/country-select.js +2 -2
  116. package/dist/components/country-select.js.map +1 -1
  117. package/dist/components/data-table-column-settings.d.ts +1 -1
  118. package/dist/components/data-table-column-settings.js +33 -7
  119. package/dist/components/data-table-column-settings.js.map +1 -1
  120. package/dist/components/data-table-filters.d.ts +4 -2
  121. package/dist/components/data-table-filters.js +2 -2
  122. package/dist/components/data-table-filters.js.map +1 -1
  123. package/dist/components/data-table-fit.d.ts +6 -4
  124. package/dist/components/data-table-fit.js +4 -1
  125. package/dist/components/data-table-fit.js.map +1 -1
  126. package/dist/components/data-table-groups.d.ts +1 -1
  127. package/dist/components/data-table-groups.js.map +1 -1
  128. package/dist/components/data-table-head.d.ts +1 -1
  129. package/dist/components/data-table-head.js +15 -12
  130. package/dist/components/data-table-head.js.map +1 -1
  131. package/dist/components/data-table-mobile.d.ts +12 -7
  132. package/dist/components/data-table-mobile.js +43 -30
  133. package/dist/components/data-table-mobile.js.map +1 -1
  134. package/dist/components/data-table-pagination.js +11 -6
  135. package/dist/components/data-table-pagination.js.map +1 -1
  136. package/dist/components/data-table-resize.d.ts +1 -1
  137. package/dist/components/data-table-resize.js.map +1 -1
  138. package/dist/components/data-table-row-actions.d.ts +2 -2
  139. package/dist/components/data-table-row-actions.js.map +1 -1
  140. package/dist/components/data-table-row.d.ts +6 -2
  141. package/dist/components/data-table-row.js +17 -10
  142. package/dist/components/data-table-row.js.map +1 -1
  143. package/dist/components/data-table-selection.d.ts +1 -1
  144. package/dist/components/data-table-selection.js.map +1 -1
  145. package/dist/components/data-table-shared.d.ts +10 -2
  146. package/dist/components/data-table-shared.js +18 -0
  147. package/dist/components/data-table-shared.js.map +1 -1
  148. package/dist/components/data-table-sort.d.ts +21 -2
  149. package/dist/components/data-table-sort.js +24 -0
  150. package/dist/components/data-table-sort.js.map +1 -1
  151. package/dist/components/data-table-virtual.d.ts +1 -1
  152. package/dist/components/data-table-virtual.js +18 -6
  153. package/dist/components/data-table-virtual.js.map +1 -1
  154. package/dist/components/data-table.d.ts +13 -4
  155. package/dist/components/data-table.js +139 -36
  156. package/dist/components/data-table.js.map +1 -1
  157. package/dist/components/date-field.d.ts +24 -2
  158. package/dist/components/date-field.js +33 -8
  159. package/dist/components/date-field.js.map +1 -1
  160. package/dist/components/date-picker.d.ts +15 -2
  161. package/dist/components/date-picker.js +55 -26
  162. package/dist/components/date-picker.js.map +1 -1
  163. package/dist/components/date-range-picker.d.ts +47 -20
  164. package/dist/components/date-range-picker.js +23 -7
  165. package/dist/components/date-range-picker.js.map +1 -1
  166. package/dist/components/error-boundary.js +37 -30
  167. package/dist/components/error-boundary.js.map +1 -1
  168. package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
  169. package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
  170. package/dist/components/field-base-labels.js.map +1 -0
  171. package/dist/components/field-base.d.ts +4 -3
  172. package/dist/components/field-base.js +3 -3
  173. package/dist/components/field-base.js.map +1 -1
  174. package/dist/components/field-sync-labels.d.ts +1 -0
  175. package/dist/components/field-sync-labels.js.map +1 -1
  176. package/dist/components/field-sync.d.ts +23 -1
  177. package/dist/components/field-sync.js.map +1 -1
  178. package/dist/components/form-actions.js +11 -5
  179. package/dist/components/form-actions.js.map +1 -1
  180. package/dist/components/hover-menu.d.ts +3 -0
  181. package/dist/components/hover-menu.js +5 -3
  182. package/dist/components/hover-menu.js.map +1 -1
  183. package/dist/components/icon-button.js +14 -9
  184. package/dist/components/icon-button.js.map +1 -1
  185. package/dist/components/inline-confirm.d.ts +43 -0
  186. package/dist/components/inline-confirm.js +67 -0
  187. package/dist/components/inline-confirm.js.map +1 -0
  188. package/dist/components/inline-entity-combobox.d.ts +4 -3
  189. package/dist/components/inline-entity-combobox.js +148 -140
  190. package/dist/components/inline-entity-combobox.js.map +1 -1
  191. package/dist/components/input.js +1 -1
  192. package/dist/components/input.js.map +1 -1
  193. package/dist/components/jump-calendar.js +28 -112
  194. package/dist/components/jump-calendar.js.map +1 -1
  195. package/dist/components/legal-page.d.ts +3 -1
  196. package/dist/components/legal-page.js +3 -2
  197. package/dist/components/legal-page.js.map +1 -1
  198. package/dist/components/legal.d.ts +4 -2
  199. package/dist/components/legal.js.map +1 -1
  200. package/dist/components/lightbox.d.ts +2 -2
  201. package/dist/components/lightbox.js +17 -6
  202. package/dist/components/lightbox.js.map +1 -1
  203. package/dist/components/list.d.ts +6 -2
  204. package/dist/components/list.js +3 -2
  205. package/dist/components/list.js.map +1 -1
  206. package/dist/components/measured-grid.d.ts +1 -1
  207. package/dist/components/measured-grid.js +2 -1
  208. package/dist/components/measured-grid.js.map +1 -1
  209. package/dist/components/mini-calendar.js +3 -5
  210. package/dist/components/mini-calendar.js.map +1 -1
  211. package/dist/components/modal.js +3 -1
  212. package/dist/components/modal.js.map +1 -1
  213. package/dist/components/month-grid.d.ts +55 -0
  214. package/dist/components/month-grid.js +148 -0
  215. package/dist/components/month-grid.js.map +1 -0
  216. package/dist/components/month-picker.d.ts +36 -4
  217. package/dist/components/month-picker.js +123 -146
  218. package/dist/components/month-picker.js.map +1 -1
  219. package/dist/components/multi-select.d.ts +2 -2
  220. package/dist/components/multi-select.js +11 -6
  221. package/dist/components/multi-select.js.map +1 -1
  222. package/dist/components/picker-sheet.js +2 -1
  223. package/dist/components/picker-sheet.js.map +1 -1
  224. package/dist/components/pie-chart-labels.d.ts +7 -0
  225. package/dist/components/pie-chart-labels.js +1 -0
  226. package/dist/components/pie-chart-labels.js.map +1 -1
  227. package/dist/components/pie-chart.d.ts +5 -3
  228. package/dist/components/pie-chart.js +7 -22
  229. package/dist/components/pie-chart.js.map +1 -1
  230. package/dist/components/popover.d.ts +3 -0
  231. package/dist/components/popover.js +7 -1
  232. package/dist/components/popover.js.map +1 -1
  233. package/dist/components/row-actions.js +2 -1
  234. package/dist/components/row-actions.js.map +1 -1
  235. package/dist/components/section-nav.d.ts +7 -0
  236. package/dist/components/section-nav.js.map +1 -1
  237. package/dist/components/series-chart-axes.d.ts +3 -3
  238. package/dist/components/series-chart-axes.js.map +1 -1
  239. package/dist/components/series-chart-labels.d.ts +7 -4
  240. package/dist/components/series-chart-labels.js.map +1 -1
  241. package/dist/components/series-chart.d.ts +31 -7
  242. package/dist/components/series-chart.js +72 -29
  243. package/dist/components/series-chart.js.map +1 -1
  244. package/dist/components/share-card.js +3 -3
  245. package/dist/components/share-card.js.map +1 -1
  246. package/dist/components/sign-chip-labels.d.ts +1 -0
  247. package/dist/components/sign-chip-labels.js.map +1 -1
  248. package/dist/components/sign-chip.d.ts +10 -1
  249. package/dist/components/sign-chip.js.map +1 -1
  250. package/dist/components/tabs-labels.d.ts +2 -0
  251. package/dist/components/tabs-labels.js +11 -0
  252. package/dist/components/tabs-labels.js.map +1 -0
  253. package/dist/components/tabs.d.ts +1 -1
  254. package/dist/components/tabs.js +1 -1
  255. package/dist/components/tabs.js.map +1 -1
  256. package/dist/components/toggle-legend.d.ts +2 -2
  257. package/dist/components/toggle-legend.js +6 -6
  258. package/dist/components/toggle-legend.js.map +1 -1
  259. package/dist/components/translation-review-editor.d.ts +4 -2
  260. package/dist/components/translation-review-editor.js +2 -3
  261. package/dist/components/translation-review-editor.js.map +1 -1
  262. package/dist/components/translation-review.d.ts +2 -1
  263. package/dist/components/translation-review.js +2 -2
  264. package/dist/components/translation-review.js.map +1 -1
  265. package/dist/components/treemap-labels.d.ts +26 -0
  266. package/dist/components/treemap-labels.js +10 -0
  267. package/dist/components/treemap-labels.js.map +1 -0
  268. package/dist/components/treemap-layout.d.ts +62 -0
  269. package/dist/components/treemap-layout.js +126 -0
  270. package/dist/components/treemap-layout.js.map +1 -0
  271. package/dist/components/treemap.d.ts +140 -17
  272. package/dist/components/treemap.js +324 -97
  273. package/dist/components/treemap.js.map +1 -1
  274. package/dist/components/use-table-state.d.ts +5 -5
  275. package/dist/components/use-table-state.js +4 -1
  276. package/dist/components/use-table-state.js.map +1 -1
  277. package/dist/data-table.d.ts +6 -2
  278. package/dist/data-table.js +7 -2
  279. package/dist/data-table.js.map +1 -1
  280. package/dist/eslint/index.js +1 -1
  281. package/dist/eslint/role-utilities.d.ts +36 -7
  282. package/dist/eslint/role-utilities.js +42 -9
  283. package/dist/eslint/role-utilities.js.map +1 -1
  284. package/dist/feedback/feedback-dialog.d.ts +25 -16
  285. package/dist/feedback/feedback-dialog.js +6 -2
  286. package/dist/feedback/feedback-dialog.js.map +1 -1
  287. package/dist/feedback/feedback-mutation.d.ts +30 -0
  288. package/dist/feedback/feedback-mutation.js +16 -0
  289. package/dist/feedback/feedback-mutation.js.map +1 -0
  290. package/dist/feedback/feedback-page-link.d.ts +53 -0
  291. package/dist/feedback/feedback-page-link.js +37 -0
  292. package/dist/feedback/feedback-page-link.js.map +1 -0
  293. package/dist/feedback/feedback-public-list.d.ts +12 -3
  294. package/dist/feedback/feedback-public-list.js +2 -1
  295. package/dist/feedback/feedback-public-list.js.map +1 -1
  296. package/dist/feedback/feedback-replies.d.ts +3 -1
  297. package/dist/feedback/feedback-replies.js +5 -4
  298. package/dist/feedback/feedback-replies.js.map +1 -1
  299. package/dist/feedback/feedback-row-detail-labels.js +5 -0
  300. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  301. package/dist/feedback/feedback-row-detail.d.ts +64 -28
  302. package/dist/feedback/feedback-row-detail.js +30 -28
  303. package/dist/feedback/feedback-row-detail.js.map +1 -1
  304. package/dist/feedback/feedback-status-undo.d.ts +30 -11
  305. package/dist/feedback/feedback-status-undo.js +10 -15
  306. package/dist/feedback/feedback-status-undo.js.map +1 -1
  307. package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
  308. package/dist/feedback/feedback-submit-dialog.js +1 -1
  309. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  310. package/dist/feedback/feedback-submit.js +9 -3
  311. package/dist/feedback/feedback-submit.js.map +1 -1
  312. package/dist/feedback/feedback-swipe.d.ts +1 -1
  313. package/dist/feedback/feedback-swipe.js.map +1 -1
  314. package/dist/feedback/feedback-table.d.ts +21 -9
  315. package/dist/feedback/feedback-table.js +45 -25
  316. package/dist/feedback/feedback-table.js.map +1 -1
  317. package/dist/feedback/feedback-thread-labels.d.ts +2 -2
  318. package/dist/feedback/feedback-thread-labels.js.map +1 -1
  319. package/dist/feedback/feedback-thread.d.ts +24 -23
  320. package/dist/feedback/feedback-thread.js +2 -1
  321. package/dist/feedback/feedback-thread.js.map +1 -1
  322. package/dist/feedback.d.ts +34 -0
  323. package/dist/feedback.js +42 -0
  324. package/dist/feedback.js.map +1 -1
  325. package/dist/hooks/use-focus-trap.d.ts +35 -0
  326. package/dist/hooks/use-focus-trap.js +6 -4
  327. package/dist/hooks/use-focus-trap.js.map +1 -1
  328. package/dist/hooks/use-hotkey.d.ts +5 -2
  329. package/dist/hooks/use-hotkey.js +5 -4
  330. package/dist/hooks/use-hotkey.js.map +1 -1
  331. package/dist/hooks/use-long-press.d.ts +7 -4
  332. package/dist/hooks/use-long-press.js +3 -0
  333. package/dist/hooks/use-long-press.js.map +1 -1
  334. package/dist/hooks/use-media-query.js +12 -4
  335. package/dist/hooks/use-media-query.js.map +1 -1
  336. package/dist/hooks/use-mounted.d.ts +22 -0
  337. package/dist/hooks/use-mounted.js +24 -0
  338. package/dist/hooks/use-mounted.js.map +1 -0
  339. package/dist/hooks/use-overlay-history.js +19 -3
  340. package/dist/hooks/use-overlay-history.js.map +1 -1
  341. package/dist/i18n/defaults.js +4 -5
  342. package/dist/i18n/defaults.js.map +1 -1
  343. package/dist/i18n/german.js +7 -1
  344. package/dist/i18n/german.js.map +1 -1
  345. package/dist/i18n/kit-labels.d.ts +9 -2
  346. package/dist/i18n/kit-labels.js.map +1 -1
  347. package/dist/i18n/locales/en.js +20 -41
  348. package/dist/i18n/locales/en.js.map +3 -3
  349. package/dist/i18n/locales/es.js +7 -1
  350. package/dist/i18n/locales/es.js.map +1 -1
  351. package/dist/i18n/locales/fr.js +20 -10
  352. package/dist/i18n/locales/fr.js.map +1 -1
  353. package/dist/i18n/locales/hu.js +9 -1
  354. package/dist/i18n/locales/hu.js.map +1 -1
  355. package/dist/i18n/locales/it.js +7 -1
  356. package/dist/i18n/locales/it.js.map +1 -1
  357. package/dist/i18n/locales/zh.js +8 -1
  358. package/dist/i18n/locales/zh.js.map +1 -1
  359. package/dist/i18n/review.js +5 -0
  360. package/dist/i18n/review.js.map +1 -1
  361. package/dist/index.d.ts +64 -17
  362. package/dist/index.js +77 -12
  363. package/dist/index.js.map +1 -1
  364. package/dist/landing/routing.d.ts +3 -1
  365. package/dist/landing/routing.js +4 -7
  366. package/dist/landing/routing.js.map +1 -1
  367. package/dist/lib/broadcast.d.ts +17 -0
  368. package/dist/lib/broadcast.js +30 -0
  369. package/dist/lib/broadcast.js.map +1 -0
  370. package/dist/lib/date-format.d.ts +37 -2
  371. package/dist/lib/date-format.js +34 -8
  372. package/dist/lib/date-format.js.map +1 -1
  373. package/dist/lib/day-format.d.ts +46 -0
  374. package/dist/lib/day-format.js +46 -0
  375. package/dist/lib/day-format.js.map +1 -0
  376. package/dist/lib/describe-failure.d.ts +14 -0
  377. package/dist/lib/describe-failure.js +9 -0
  378. package/dist/lib/describe-failure.js.map +1 -0
  379. package/dist/lib/direction.d.ts +16 -0
  380. package/dist/lib/direction.js +9 -1
  381. package/dist/lib/direction.js.map +1 -1
  382. package/dist/lib/focus-left.d.ts +63 -0
  383. package/dist/lib/focus-left.js +67 -0
  384. package/dist/lib/focus-left.js.map +1 -0
  385. package/dist/lib/format.js +5 -14
  386. package/dist/lib/format.js.map +1 -1
  387. package/dist/lib/http-status.d.ts +24 -0
  388. package/dist/lib/http-status.js +14 -0
  389. package/dist/lib/http-status.js.map +1 -0
  390. package/dist/lib/intl-cache.d.ts +14 -0
  391. package/dist/lib/intl-cache.js +15 -0
  392. package/dist/lib/intl-cache.js.map +1 -0
  393. package/dist/lib/isin.d.ts +10 -0
  394. package/dist/lib/isin.js.map +1 -1
  395. package/dist/lib/iso-day.d.ts +11 -0
  396. package/dist/lib/iso-day.js +8 -0
  397. package/dist/lib/iso-day.js.map +1 -0
  398. package/dist/lib/lazy-with-fallback.d.ts +31 -0
  399. package/dist/lib/lazy-with-fallback.js +40 -0
  400. package/dist/lib/lazy-with-fallback.js.map +1 -0
  401. package/dist/lib/path-pattern.d.ts +34 -0
  402. package/dist/lib/path-pattern.js +24 -0
  403. package/dist/lib/path-pattern.js.map +1 -0
  404. package/dist/lib/reduced-motion.d.ts +2 -1
  405. package/dist/lib/reduced-motion.js.map +1 -1
  406. package/dist/lib/round.d.ts +2 -1
  407. package/dist/lib/round.js +2 -1
  408. package/dist/lib/round.js.map +1 -1
  409. package/dist/lib/safe-storage.d.ts +24 -5
  410. package/dist/lib/safe-storage.js +27 -2
  411. package/dist/lib/safe-storage.js.map +1 -1
  412. package/dist/lib/session-refresh.js +1 -1
  413. package/dist/lib/session-refresh.js.map +1 -1
  414. package/dist/lib/share-format.d.ts +13 -0
  415. package/dist/lib/share-format.js +10 -0
  416. package/dist/lib/share-format.js.map +1 -0
  417. package/dist/lib/text-case.d.ts +17 -0
  418. package/dist/lib/text-case.js +8 -0
  419. package/dist/lib/text-case.js.map +1 -0
  420. package/dist/lib/text-match.d.ts +29 -0
  421. package/dist/lib/text-match.js +20 -2
  422. package/dist/lib/text-match.js.map +1 -1
  423. package/dist/lib/thenable.d.ts +13 -0
  424. package/dist/lib/thenable.js +8 -0
  425. package/dist/lib/thenable.js.map +1 -0
  426. package/dist/lib/translation-review.d.ts +7 -2
  427. package/dist/lib/translation-review.js +4 -4
  428. package/dist/lib/translation-review.js.map +1 -1
  429. package/dist/notifications/device-zone-report.js +1 -1
  430. package/dist/notifications/device-zone-report.js.map +1 -1
  431. package/dist/notifications/notification-bell.d.ts +2 -1
  432. package/dist/notifications/notification-bell.js +3 -3
  433. package/dist/notifications/notification-bell.js.map +1 -1
  434. package/dist/notifications/notification-inbox.d.ts +10 -6
  435. package/dist/notifications/notification-inbox.js +26 -48
  436. package/dist/notifications/notification-inbox.js.map +1 -1
  437. package/dist/notifications/notification-parts.d.ts +3 -2
  438. package/dist/notifications/notification-parts.js +1 -3
  439. package/dist/notifications/notification-parts.js.map +1 -1
  440. package/dist/notifications/notification-types-setting.js +1 -1
  441. package/dist/notifications/notification-types-setting.js.map +1 -1
  442. package/dist/notifications/notifications-labels.d.ts +6 -0
  443. package/dist/notifications/notifications-labels.js +1 -0
  444. package/dist/notifications/notifications-labels.js.map +1 -1
  445. package/dist/notifications/push-device-setting.js +1 -1
  446. package/dist/notifications/push-device-setting.js.map +1 -1
  447. package/dist/notifications/push-devices-setting.d.ts +2 -1
  448. package/dist/notifications/push-devices-setting.js +27 -49
  449. package/dist/notifications/push-devices-setting.js.map +1 -1
  450. package/dist/notifications/quiet-hours-setting.d.ts +10 -3
  451. package/dist/notifications/quiet-hours-setting.js +65 -26
  452. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  453. package/dist/notifications/unsubscribe-panel.js +4 -7
  454. package/dist/notifications/unsubscribe-panel.js.map +1 -1
  455. package/dist/notifications/use-push-device.d.ts +39 -1
  456. package/dist/notifications/use-push-device.js +28 -7
  457. package/dist/notifications/use-push-device.js.map +1 -1
  458. package/dist/offline/query-persistence.d.ts +3 -1
  459. package/dist/offline/query-persistence.js +19 -2
  460. package/dist/offline/query-persistence.js.map +1 -1
  461. package/dist/rhf/fields.d.ts +11 -4
  462. package/dist/rhf/fields.js.map +1 -1
  463. package/dist/search/command-palette.js +1 -1
  464. package/dist/search/command-palette.js.map +1 -1
  465. package/dist/search/global-search.js +19 -9
  466. package/dist/search/global-search.js.map +1 -1
  467. package/dist/search/use-command-key.d.ts +12 -1
  468. package/dist/search/use-command-key.js +3 -12
  469. package/dist/search/use-command-key.js.map +1 -1
  470. package/dist/search.d.ts +7 -0
  471. package/dist/search.js +10 -0
  472. package/dist/search.js.map +1 -1
  473. package/dist/settings/use-settings-focus.js +1 -0
  474. package/dist/settings/use-settings-focus.js.map +1 -1
  475. package/dist/shell/account-menu-language.d.ts +21 -5
  476. package/dist/shell/account-menu-language.js +3 -1
  477. package/dist/shell/account-menu-language.js.map +1 -1
  478. package/dist/shell/account-menu-text-size.d.ts +26 -9
  479. package/dist/shell/account-menu-text-size.js +3 -2
  480. package/dist/shell/account-menu-text-size.js.map +1 -1
  481. package/dist/shell/dev-menu.js +5 -18
  482. package/dist/shell/dev-menu.js.map +1 -1
  483. package/dist/shell/role-switcher.d.ts +7 -0
  484. package/dist/shell/role-switcher.js.map +1 -1
  485. package/dist/shell/top-bar-actions.d.ts +1 -1
  486. package/dist/shell/top-bar-actions.js.map +1 -1
  487. package/dist/shell/top-bar-parts-labels.d.ts +0 -2
  488. package/dist/shell/top-bar-parts-labels.js +0 -1
  489. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  490. package/dist/shell.d.ts +27 -8
  491. package/dist/shell.js +28 -7
  492. package/dist/shell.js.map +1 -1
  493. package/dist/sync/engine.d.ts +30 -4
  494. package/dist/sync/engine.js +172 -52
  495. package/dist/sync/engine.js.map +1 -1
  496. package/dist/sync.d.ts +6 -2
  497. package/dist/sync.js +6 -1
  498. package/dist/sync.js.map +1 -1
  499. package/dist/testing/css-variables.js +3 -8
  500. package/dist/testing/css-variables.js.map +1 -1
  501. package/dist/theme/contrast.d.ts +2 -1
  502. package/dist/theme/contrast.js +3 -8
  503. package/dist/theme/contrast.js.map +1 -1
  504. package/dist/theme/palette-store.js +6 -6
  505. package/dist/theme/palette-store.js.map +1 -1
  506. package/dist/theme/text-size.js +3 -8
  507. package/dist/theme/text-size.js.map +1 -1
  508. package/dist/theme/theme-store.js +3 -6
  509. package/dist/theme/theme-store.js.map +1 -1
  510. package/dist/tour/tour-catalogue.d.ts +7 -4
  511. package/dist/tour/tour-catalogue.js +12 -10
  512. package/dist/tour/tour-catalogue.js.map +1 -1
  513. package/dist/tour/tour-dock.d.ts +0 -2
  514. package/dist/tour/tour-dock.js +0 -2
  515. package/dist/tour/tour-dock.js.map +1 -1
  516. package/dist/tour/tour-gates.d.ts +4 -0
  517. package/dist/tour/tour-gates.js +14 -0
  518. package/dist/tour/tour-gates.js.map +1 -1
  519. package/dist/tour/tour-overlay.d.ts +27 -0
  520. package/dist/tour/tour-overlay.js +741 -0
  521. package/dist/tour/tour-overlay.js.map +1 -0
  522. package/dist/tour/tour.d.ts +13 -3
  523. package/dist/tour/tour.js +59 -781
  524. package/dist/tour/tour.js.map +1 -1
  525. package/dist/tour/use-tour-progress.js +1 -1
  526. package/dist/tour/use-tour-progress.js.map +1 -1
  527. package/dist/wizard/stepper-nav.d.ts +5 -1
  528. package/dist/wizard/stepper-nav.js.map +1 -1
  529. package/dist/wizard/types.d.ts +6 -2
  530. package/dist/wizard/types.js.map +1 -1
  531. package/dist/wizard/use-wizard.d.ts +3 -1
  532. package/dist/wizard/use-wizard.js.map +1 -1
  533. package/dist/wizard/validation.d.ts +3 -1
  534. package/dist/wizard/validation.js.map +1 -1
  535. package/package.json +10 -6
  536. package/src/account/account-parts.ts +5 -25
  537. package/src/account/data-export-setting-labels.ts +1 -1
  538. package/src/account/delete-account-setting-labels.ts +1 -1
  539. package/src/account/email-change-setting-labels.ts +1 -1
  540. package/src/account/passkeys-setting.tsx +60 -38
  541. package/src/account/sessions-setting.tsx +18 -12
  542. package/src/admin/admin-action-confirm.tsx +1 -5
  543. package/src/admin/admin-parts.ts +11 -25
  544. package/src/admin/mail-test-card-labels.ts +1 -1
  545. package/src/admin/plan-change-labels.ts +5 -23
  546. package/src/admin/plan-change.tsx +7 -44
  547. package/src/admin/reviewer-scope-editor.tsx +3 -3
  548. package/src/auth/auth-errors-labels.ts +23 -0
  549. package/src/auth/auth-errors.ts +11 -38
  550. package/src/auth/complete-name-dialog.tsx +4 -1
  551. package/src/auth/forgot-password-form-labels.ts +1 -1
  552. package/src/auth/forgot-password-form.tsx +11 -6
  553. package/src/auth/register-form-labels.ts +1 -1
  554. package/src/auth/reset-password-form-labels.ts +1 -1
  555. package/src/auth/reset-password-form.tsx +8 -4
  556. package/src/auth/sign-in-form-labels.ts +1 -1
  557. package/src/auth/status-parts.tsx +0 -6
  558. package/src/auth/verify-email-labels.ts +1 -1
  559. package/src/auth/verify-email.tsx +11 -6
  560. package/src/billing/cancel-subscription.tsx +26 -12
  561. package/src/billing/dialog-close.ts +34 -0
  562. package/src/billing/plan-card.tsx +36 -11
  563. package/src/billing/plan-change-labels.ts +66 -0
  564. package/src/billing/plan-switch.tsx +26 -12
  565. package/src/chart.ts +21 -3
  566. package/src/components/account-chips.tsx +20 -23
  567. package/src/components/alert-banner.tsx +82 -5
  568. package/src/components/amount-input.tsx +18 -7
  569. package/src/components/autocomplete.tsx +64 -70
  570. package/src/components/bulk-action-bar.tsx +70 -2
  571. package/src/components/button-look.ts +5 -5
  572. package/src/components/button.tsx +2 -2
  573. package/src/components/chart-edge.ts +34 -1
  574. package/src/components/chart-figure.tsx +35 -0
  575. package/src/components/chart-zoom-core.tsx +6 -5
  576. package/src/components/chart.tsx +26 -5
  577. package/src/components/combobox-core.tsx +293 -62
  578. package/src/components/combobox.tsx +183 -153
  579. package/src/components/copy-button.tsx +34 -23
  580. package/src/components/country-select.tsx +16 -11
  581. package/src/components/data-table-column-settings.tsx +52 -10
  582. package/src/components/data-table-filters.ts +6 -4
  583. package/src/components/data-table-fit.ts +19 -5
  584. package/src/components/data-table-groups.tsx +1 -1
  585. package/src/components/data-table-head.tsx +32 -22
  586. package/src/components/data-table-mobile.tsx +61 -26
  587. package/src/components/data-table-pagination.tsx +21 -6
  588. package/src/components/data-table-resize.ts +1 -1
  589. package/src/components/data-table-row-actions.tsx +3 -3
  590. package/src/components/data-table-row.tsx +25 -14
  591. package/src/components/data-table-selection.ts +1 -1
  592. package/src/components/data-table-shared.tsx +33 -1
  593. package/src/components/data-table-sort.ts +57 -2
  594. package/src/components/data-table-virtual.ts +32 -8
  595. package/src/components/data-table.tsx +239 -68
  596. package/src/components/date-field.tsx +65 -8
  597. package/src/components/date-picker.tsx +125 -48
  598. package/src/components/date-range-picker.tsx +82 -31
  599. package/src/components/error-boundary.tsx +53 -39
  600. package/src/components/field-base-labels.ts +20 -0
  601. package/src/components/field-base.tsx +13 -7
  602. package/src/components/field-sync-labels.ts +1 -0
  603. package/src/components/field-sync.tsx +23 -1
  604. package/src/components/form-actions.tsx +20 -5
  605. package/src/components/hover-menu.tsx +18 -8
  606. package/src/components/icon-button.tsx +14 -9
  607. package/src/components/inline-confirm.tsx +116 -0
  608. package/src/components/inline-entity-combobox.tsx +197 -153
  609. package/src/components/input.tsx +1 -1
  610. package/src/components/jump-calendar.tsx +30 -146
  611. package/src/components/legal-page.tsx +10 -7
  612. package/src/components/legal.tsx +4 -2
  613. package/src/components/lightbox.tsx +21 -8
  614. package/src/components/list.tsx +10 -4
  615. package/src/components/measured-grid.tsx +8 -4
  616. package/src/components/mini-calendar.tsx +6 -5
  617. package/src/components/modal.tsx +6 -1
  618. package/src/components/month-grid.tsx +229 -0
  619. package/src/components/month-picker.tsx +192 -200
  620. package/src/components/multi-select.tsx +21 -9
  621. package/src/components/picker-sheet.tsx +12 -9
  622. package/src/components/pie-chart-labels.ts +8 -0
  623. package/src/components/pie-chart.tsx +22 -28
  624. package/src/components/popover.tsx +18 -1
  625. package/src/components/row-actions.tsx +2 -1
  626. package/src/components/section-nav.tsx +7 -0
  627. package/src/components/series-chart-axes.ts +3 -3
  628. package/src/components/series-chart-labels.ts +7 -4
  629. package/src/components/series-chart.tsx +178 -69
  630. package/src/components/share-card.tsx +6 -6
  631. package/src/components/sign-chip-labels.ts +1 -0
  632. package/src/components/sign-chip.tsx +10 -1
  633. package/src/components/tabs-labels.ts +13 -0
  634. package/src/components/tabs.tsx +2 -2
  635. package/src/components/toggle-legend.tsx +16 -11
  636. package/src/components/translation-review-editor.tsx +6 -5
  637. package/src/components/translation-review.tsx +4 -3
  638. package/src/components/treemap-labels.ts +39 -0
  639. package/src/components/treemap-layout.ts +210 -0
  640. package/src/components/treemap.tsx +722 -133
  641. package/src/components/use-table-state.ts +12 -9
  642. package/src/data-table.ts +9 -2
  643. package/src/eslint/role-utilities.ts +97 -19
  644. package/src/feedback/feedback-dialog.tsx +30 -19
  645. package/src/feedback/feedback-mutation.ts +41 -0
  646. package/src/feedback/feedback-page-link.ts +90 -0
  647. package/src/feedback/feedback-public-list.tsx +17 -5
  648. package/src/feedback/feedback-replies.tsx +13 -6
  649. package/src/feedback/feedback-row-detail-labels.ts +5 -0
  650. package/src/feedback/feedback-row-detail.tsx +103 -67
  651. package/src/feedback/feedback-status-undo.ts +41 -27
  652. package/src/feedback/feedback-submit-dialog.tsx +2 -2
  653. package/src/feedback/feedback-submit.tsx +21 -7
  654. package/src/feedback/feedback-swipe.tsx +1 -1
  655. package/src/feedback/feedback-table.tsx +86 -38
  656. package/src/feedback/feedback-thread-labels.ts +2 -2
  657. package/src/feedback/feedback-thread.tsx +27 -25
  658. package/src/feedback.ts +42 -0
  659. package/src/hooks/use-focus-trap.ts +8 -24
  660. package/src/hooks/use-hotkey.ts +24 -7
  661. package/src/hooks/use-long-press.ts +16 -2
  662. package/src/hooks/use-media-query.ts +20 -4
  663. package/src/hooks/use-mounted.ts +39 -0
  664. package/src/hooks/use-overlay-history.ts +32 -3
  665. package/src/i18n/defaults.ts +4 -5
  666. package/src/i18n/german.ts +8 -2
  667. package/src/i18n/kit-labels.tsx +9 -2
  668. package/src/i18n/locales/es.ts +8 -2
  669. package/src/i18n/locales/fr.ts +21 -13
  670. package/src/i18n/locales/hu.ts +10 -2
  671. package/src/i18n/locales/it.ts +8 -2
  672. package/src/i18n/locales/zh.ts +9 -2
  673. package/src/i18n/review.ts +5 -0
  674. package/src/index.ts +103 -13
  675. package/src/landing/routing.tsx +14 -10
  676. package/src/lib/broadcast.ts +52 -0
  677. package/src/lib/date-format.ts +89 -13
  678. package/src/lib/day-format.ts +96 -0
  679. package/src/lib/describe-failure.ts +18 -0
  680. package/src/lib/direction.ts +39 -0
  681. package/src/lib/focus-left.ts +156 -0
  682. package/src/lib/format.ts +5 -17
  683. package/src/lib/http-status.ts +38 -0
  684. package/src/lib/intl-cache.ts +25 -0
  685. package/src/lib/isin.ts +10 -0
  686. package/src/lib/iso-day.ts +13 -0
  687. package/src/lib/lazy-with-fallback.ts +82 -0
  688. package/src/lib/path-pattern.ts +55 -0
  689. package/src/lib/reduced-motion.ts +2 -1
  690. package/src/lib/round.ts +7 -2
  691. package/src/lib/safe-storage.ts +48 -6
  692. package/src/lib/session-refresh.ts +1 -1
  693. package/src/lib/share-format.ts +18 -0
  694. package/src/lib/text-case.ts +19 -0
  695. package/src/lib/text-match.ts +57 -2
  696. package/src/lib/thenable.ts +19 -0
  697. package/src/lib/translation-review.ts +13 -5
  698. package/src/notifications/device-zone-report.ts +1 -1
  699. package/src/notifications/notification-bell.tsx +7 -4
  700. package/src/notifications/notification-inbox.tsx +40 -58
  701. package/src/notifications/notification-parts.tsx +3 -4
  702. package/src/notifications/notification-types-setting.tsx +1 -1
  703. package/src/notifications/notifications-labels.ts +7 -0
  704. package/src/notifications/push-device-setting.tsx +1 -1
  705. package/src/notifications/push-devices-setting.tsx +30 -55
  706. package/src/notifications/quiet-hours-setting.tsx +93 -31
  707. package/src/notifications/unsubscribe-panel.tsx +4 -7
  708. package/src/notifications/use-push-device.ts +76 -10
  709. package/src/offline/query-persistence.ts +35 -3
  710. package/src/rhf/fields.tsx +11 -4
  711. package/src/search/command-palette.tsx +2 -4
  712. package/src/search/global-search.tsx +36 -15
  713. package/src/search/use-command-key.ts +13 -12
  714. package/src/search.ts +9 -0
  715. package/src/settings/use-settings-focus.ts +3 -0
  716. package/src/shell/account-menu-language.tsx +27 -5
  717. package/src/shell/account-menu-text-size.tsx +32 -10
  718. package/src/shell/dev-menu.tsx +7 -21
  719. package/src/shell/role-switcher.tsx +7 -0
  720. package/src/shell/top-bar-actions.tsx +1 -1
  721. package/src/shell/top-bar-parts-labels.ts +0 -3
  722. package/src/shell.ts +40 -9
  723. package/src/sync/engine.ts +339 -61
  724. package/src/sync.ts +8 -1
  725. package/src/testing/css-variables.ts +8 -9
  726. package/src/theme/contrast.ts +8 -9
  727. package/src/theme/palette-store.ts +9 -9
  728. package/src/theme/text-size.ts +6 -8
  729. package/src/theme/theme-store.ts +7 -9
  730. package/src/tour/tour-catalogue.tsx +26 -15
  731. package/src/tour/tour-dock.ts +0 -2
  732. package/src/tour/tour-gates.ts +23 -0
  733. package/src/tour/tour-overlay.tsx +1170 -0
  734. package/src/tour/tour.tsx +108 -1202
  735. package/src/tour/use-tour-progress.ts +1 -1
  736. package/src/wizard/stepper-nav.tsx +3 -1
  737. package/src/wizard/types.ts +11 -2
  738. package/src/wizard/use-wizard.ts +2 -1
  739. package/src/wizard/validation.ts +8 -2
  740. package/tokens.css +2 -1
  741. package/dist/components/ui-labels.js.map +0 -1
  742. package/dist/shell/dev-switchers.d.ts +0 -6
  743. package/dist/shell/dev-switchers.js +0 -12
  744. package/dist/shell/dev-switchers.js.map +0 -1
  745. package/src/components/ui-labels.ts +0 -24
  746. package/src/shell/dev-switchers.tsx +0 -18
@@ -7,8 +7,9 @@ import { TextLink } from "../components/text-link";
7
7
  import { toast } from "../components/toast";
8
8
  import { Button } from "../components/button";
9
9
  import type { AuthedFetcher } from "../hooks/use-authed-src";
10
- import { useKitLabels, useKitLocale, type LabelOverride } from "../i18n/kit-labels";
11
- import { formatDate } from "../lib/format";
10
+ import type { PathPattern } from "../landing/routing";
11
+ import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
12
+ import { useDayFormatter } from "../lib/day-format";
12
13
  import { DEFAULT_MAX_ATTACHMENT_BYTES } from "./feedback-attachment";
13
14
  import { DEFAULT_FEEDBACK_DIALOG_LABELS } from "./feedback-dialog";
14
15
  import {
@@ -34,6 +35,8 @@ import {
34
35
  splitDescription,
35
36
  } from "./feedback-record";
36
37
  import type { FeedbackContext, FeedbackRecord } from "./feedback-record";
38
+ import { runMutation, type FeedbackMutationCall } from "./feedback-mutation";
39
+ import { feedbackPage, feedbackPageLinkTarget } from "./feedback-page-link";
37
40
  import { useFeedbackStatusUndo } from "./feedback-status-undo";
38
41
  import type { FeedbackStatusChange } from "./feedback-status-undo";
39
42
  import type { CommitScope } from "../components/write-lock";
@@ -130,15 +133,21 @@ export interface FeedbackDetailLabels {
130
133
  /** On section 4's heading line once the row is settled, given the formatted
131
134
  * `resolved_at` date. de-CH: "Erledigt am: {{date}}" */
132
135
  resolvedAt: (date: string) => string;
133
- /** The admin's button while there is no outcome. **Unused since 0.38** (the outcome is
134
- * frozen, §9.7; a reply is written instead); kept for one release.
135
- * de-CH: "Ergebnis hinzufügen" */
136
+ // Deprecated on these members, the ones an app's code reads and overrides through: the
137
+ // tags sat on the English default's keys, and reached nothing — the default is typed by
138
+ // this interface (0.52 code review, feedback-row-detail-labels.ts; refactor audit
139
+ // 2026-10-30, DOC-9).
140
+ /** The admin's button while there is no outcome — read by nothing since 0.38 (the
141
+ * outcome is frozen, §9.7; a reply is written instead). de-CH: "Ergebnis hinzufügen"
142
+ * @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
136
143
  outcomeAdd: string;
137
144
  /** The same button once there is one. Unused since 0.38, as `outcomeAdd`.
138
- * de-CH: "Aktualisieren" */
145
+ * de-CH: "Aktualisieren"
146
+ * @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
139
147
  outcomeUpdate: string;
140
- /** The line above the outcome editor. Unused since 0.38, as `outcomeAdd`. de-CH: "Was wurde umgesetzt, entschieden oder
141
- * warum nicht." */
148
+ /** The line above the outcome editor. Unused since 0.38, as `outcomeAdd`.
149
+ * de-CH: "Was wurde umgesetzt, entschieden oder warum nicht."
150
+ * @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
142
151
  outcomePlaceholder: string;
143
152
  /** The button that opens section 5 on an answered row. de-CH: "Nacharbeit" */
144
153
  rework: string;
@@ -172,42 +181,28 @@ export function useFeedbackDetailLabels(labels?: LabelOverride<FeedbackDetailLab
172
181
 
173
182
  /* ── The page a report was filed on (§3.2, §4.4.2) ────────────────────────── */
174
183
 
175
- /** `context.url`, else `context.route` — a parsed URL, or null when neither is set or
176
- * the value is no http(s) address or path (a `javascript:` value is not a page). */
177
- function parsePage(context: FeedbackContext | null | undefined): URL | null {
178
- const raw = (context?.url || context?.route || "").trim();
179
- if (!raw) return null;
180
- try {
181
- // A base, so a PATH-ONLY value parses too: Kurvenschmiede backfills its old rows
182
- // with `url = page_path + search` (§3.2), and keksdose's `new URL(raw)` threw on
183
- // those and dropped the section.
184
- const url = new URL(raw, "http://localhost");
185
- return url.protocol === "http:" || url.protocol === "https:" ? url : null;
186
- } catch {
187
- return null;
188
- }
189
- }
190
-
191
- /** Collapses a leading `//` run: `/\/\/evil.example/` as a path would be a
192
- * protocol-relative link off the app. */
193
- const localPath = (pathname: string) => pathname.replace(/^\/{2,}/, "/");
194
-
195
184
  /**
196
- * The in-app link to the page a report was filed on — path + query + hash (keksdose
197
- * `localHref`: the query and hash carry the state worth restoring, `?tab=import`, a
198
- * drill-down). Read from `context.url`, else `context.route`; a path-only `url` works.
199
- * Always a path on THIS app, never another origin's address, so it is safe as an
200
- * `href` whatever the row says. `null` when there is nothing to link.
185
+ * The page a report was filed on as the reporter had it — path + query + hash (keksdose
186
+ * `localHref`: the query and hash carry the state, `?tab=import`, a drill-down). Read from
187
+ * `context.url`, else `context.route`; a path-only `url` works. `null` when there is no
188
+ * page.
189
+ *
190
+ * Always a path on THIS app, never another origin's address — but the path and query
191
+ * are the reporter's to write, so it is TEXT, not a link target: `/join?token=…` acts on
192
+ * load, and `/login?next=…` forwards a signed-in admin to whatever its query names
193
+ * (refactor audit 2026-10-30, FLW-7; 0.52 code review). The kit's URL cell and section
194
+ * link {@link feedbackPagePath} alone, and not even that for a one-shot route
195
+ * (`pageLinkExclude`) — `FeedbackRowDetail` and `useFeedbackColumns` draw the page that
196
+ * way; an app's own cell should not link this.
201
197
  */
202
198
  export function feedbackPageHref(context: FeedbackContext | null | undefined): string | null {
203
- const url = parsePage(context);
204
- return url ? `${localPath(url.pathname)}${url.search}${url.hash}` : null;
199
+ return feedbackPage(context)?.href ?? null;
205
200
  }
206
201
 
207
- /** The page's path alone — the compact text a URL column shows (§4.3). */
202
+ /** The page's path alone — the compact text a URL column shows (§4.3), and the only part
203
+ * of the page the kit links. */
208
204
  export function feedbackPagePath(context: FeedbackContext | null | undefined): string | null {
209
- const url = parsePage(context);
210
- return url ? localPath(url.pathname) : null;
205
+ return feedbackPage(context)?.path ?? null;
211
206
  }
212
207
 
213
208
  /**
@@ -216,8 +211,7 @@ export function feedbackPagePath(context: FeedbackContext | null | undefined): s
216
211
  * (feedback #278) — else `context.route`. `null` when there is no page.
217
212
  */
218
213
  export function feedbackPageUrl(context: FeedbackContext | null | undefined): string | null {
219
- if (!parsePage(context)) return null;
220
- return (context?.url || context?.route || "").trim();
214
+ return feedbackPage(context)?.url ?? null;
221
215
  }
222
216
 
223
217
  /* ── Attachments (§3.5, §4.4.3) ───────────────────────────────────────────── */
@@ -315,13 +309,25 @@ export interface FeedbackDetailPatch {
315
309
  }
316
310
 
317
311
  /**
318
- * The page's update mutation. **TanStack Query's `mutate` fits as it stands** — pass
319
- * `update.mutate` (and `pending={update.isPending}`), the same function
320
- * `useFeedbackStatusUndo` takes. A hand-written one sends the PATCH and calls
321
- * `onSuccess` once it has landed, and only then: that is when an editor closes. A
322
- * failure is the mutation's own to toast — the server's `detail`, else
312
+ * The page's update mutation (0.52): **TanStack Query's `mutateAsync`** — pass
313
+ * `update.mutateAsync` (and `pending={update.isPending}`), the same function
314
+ * `useFeedbackStatusUndo` takes. An editor closes when the promise resolves, which it does
315
+ * for every call — also when a status pill was pressed while the save was in flight
316
+ * (refactor audit 2026-10-30, FLW-3). A hand-written one resolves once the PATCH has
317
+ * landed. A failure is the mutation's own to toast — the server's `detail`, else
323
318
  * `feedbackToast.updateFailed` (§4.4) — and leaves the editor open with its draft.
324
319
  */
320
+ export type FeedbackDetailUpdateAsync = (patch: FeedbackDetailPatch) => Promise<unknown>;
321
+
322
+ /**
323
+ * The callback form: TanStack Query's `mutate`, or a function that calls `onSuccess` once
324
+ * the PATCH has landed. TanStack calls a per-call `onSuccess` for the LATEST `mutate()`
325
+ * only, so an editor whose save was followed by another PATCH before it answered stayed
326
+ * open, and the earlier status change lost its Undo.
327
+ *
328
+ * @deprecated 0.52 — pass `update.mutateAsync` ({@link FeedbackDetailUpdateAsync}); removed
329
+ * in 0.53
330
+ */
325
331
  export type FeedbackDetailUpdate = (patch: FeedbackDetailPatch, callbacks: { onSuccess: () => void }) => void;
326
332
 
327
333
  /** `POST /feedback/attachments` (§3.3): one file up, its URL
@@ -342,10 +348,10 @@ export interface FeedbackReworkSectionProps {
342
348
  /** 0.40: the rework as an entry of its own — see {@link FeedbackReworkSend}. With it,
343
349
  * `onUpdate` is not called. */
344
350
  onRework?: FeedbackReworkSend;
345
- /** The PATCH — see {@link FeedbackDetailUpdate}. Called with `{ id, body }` only, and
346
- * only without `onRework`: the legacy append (§3.4), which server-kit 0.13 still
351
+ /** The PATCH — see {@link FeedbackDetailUpdateAsync}. Called with `{ id, body }` only,
352
+ * and only without `onRework`: the legacy append (§3.4), which server-kit 0.13 still
347
353
  * turns into an entry for one release. Optional since 0.40; pass one of the two. */
348
- onUpdate?: FeedbackDetailUpdate;
354
+ onUpdate?: FeedbackMutationCall<FeedbackDetailPatch>;
349
355
  /** The PATCH is in flight (`update.isPending`). The upload adds its own. */
350
356
  pending?: boolean;
351
357
  /** The upload. Left out, the note goes without a file field. */
@@ -466,7 +472,7 @@ export function FeedbackReworkSection({
466
472
  return;
467
473
  }
468
474
  if (body === null) return;
469
- onUpdate({ id: row.id, body }, { onSuccess: () => onSent?.() });
475
+ runMutation(onUpdate, { id: row.id, body }, () => onSent?.());
470
476
  };
471
477
 
472
478
  return (
@@ -510,8 +516,10 @@ export interface FeedbackRowDetailProps {
510
516
  canEdit: boolean;
511
517
  /** The signed-in user's id — who the AUTHOR is: the description editor and rework. */
512
518
  viewerId?: number | null;
513
- /** The page's PATCH — `update.mutate` (see {@link FeedbackDetailUpdate}). */
514
- onUpdate: FeedbackDetailUpdate;
519
+ /** The page's PATCH — `update.mutateAsync` (see {@link FeedbackDetailUpdateAsync}). The
520
+ * callback form ({@link FeedbackDetailUpdate}, `update.mutate`) still fits, deprecated
521
+ * since 0.52; the prop's one signature takes both. */
522
+ onUpdate: FeedbackMutationCall<FeedbackDetailPatch>;
515
523
  /** `update.isPending`: the editors' save buttons wait for it. */
516
524
  pending?: boolean;
517
525
  /** `POST /feedback/attachments` for the rework's one file and, since 0.47 (§12) with
@@ -522,7 +530,7 @@ export interface FeedbackRowDetailProps {
522
530
  * the browser's own fetch with same-origin cookies. */
523
531
  fetcher?: AuthedFetcher | null;
524
532
  /**
525
- * The undoable status change — what `useFeedbackStatusUndo(update.mutate)` returns,
533
+ * The undoable status change — what `useFeedbackStatusUndo(update.mutateAsync)` returns,
526
534
  * the SAME one the table's status cell and the swipes use (§4.5). Left out, the
527
535
  * detail builds one from `onUpdate`, which is equivalent as long as `onUpdate` is the
528
536
  * page's mutation (its observer outlives the row a status filter removes).
@@ -534,9 +542,20 @@ export interface FeedbackRowDetailProps {
534
542
  /** The rework's and (0.47, with `replyAttachments`) the reply composer's file field,
535
543
  * over the contract's defaults. */
536
544
  reworkAttachment?: Partial<FeedbackNoteAttachment>;
537
- /** How the `resolved_at` date reads — the app's date cell, as a string. Default: the
538
- * kit's `formatDate` in the provider's locale, `medium` style. */
545
+ /** How the `resolved_at` date reads — the app's date cell, as a string. Default
546
+ * (0.52): the `<UiKitProvider formatDate>` when the app set one, else the kit's
547
+ * `formatDate` in the provider's locale and time zone, `medium` style. */
539
548
  renderDate?: (iso: string) => string;
549
+ /**
550
+ * 0.52 (FLW-7): the app's one-shot routes, ON TOP of the kit's — `/join`,
551
+ * `/register`, `/verify-email`, `/reset-password` (a string is that path and everything
552
+ * under it, a RegExp is tested on the path, as `useLastVisitedPage`'s `exclude`). The
553
+ * URL section shows such a page as text with Copy, never as a link: it acts on load,
554
+ * and a report's page is the reporter's to write. Any other page links its PATH alone;
555
+ * the query, where tokens and `?next=` targets travel, is text. keksdose:
556
+ * `["/banks/callback", "/share-target"]`. Keep it stable (module scope).
557
+ */
558
+ pageLinkExclude?: readonly PathPattern[];
540
559
  /**
541
560
  * The detail's saves COMMIT (description, outcome, rework, status): under a locked
542
561
  * `WriteLockProvider` each is `aria-disabled` with the lock's reason, and nothing
@@ -607,12 +626,12 @@ export interface FeedbackRowDetailProps {
607
626
  * ```tsx
608
627
  * const update = useMutation({ mutationFn: ({ id, ...patch }) => api.updateFeedback(id, patch),
609
628
  * onSuccess: invalidate, onError: (e) => toast.error(detailOf(e) ?? toastLabels.updateFailed) });
610
- * const changeStatus = useFeedbackStatusUndo(update.mutate);
629
+ * const changeStatus = useFeedbackStatusUndo(update.mutateAsync);
611
630
  * <DataTable
612
631
  * isExpanded={(row) => expandedId === row.id}
613
632
  * expandedRow={(row) => (
614
633
  * <FeedbackRowDetail row={row} canEdit={isAdmin && !mine} viewerId={user?.id}
615
- * onUpdate={update.mutate} pending={update.isPending} statusChange={changeStatus}
634
+ * onUpdate={update.mutateAsync} pending={update.isPending} statusChange={changeStatus}
616
635
  * onUpload={api.uploadFeedbackAttachment} fetcher={authedImageFetcher}
617
636
  * onCaptureScreenshot={captureAppScreenshot} />
618
637
  * )} … />
@@ -634,6 +653,7 @@ export function FeedbackRowDetail({
634
653
  onCaptureScreenshot,
635
654
  reworkAttachment,
636
655
  renderDate,
656
+ pageLinkExclude,
637
657
  commit,
638
658
  showSubject = true,
639
659
  onReply,
@@ -649,7 +669,6 @@ export function FeedbackRowDetail({
649
669
  // "placeholder = the dialog's body label" (§4.4.1): read from the dialog's own
650
670
  // namespace, so the two can never say different things.
651
671
  const dialogText = useKitLabels("feedbackDialog", DEFAULT_FEEDBACK_DIALOG_LABELS);
652
- const locale = useKitLocale();
653
672
  const ownStatusChange = useFeedbackStatusUndo(onUpdate);
654
673
  const changeStatus = statusChange ?? ownStatusChange;
655
674
  const [editingBody, setEditingBody] = useState(false);
@@ -660,13 +679,17 @@ export function FeedbackRowDetail({
660
679
  // rework rounds stay in the prose: they are what was said after the answer.
661
680
  const bodyText = splitBodyAttachments(row.body).text;
662
681
  const { description } = splitDescription(row.body);
663
- const pageHref = feedbackPageHref(row.context);
664
- const pageUrl = feedbackPageUrl(row.context);
682
+ const page = feedbackPage(row.context);
683
+ const pageLink = page && feedbackPageLinkTarget(page, pageLinkExclude);
665
684
  // 0.47 (§12): with the entries, each entry's file is drawn inline in the Replies
666
685
  // timeline, so the Attachment section holds the report's own files.
667
686
  const files = feedbackAttachmentUrls(row.replies ? { ...row, replies: undefined } : row);
668
687
  const fetchFile = fetcher ?? plainFeedbackFetch;
669
- const dateText = (iso: string) => (renderDate ? renderDate(iso) : formatDate(iso, "medium", { locale }));
688
+ // A date in a sentence ("Resolved: …"), so no weekday — through the kit's one day
689
+ // ladder, which reaches the provider's `formatDate` (0.52, refactor audit 2026-10-30,
690
+ // DUP-2).
691
+ const day = useDayFormatter<string>(renderDate);
692
+ const dateText = (iso: string) => day(iso);
670
693
 
671
694
  const saveDescription = (value: string) => {
672
695
  // Only a real change makes a round trip; clearing it is one ("" — the description
@@ -675,7 +698,7 @@ export function FeedbackRowDetail({
675
698
  setEditingBody(false);
676
699
  return;
677
700
  }
678
- onUpdate({ id: row.id, body: replaceDescription(row.body, value) }, { onSuccess: () => setEditingBody(false) });
701
+ runMutation(onUpdate, { id: row.id, body: replaceDescription(row.body, value) }, () => setEditingBody(false));
679
702
  };
680
703
 
681
704
  // 0.38 (§9.7): the replies replace the outcome; a row without them is a server before
@@ -735,14 +758,27 @@ export function FeedbackRowDetail({
735
758
  )}
736
759
  </FeedbackDetailSection>
737
760
 
738
- {pageHref && pageUrl && (
739
- // The page it was filed on, with the full URL a click away (keksdose #278).
761
+ {page && (
762
+ // The page it was filed on, with the full URL a click away (keksdose #278). Only
763
+ // the path is a link; the query and hash, the reporter's to write, are text — and
764
+ // a one-shot path is text too (FLW-7, 0.52 code review: see feedback-page-link).
740
765
  <FeedbackDetailSection title={labels.url}>
741
766
  <div className="flex min-w-0 items-center gap-1.5">
742
- <TextLink href={pageHref} tone="secondary" underline="hover" stopPropagation className="min-w-0">
743
- <code className="break-all text-xs">{pageHref}</code>
744
- </TextLink>
745
- <CopyButton size="xs" className="shrink-0" text={pageUrl} label={labels.copyUrl} stopPropagation />
767
+ <code
768
+ className="min-w-0 break-all text-xs text-secondary"
769
+ data-feedback-page=""
770
+ data-feedback-page-unlinked={pageLink ? undefined : ""}
771
+ >
772
+ {pageLink ? (
773
+ <TextLink href={pageLink} tone="secondary" underline="hover" stopPropagation>
774
+ {page.path}
775
+ </TextLink>
776
+ ) : (
777
+ page.path
778
+ )}
779
+ {page.href.slice(page.path.length)}
780
+ </code>
781
+ <CopyButton size="xs" className="shrink-0" text={page.url} label={labels.copyUrl} stopPropagation />
746
782
  </div>
747
783
  </FeedbackDetailSection>
748
784
  )}
@@ -9,6 +9,7 @@ import {
9
9
  } from "./feedback-labels";
10
10
  import type { FeedbackRecord } from "./feedback-record";
11
11
  import type { LabelOverride } from "../i18n/kit-labels";
12
+ import { runMutation, type FeedbackMutationCall } from "./feedback-mutation";
12
13
 
13
14
  /**
14
15
  * A status change that can be taken back — §4.5 of the feedback contract, lifted from
@@ -30,12 +31,25 @@ export interface FeedbackStatusPatch {
30
31
  }
31
32
 
32
33
  /**
33
- * The page's status mutation. **TanStack Query's `mutate` fits as it stands** — pass
34
- * `updateMutation.mutate` (stable across renders), not `mutateAsync`. A hand-written
35
- * one sends the PATCH and calls `onSuccess` once it has landed, and only then.
34
+ * The page's status mutation (0.52): **TanStack Query's `mutateAsync`** — pass
35
+ * `update.mutateAsync`. The toast comes when the promise resolves, which it does for every
36
+ * call (refactor audit 2026-10-30, FLW-3). A hand-written one returns a promise that
37
+ * resolves once the PATCH has landed and rejects when it failed.
36
38
  *
37
39
  * Failure is the mutation's own business: its `onError` toasts the server's `detail`,
38
- * else `feedbackToast.updateFailed` (§4.4) — this hook adds no second error toast.
40
+ * else `feedbackToast.updateFailed` (§4.4) — this hook adds no second error toast, and
41
+ * catches the rejection.
42
+ */
43
+ export type FeedbackStatusMutateAsync = (patch: FeedbackStatusPatch) => Promise<unknown>;
44
+
45
+ /**
46
+ * The callback form: TanStack Query's `mutate`, or a function that calls `onSuccess` once
47
+ * the PATCH has landed. TanStack calls a per-call `onSuccess` for the LATEST `mutate()` on
48
+ * its observer only, so a second change sent before the first answered — another swipe,
49
+ * another pill, the Undo itself — lost the first change's Undo toast.
50
+ *
51
+ * @deprecated 0.52 — pass `update.mutateAsync` ({@link FeedbackStatusMutateAsync}), whose
52
+ * promise settles for every call; removed in 0.53
39
53
  */
40
54
  export type FeedbackStatusMutate = (patch: FeedbackStatusPatch, callbacks: { onSuccess: () => void }) => void;
41
55
 
@@ -64,20 +78,26 @@ export const FEEDBACK_UNDO_DURATION = 8000;
64
78
  *
65
79
  * ```tsx
66
80
  * const update = useMutation({ mutationFn: api.updateFeedback, onError: … });
67
- * const changeStatus = useFeedbackStatusUndo(update.mutate);
81
+ * const changeStatus = useFeedbackStatusUndo(update.mutateAsync);
68
82
  * <FeedbackStatusTransitions … onPick={(status) => changeStatus(row, status)} />
69
83
  * ```
70
84
  *
71
- * Give it the PAGE's mutation, not one a row owns: TanStack only calls per-call
72
- * callbacks while the observer that started the mutation is mounted, and a row the new
73
- * status filters out unmounts before the PATCH answers — the toast would never come.
85
+ * Give it the PAGE's mutation, not one a row owns: a row the new status filters out
86
+ * unmounts before the PATCH answers.
74
87
  *
75
- * The flow: PATCH `{ id, status }` → on success a success toast
88
+ * The flow: PATCH `{ id, status }` → once it has landed a success toast
76
89
  * `statusChanged(newName, title)` with the action `statusUndo`, 8 s → Undo PATCHes
77
- * `{ id, status: previous }` → on success `statusRestored(previousName, title)`.
90
+ * `{ id, status: previous }` → once that has landed `statusRestored(previousName, title)`.
91
+ * Each change waits for its OWN answer, so two changes in flight each get their toast.
92
+ *
93
+ * `update.mutate` ({@link FeedbackStatusMutate}) still fits, deprecated since 0.52: with it
94
+ * a second change before the first answered loses the first one's Undo. One signature
95
+ * takes both rather than two overloads: TypeScript types an inline callback's parameters
96
+ * from the FIRST overload, so a hand-written `(patch, { onSuccess }) => …` — the form this
97
+ * hook documented until 0.52 — would no longer compile.
78
98
  */
79
99
  export function useFeedbackStatusUndo(
80
- mutate: FeedbackStatusMutate,
100
+ mutate: FeedbackMutationCall<FeedbackStatusPatch>,
81
101
  { labels, statusLabels }: FeedbackStatusUndoOptions = {},
82
102
  ): FeedbackStatusChange {
83
103
  const words = useFeedbackToastLabels(labels);
@@ -87,22 +107,16 @@ export function useFeedbackStatusUndo(
87
107
  const { id, title, status: previous } = row;
88
108
  if (status === previous) return;
89
109
  const nameOf = (value: FeedbackStatus) => names[value] ?? value;
90
- mutate(
91
- { id, status },
92
- {
93
- onSuccess: () => {
94
- toast.undo(words.statusChanged(nameOf(status), title), {
95
- label: words.statusUndo,
96
- duration: FEEDBACK_UNDO_DURATION,
97
- onUndo: () =>
98
- mutate(
99
- { id, status: previous },
100
- { onSuccess: () => void toast.success(words.statusRestored(nameOf(previous), title)) },
101
- ),
102
- });
103
- },
104
- },
105
- );
110
+ runMutation(mutate, { id, status }, () => {
111
+ toast.undo(words.statusChanged(nameOf(status), title), {
112
+ label: words.statusUndo,
113
+ duration: FEEDBACK_UNDO_DURATION,
114
+ onUndo: () =>
115
+ runMutation(mutate, { id, status: previous }, () => {
116
+ toast.success(words.statusRestored(nameOf(previous), title));
117
+ }),
118
+ });
119
+ });
106
120
  },
107
121
  [mutate, words, names],
108
122
  );
@@ -37,7 +37,7 @@ export interface FeedbackSubmitDialogProps {
37
37
  onCategoryChange: (category: FeedbackCategory) => void;
38
38
  submitting: boolean;
39
39
  /** The form, and the `context` built from the same values the box showed. */
40
- onSubmit: (data: FeedbackMultipleSubmission, context: FeedbackContext) => void | Promise<void>;
40
+ onSubmit: (data: FeedbackMultipleSubmission<FeedbackCategory>, context: FeedbackContext) => void | Promise<void>;
41
41
  user?: FeedbackSubmitter | null;
42
42
  /** `location.href` when the dialog opened. */
43
43
  url: string;
@@ -89,7 +89,7 @@ export function FeedbackSubmitDialog({
89
89
  onClose={onClose}
90
90
  categories={FEEDBACK_PICKABLE_CATEGORIES.map((value) => ({ value, label: categoryLabels[value] }))}
91
91
  category={category}
92
- onCategoryChange={(value) => onCategoryChange(value as FeedbackCategory)}
92
+ onCategoryChange={onCategoryChange}
93
93
  submitting={submitting}
94
94
  attachments="multiple"
95
95
  maxAttachments={DEFAULT_MAX_ATTACHMENTS}
@@ -1,8 +1,10 @@
1
- import { lazy, Suspense, useRef, useState } from "react";
1
+ import { Suspense, useLayoutEffect, useRef, useState } from "react";
2
2
  import type { ReactNode } from "react";
3
3
  import { toast } from "../components/toast";
4
+ import { lazyWithFallback } from "../lib/lazy-with-fallback";
4
5
  // Types only, gone from the built module: the dialog's modules load with the dialog.
5
6
  import type { FeedbackSubmitter } from "./feedback-context";
7
+ import type { FeedbackSubmitDialogProps } from "./feedback-submit-dialog";
6
8
  import type { FeedbackMultipleSubmission } from "./feedback-dialog";
7
9
  import { useFeedbackToastLabels } from "./feedback-labels";
8
10
  import { FEEDBACK_PICKABLE_CATEGORIES, type FeedbackContext, type FeedbackEnvironment } from "./feedback-record";
@@ -14,11 +16,22 @@ import type { FeedbackCategory } from "./feedback-vocabulary";
14
16
  * LITERAL relative `import()`, as the catalogue loaders are (i18n/languages.ts): the
15
17
  * library build keeps the module its own (`bundle: false`), and a path an app's bundler
16
18
  * can read is a chunk it can split off.
19
+ *
20
+ * A fetch that fails — a tab left open across a deploy, offline — closes the dialog
21
+ * rather than throwing (0.52 code review, tour.tsx): the hook lives in the top bar, above
22
+ * the routes' error boundaries, so the rejected import took the whole shell down. The
23
+ * next open fetches again.
17
24
  */
18
- const LazySubmitDialog = lazy(() =>
19
- import("./feedback-submit-dialog").then((module) => ({ default: module.FeedbackSubmitDialog })),
25
+ const LazySubmitDialog = lazyWithFallback(
26
+ () => import("./feedback-submit-dialog").then((module) => module.FeedbackSubmitDialog),
27
+ SubmitDialogUnavailable,
20
28
  );
21
29
 
30
+ function SubmitDialogUnavailable({ onClose }: FeedbackSubmitDialogProps) {
31
+ useLayoutEffect(onClose, [onClose]);
32
+ return null;
33
+ }
34
+
22
35
  /**
23
36
  * `FeedbackCreate` — the body of `POST /feedback` (keksdose `schemas/feedback.py:25`, §3.4
24
37
  * of docs/feedback-harmonization.md), as {@link useFeedbackSubmit} hands it to the app's
@@ -165,7 +178,7 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
165
178
  const close = () => setIsOpen(false);
166
179
 
167
180
  // `context` comes from the dialog, built off the values its context box shows.
168
- const submit = async (data: FeedbackMultipleSubmission, context: FeedbackContext) => {
181
+ const submit = async (data: FeedbackMultipleSubmission<FeedbackCategory>, context: FeedbackContext) => {
169
182
  if (inFlight.current) return;
170
183
  inFlight.current = true;
171
184
  setSubmitting(true);
@@ -179,7 +192,7 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
179
192
  result = await create({
180
193
  title: data.title.trim(),
181
194
  body: data.body.trim() ? data.body : "",
182
- category: data.category as FeedbackCategory,
195
+ category: data.category,
183
196
  context,
184
197
  screenshot_url,
185
198
  attachment_urls,
@@ -197,8 +210,9 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
197
210
  };
198
211
 
199
212
  // Nothing is drawn while the dialog's module is on its way — a few milliseconds, once per
200
- // page load; a spinner would only flash. A load that fails (a deploy replaced the chunk)
201
- // throws a chunk-load error to the app's error boundary, as a lazy route's does.
213
+ // page load; a spinner would only flash. A load that fails (a deploy replaced the chunk,
214
+ // offline) closes the dialog (`SubmitDialogUnavailable`): the hook sits in the top bar,
215
+ // above the routes' error boundaries, where a thrown chunk error took the shell down.
202
216
  const dialog = isOpen ? (
203
217
  <Suspense fallback={null}>
204
218
  <LazySubmitDialog
@@ -124,7 +124,7 @@ function panel(
124
124
  * for it, or `null` when the row offers no swipe at all:
125
125
  *
126
126
  * ```tsx
127
- * const changeStatus = useFeedbackStatusUndo(update.mutate);
127
+ * const changeStatus = useFeedbackStatusUndo(update.mutateAsync);
128
128
  * const statusLabels = useFeedbackStatusLabels();
129
129
  * <DataTable
130
130
  * mobileSwipeActions={isAdmin && !mine