@eifi1/ui-kit 0.54.0 → 0.55.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 (847) hide show
  1. package/README.md +90 -76
  2. package/dist/admin/plan-change.js +2 -2
  3. package/dist/admin/plan-change.js.map +1 -1
  4. package/dist/admin/user-roster.d.ts +6 -0
  5. package/dist/admin/user-roster.js +4 -0
  6. package/dist/admin/user-roster.js.map +1 -1
  7. package/dist/billing/billing-labels.d.ts +26 -0
  8. package/dist/billing/billing-labels.js +9 -0
  9. package/dist/billing/billing-labels.js.map +1 -1
  10. package/dist/billing/subscription-standing.d.ts +61 -0
  11. package/dist/billing/subscription-standing.js +51 -0
  12. package/dist/billing/subscription-standing.js.map +1 -0
  13. package/dist/billing/usage-meter.d.ts +52 -0
  14. package/dist/billing/usage-meter.js +52 -0
  15. package/dist/billing/usage-meter.js.map +1 -0
  16. package/dist/chart.d.ts +1 -0
  17. package/dist/chart.js +4 -0
  18. package/dist/chart.js.map +1 -1
  19. package/dist/components/alert-banner.js +2 -3
  20. package/dist/components/alert-banner.js.map +1 -1
  21. package/dist/components/amount-input.js +3 -15
  22. package/dist/components/amount-input.js.map +1 -1
  23. package/dist/components/autocomplete.js +2 -2
  24. package/dist/components/autocomplete.js.map +1 -1
  25. package/dist/components/bulk-action-bar.js +2 -1
  26. package/dist/components/bulk-action-bar.js.map +1 -1
  27. package/dist/components/button.d.ts +35 -1
  28. package/dist/components/button.js +5 -9
  29. package/dist/components/button.js.map +1 -1
  30. package/dist/components/calendar-heatmap.js +2 -2
  31. package/dist/components/calendar-heatmap.js.map +1 -1
  32. package/dist/components/camera-button.d.ts +89 -0
  33. package/dist/components/camera-button.js +122 -0
  34. package/dist/components/camera-button.js.map +1 -0
  35. package/dist/components/camera-capture.d.ts +66 -0
  36. package/dist/components/camera-capture.js +190 -0
  37. package/dist/components/camera-capture.js.map +1 -0
  38. package/dist/components/camera-labels.d.ts +20 -0
  39. package/dist/components/camera-labels.js +15 -0
  40. package/dist/components/camera-labels.js.map +1 -0
  41. package/dist/components/chart-edge.d.ts +9 -0
  42. package/dist/components/chart-edge.js +14 -3
  43. package/dist/components/chart-edge.js.map +1 -1
  44. package/dist/components/chart-zoom-core.js +34 -29
  45. package/dist/components/chart-zoom-core.js.map +1 -1
  46. package/dist/components/checkbox-group.js +1 -1
  47. package/dist/components/checkbox-group.js.map +1 -1
  48. package/dist/components/combobox-core.js +3 -2
  49. package/dist/components/combobox-core.js.map +1 -1
  50. package/dist/components/combobox.js +2 -2
  51. package/dist/components/combobox.js.map +1 -1
  52. package/dist/components/consent-again-notice-labels.d.ts +25 -0
  53. package/dist/components/consent-again-notice-labels.js +15 -0
  54. package/dist/components/consent-again-notice-labels.js.map +1 -0
  55. package/dist/components/consent-again-notice.d.ts +85 -0
  56. package/dist/components/consent-again-notice.js +94 -0
  57. package/dist/components/consent-again-notice.js.map +1 -0
  58. package/dist/components/country-select.js +2 -7
  59. package/dist/components/country-select.js.map +1 -1
  60. package/dist/components/currency-select.js +2 -2
  61. package/dist/components/currency-select.js.map +1 -1
  62. package/dist/components/danger-confirm.js +2 -2
  63. package/dist/components/danger-confirm.js.map +1 -1
  64. package/dist/components/data-table-column-settings.js +2 -2
  65. package/dist/components/data-table-column-settings.js.map +1 -1
  66. package/dist/components/data-table-fit.js.map +1 -1
  67. package/dist/components/data-table-virtual.js +13 -3
  68. package/dist/components/data-table-virtual.js.map +1 -1
  69. package/dist/components/date-field.js +2 -2
  70. package/dist/components/date-field.js.map +1 -1
  71. package/dist/components/date-picker.js +2 -2
  72. package/dist/components/date-picker.js.map +1 -1
  73. package/dist/components/date-range-picker.js +2 -6
  74. package/dist/components/date-range-picker.js.map +1 -1
  75. package/dist/components/dialog-frame.d.ts +3 -1
  76. package/dist/components/dialog-frame.js.map +1 -1
  77. package/dist/components/dropdown.js +7 -3
  78. package/dist/components/dropdown.js.map +1 -1
  79. package/dist/components/entity-combobox.js +2 -2
  80. package/dist/components/entity-combobox.js.map +1 -1
  81. package/dist/components/field-parts.d.ts +108 -6
  82. package/dist/components/field-parts.js +59 -6
  83. package/dist/components/field-parts.js.map +1 -1
  84. package/dist/components/field-suggestion-labels.d.ts +2 -0
  85. package/dist/components/field-suggestion-labels.js +10 -0
  86. package/dist/components/field-suggestion-labels.js.map +1 -0
  87. package/dist/components/field.js +1 -1
  88. package/dist/components/field.js.map +1 -1
  89. package/dist/components/file-button.d.ts +1 -1
  90. package/dist/components/file-button.js.map +1 -1
  91. package/dist/components/floating-panel.d.ts +7 -6
  92. package/dist/components/floating-panel.js +3 -17
  93. package/dist/components/floating-panel.js.map +1 -1
  94. package/dist/components/form-actions.d.ts +3 -2
  95. package/dist/components/form-actions.js.map +1 -1
  96. package/dist/components/hover-menu.js +3 -2
  97. package/dist/components/hover-menu.js.map +1 -1
  98. package/dist/components/icon-button.d.ts +23 -5
  99. package/dist/components/icon-button.js +6 -8
  100. package/dist/components/icon-button.js.map +1 -1
  101. package/dist/components/inline-confirm.js +2 -1
  102. package/dist/components/inline-confirm.js.map +1 -1
  103. package/dist/components/inline-entity-combobox.js +2 -2
  104. package/dist/components/inline-entity-combobox.js.map +1 -1
  105. package/dist/components/input.js +2 -2
  106. package/dist/components/input.js.map +1 -1
  107. package/dist/components/jump-calendar.js +3 -3
  108. package/dist/components/jump-calendar.js.map +1 -1
  109. package/dist/components/legal.d.ts +13 -1
  110. package/dist/components/legal.js +12 -0
  111. package/dist/components/legal.js.map +1 -1
  112. package/dist/components/legended-series-chart.d.ts +80 -0
  113. package/dist/components/legended-series-chart.js +70 -0
  114. package/dist/components/legended-series-chart.js.map +1 -0
  115. package/dist/components/lightbox.js +2 -1
  116. package/dist/components/lightbox.js.map +1 -1
  117. package/dist/components/mini-calendar.js +13 -5
  118. package/dist/components/mini-calendar.js.map +1 -1
  119. package/dist/components/modal.d.ts +23 -2
  120. package/dist/components/modal.js +24 -6
  121. package/dist/components/modal.js.map +1 -1
  122. package/dist/components/month-picker.d.ts +1 -1
  123. package/dist/components/month-picker.js +6 -6
  124. package/dist/components/month-picker.js.map +1 -1
  125. package/dist/components/multi-entity-combobox.js +2 -2
  126. package/dist/components/multi-entity-combobox.js.map +1 -1
  127. package/dist/components/multi-select.js +2 -6
  128. package/dist/components/multi-select.js.map +1 -1
  129. package/dist/components/number-input.js +2 -2
  130. package/dist/components/number-input.js.map +1 -1
  131. package/dist/components/page-header-layout.d.ts +18 -0
  132. package/dist/components/page-header-layout.js +23 -0
  133. package/dist/components/page-header-layout.js.map +1 -0
  134. package/dist/components/page-header-skeleton.d.ts +41 -0
  135. package/dist/components/page-header-skeleton.js +52 -0
  136. package/dist/components/page-header-skeleton.js.map +1 -0
  137. package/dist/components/page-header.js +4 -17
  138. package/dist/components/page-header.js.map +1 -1
  139. package/dist/components/popover.js +7 -2
  140. package/dist/components/popover.js.map +1 -1
  141. package/dist/components/release-notes-labels.d.ts +16 -0
  142. package/dist/components/release-notes-labels.js +18 -0
  143. package/dist/components/release-notes-labels.js.map +1 -0
  144. package/dist/components/release-notes.d.ts +65 -0
  145. package/dist/components/release-notes.js +65 -0
  146. package/dist/components/release-notes.js.map +1 -0
  147. package/dist/components/select.js +2 -2
  148. package/dist/components/select.js.map +1 -1
  149. package/dist/components/series-chart-labels.d.ts +9 -0
  150. package/dist/components/series-chart-labels.js +3 -1
  151. package/dist/components/series-chart-labels.js.map +1 -1
  152. package/dist/components/series-chart.d.ts +5 -0
  153. package/dist/components/series-chart.js +89 -36
  154. package/dist/components/series-chart.js.map +1 -1
  155. package/dist/components/toggle-group.js +3 -2
  156. package/dist/components/toggle-group.js.map +1 -1
  157. package/dist/components/treemap-layout.js.map +1 -1
  158. package/dist/components/treemap.d.ts +17 -15
  159. package/dist/components/treemap.js +167 -85
  160. package/dist/components/treemap.js.map +1 -1
  161. package/dist/eslint/index.js +1 -1
  162. package/dist/eslint/role-utilities.d.ts +2 -2
  163. package/dist/eslint/role-utilities.js.map +1 -1
  164. package/dist/feedback/feedback-inbox-page.d.ts +260 -0
  165. package/dist/feedback/feedback-inbox-page.js +207 -0
  166. package/dist/feedback/feedback-inbox-page.js.map +1 -0
  167. package/dist/feedback/feedback-vocabulary.js +2 -2
  168. package/dist/feedback/feedback-vocabulary.js.map +1 -1
  169. package/dist/feedback.d.ts +1 -0
  170. package/dist/feedback.js +6 -0
  171. package/dist/feedback.js.map +1 -1
  172. package/dist/hooks/use-debounce.d.ts +32 -5
  173. package/dist/hooks/use-debounce.js +6 -5
  174. package/dist/hooks/use-debounce.js.map +1 -1
  175. package/dist/hooks/use-file-picker.d.ts +3 -1
  176. package/dist/hooks/use-file-picker.js.map +1 -1
  177. package/dist/hooks/use-focus-trap.d.ts +19 -3
  178. package/dist/hooks/use-focus-trap.js +15 -5
  179. package/dist/hooks/use-focus-trap.js.map +1 -1
  180. package/dist/hooks/use-has-camera.d.ts +36 -0
  181. package/dist/hooks/use-has-camera.js +53 -0
  182. package/dist/hooks/use-has-camera.js.map +1 -0
  183. package/dist/hooks/use-hotkey.js +1 -10
  184. package/dist/hooks/use-hotkey.js.map +1 -1
  185. package/dist/hooks/use-overlay-history.d.ts +6 -1
  186. package/dist/hooks/use-overlay-history.js +10 -2
  187. package/dist/hooks/use-overlay-history.js.map +1 -1
  188. package/dist/i18n/defaults.js +11 -1
  189. package/dist/i18n/defaults.js.map +1 -1
  190. package/dist/i18n/german.js +75 -3
  191. package/dist/i18n/german.js.map +1 -1
  192. package/dist/i18n/kit-labels.d.ts +20 -0
  193. package/dist/i18n/kit-labels.js.map +1 -1
  194. package/dist/i18n/locales/en.js +92 -4
  195. package/dist/i18n/locales/en.js.map +3 -3
  196. package/dist/i18n/locales/es.js +71 -3
  197. package/dist/i18n/locales/es.js.map +1 -1
  198. package/dist/i18n/locales/fr.js +72 -2
  199. package/dist/i18n/locales/fr.js.map +1 -1
  200. package/dist/i18n/locales/hu.js +74 -3
  201. package/dist/i18n/locales/hu.js.map +1 -1
  202. package/dist/i18n/locales/it.js +74 -3
  203. package/dist/i18n/locales/it.js.map +1 -1
  204. package/dist/i18n/locales/zh.js +71 -3
  205. package/dist/i18n/locales/zh.js.map +1 -1
  206. package/dist/i18n/review.js +22 -1
  207. package/dist/i18n/review.js.map +1 -1
  208. package/dist/index.d.ts +24 -5
  209. package/dist/index.js +35 -1
  210. package/dist/index.js.map +1 -1
  211. package/dist/landing/landing-labels.d.ts +8 -0
  212. package/dist/landing/landing-labels.js +2 -1
  213. package/dist/landing/landing-labels.js.map +1 -1
  214. package/dist/lib/changelog.d.ts +130 -0
  215. package/dist/lib/changelog.js +137 -0
  216. package/dist/lib/changelog.js.map +1 -0
  217. package/dist/lib/clipboard-minus.js +2 -2
  218. package/dist/lib/clipboard-minus.js.map +1 -1
  219. package/dist/lib/dates.d.ts +29 -3
  220. package/dist/lib/dates.js +41 -12
  221. package/dist/lib/dates.js.map +1 -1
  222. package/dist/lib/editable-content.d.ts +33 -0
  223. package/dist/lib/editable-content.js +15 -0
  224. package/dist/lib/editable-content.js.map +1 -0
  225. package/dist/lib/focus-left.d.ts +47 -1
  226. package/dist/lib/focus-left.js +11 -2
  227. package/dist/lib/focus-left.js.map +1 -1
  228. package/dist/lib/server-wake.d.ts +49 -9
  229. package/dist/lib/server-wake.js +25 -14
  230. package/dist/lib/server-wake.js.map +1 -1
  231. package/dist/lib/session-refresh.d.ts +53 -0
  232. package/dist/lib/session-refresh.js +27 -1
  233. package/dist/lib/session-refresh.js.map +1 -1
  234. package/dist/rhf/fields.js +3 -3
  235. package/dist/rhf/fields.js.map +1 -1
  236. package/dist/shell/app-shell.d.ts +25 -1
  237. package/dist/shell/app-shell.js +3 -1
  238. package/dist/shell/app-shell.js.map +1 -1
  239. package/dist/shell/dev-menu.d.ts +3 -0
  240. package/dist/shell/dev-menu.js +4 -2
  241. package/dist/shell/dev-menu.js.map +1 -1
  242. package/dist/shell/held-changes-banner-labels.d.ts +23 -0
  243. package/dist/shell/held-changes-banner-labels.js +14 -0
  244. package/dist/shell/held-changes-banner-labels.js.map +1 -0
  245. package/dist/shell/held-changes-banner.d.ts +75 -0
  246. package/dist/shell/held-changes-banner.js +106 -0
  247. package/dist/shell/held-changes-banner.js.map +1 -0
  248. package/dist/shell/sync-status-indicator.d.ts +27 -12
  249. package/dist/shell/sync-status-indicator.js +13 -4
  250. package/dist/shell/sync-status-indicator.js.map +1 -1
  251. package/dist/shell/top-bar-parts-labels.d.ts +5 -0
  252. package/dist/shell/top-bar-parts-labels.js +3 -1
  253. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  254. package/dist/shell.d.ts +2 -0
  255. package/dist/shell.js +3 -0
  256. package/dist/shell.js.map +1 -1
  257. package/dist/sync/engine.d.ts +11 -2
  258. package/dist/sync/engine.js +13 -5
  259. package/dist/sync/engine.js.map +1 -1
  260. package/dist/sync/hooks.d.ts +3 -2
  261. package/dist/sync/hooks.js +4 -2
  262. package/dist/sync/hooks.js.map +1 -1
  263. package/dist/testing/css-variables.generated.d.ts +2 -2
  264. package/dist/testing/css-variables.generated.js +1 -1
  265. package/dist/testing/css-variables.generated.js.map +1 -1
  266. package/dist/theme/chart-palette.d.ts +18 -0
  267. package/dist/theme/chart-palette.js +17 -1
  268. package/dist/theme/chart-palette.js.map +1 -1
  269. package/dist/theme/contrast-tokens.d.ts +3 -3
  270. package/dist/theme/contrast-tokens.js.map +1 -1
  271. package/dist/theme/contrast.d.ts +4 -4
  272. package/dist/theme/contrast.js.map +1 -1
  273. package/dist/tour/tour-overlay.js +2 -1
  274. package/dist/tour/tour-overlay.js.map +1 -1
  275. package/package.json +5 -9
  276. package/tokens.css +19 -54
  277. package/src/account/account-parts.ts +0 -47
  278. package/src/account/account-settings-labels.ts +0 -240
  279. package/src/account/account-settings.tsx +0 -698
  280. package/src/account/data-export-setting-labels.ts +0 -20
  281. package/src/account/data-export-setting.tsx +0 -200
  282. package/src/account/delete-account-setting-labels.ts +0 -33
  283. package/src/account/delete-account-setting.tsx +0 -342
  284. package/src/account/email-change-setting-labels.ts +0 -31
  285. package/src/account/email-change-setting.tsx +0 -443
  286. package/src/account/passkeys-setting.tsx +0 -445
  287. package/src/account/sessions-setting-labels.ts +0 -24
  288. package/src/account/sessions-setting.tsx +0 -283
  289. package/src/admin/admin-action-confirm-labels.ts +0 -19
  290. package/src/admin/admin-action-confirm.tsx +0 -509
  291. package/src/admin/admin-action-log-labels.ts +0 -83
  292. package/src/admin/admin-action-log.tsx +0 -464
  293. package/src/admin/admin-area-labels.ts +0 -114
  294. package/src/admin/admin-forbidden.tsx +0 -75
  295. package/src/admin/admin-overview.tsx +0 -258
  296. package/src/admin/admin-parts.ts +0 -68
  297. package/src/admin/admin-sections.tsx +0 -208
  298. package/src/admin/admin-tool-links.tsx +0 -90
  299. package/src/admin/invitations-panel-labels.ts +0 -31
  300. package/src/admin/invitations-panel.tsx +0 -516
  301. package/src/admin/mail-test-card-labels.ts +0 -19
  302. package/src/admin/mail-test-card.tsx +0 -189
  303. package/src/admin/plan-change-labels.ts +0 -5
  304. package/src/admin/plan-change.tsx +0 -474
  305. package/src/admin/reviewer-scope-editor-labels.ts +0 -16
  306. package/src/admin/reviewer-scope-editor.tsx +0 -224
  307. package/src/admin/role-select-labels.ts +0 -16
  308. package/src/admin/role-select.tsx +0 -282
  309. package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
  310. package/src/admin/transfer-ownership-dialog.tsx +0 -162
  311. package/src/admin/user-roster-labels.ts +0 -17
  312. package/src/admin/user-roster.tsx +0 -559
  313. package/src/auth/accept-invitation-labels.ts +0 -21
  314. package/src/auth/accept-invitation.tsx +0 -210
  315. package/src/auth/auth-errors-labels.ts +0 -23
  316. package/src/auth/auth-errors.ts +0 -439
  317. package/src/auth/complete-name-dialog-labels.ts +0 -16
  318. package/src/auth/complete-name-dialog.tsx +0 -253
  319. package/src/auth/email-tag.ts +0 -75
  320. package/src/auth/forgot-password-form-labels.ts +0 -20
  321. package/src/auth/forgot-password-form.tsx +0 -221
  322. package/src/auth/form-rules.ts +0 -40
  323. package/src/auth/new-password-fields.tsx +0 -85
  324. package/src/auth/not-found-page-labels.ts +0 -12
  325. package/src/auth/not-found-page.tsx +0 -95
  326. package/src/auth/register-form-labels.ts +0 -31
  327. package/src/auth/register-form.tsx +0 -456
  328. package/src/auth/reset-password-form-labels.ts +0 -27
  329. package/src/auth/reset-password-form.tsx +0 -341
  330. package/src/auth/sign-in-form-labels.ts +0 -44
  331. package/src/auth/sign-in-form.tsx +0 -858
  332. package/src/auth/status-parts.tsx +0 -132
  333. package/src/auth/verify-email-labels.ts +0 -26
  334. package/src/auth/verify-email.tsx +0 -445
  335. package/src/billing/billing-banner.tsx +0 -258
  336. package/src/billing/billing-labels.ts +0 -381
  337. package/src/billing/billing-lock.ts +0 -108
  338. package/src/billing/billing-overview.ts +0 -157
  339. package/src/billing/billing-standing.ts +0 -80
  340. package/src/billing/cancel-request.ts +0 -97
  341. package/src/billing/cancel-subscription.tsx +0 -98
  342. package/src/billing/checkout-processing.ts +0 -394
  343. package/src/billing/checkout-return.ts +0 -90
  344. package/src/billing/pay-page.ts +0 -330
  345. package/src/billing/plan-card.tsx +0 -562
  346. package/src/billing/plan-change-labels.ts +0 -66
  347. package/src/billing/plan-limit-notice.tsx +0 -148
  348. package/src/billing/plan-limit-toast.tsx +0 -90
  349. package/src/billing/plan-limit.ts +0 -52
  350. package/src/billing/plan-price.ts +0 -98
  351. package/src/billing/plan-switch.tsx +0 -216
  352. package/src/billing/provider-page.ts +0 -84
  353. package/src/billing/subscription-actions.tsx +0 -247
  354. package/src/billing/subscription-status-chip.tsx +0 -95
  355. package/src/chart.ts +0 -103
  356. package/src/components/account-chips-labels.ts +0 -16
  357. package/src/components/account-chips.tsx +0 -474
  358. package/src/components/alert-banner.tsx +0 -670
  359. package/src/components/amount-input.tsx +0 -816
  360. package/src/components/appearance-labels.ts +0 -63
  361. package/src/components/authed-image-labels.ts +0 -11
  362. package/src/components/authed-image.tsx +0 -209
  363. package/src/components/autocomplete.tsx +0 -645
  364. package/src/components/breadcrumbs-labels.ts +0 -10
  365. package/src/components/breadcrumbs.tsx +0 -205
  366. package/src/components/bulk-action-bar-labels.ts +0 -11
  367. package/src/components/bulk-action-bar.tsx +0 -443
  368. package/src/components/button-group.tsx +0 -223
  369. package/src/components/button-look.ts +0 -256
  370. package/src/components/button.tsx +0 -339
  371. package/src/components/calculator.tsx +0 -341
  372. package/src/components/calendar-heatmap-labels.ts +0 -15
  373. package/src/components/calendar-heatmap.tsx +0 -600
  374. package/src/components/card.tsx +0 -377
  375. package/src/components/chart-edge.ts +0 -106
  376. package/src/components/chart-figure.tsx +0 -35
  377. package/src/components/chart-height.ts +0 -30
  378. package/src/components/chart-zoom-core.tsx +0 -627
  379. package/src/components/chart-zoom.tsx +0 -22
  380. package/src/components/chart.tsx +0 -554
  381. package/src/components/checkbox-group.tsx +0 -247
  382. package/src/components/checkbox.tsx +0 -346
  383. package/src/components/chip-input.tsx +0 -370
  384. package/src/components/chip-labels.ts +0 -13
  385. package/src/components/chip.tsx +0 -843
  386. package/src/components/choice-card.tsx +0 -544
  387. package/src/components/column-mapper-labels.ts +0 -38
  388. package/src/components/column-mapper.tsx +0 -655
  389. package/src/components/combobox-core.tsx +0 -1321
  390. package/src/components/combobox-suggestions.tsx +0 -131
  391. package/src/components/combobox.tsx +0 -716
  392. package/src/components/confirm-context.ts +0 -7
  393. package/src/components/confirm-dialog-labels.ts +0 -13
  394. package/src/components/confirm-dialog.tsx +0 -341
  395. package/src/components/copy-button-labels.ts +0 -13
  396. package/src/components/copy-button.tsx +0 -192
  397. package/src/components/country-select-labels.ts +0 -11
  398. package/src/components/country-select.tsx +0 -539
  399. package/src/components/currency-option-list.tsx +0 -188
  400. package/src/components/currency-select.tsx +0 -343
  401. package/src/components/danger-confirm-labels.ts +0 -20
  402. package/src/components/danger-confirm.tsx +0 -987
  403. package/src/components/data-table-cells.tsx +0 -118
  404. package/src/components/data-table-column-settings.tsx +0 -198
  405. package/src/components/data-table-filter-popover.tsx +0 -289
  406. package/src/components/data-table-filters.ts +0 -315
  407. package/src/components/data-table-fit.ts +0 -301
  408. package/src/components/data-table-groups.tsx +0 -288
  409. package/src/components/data-table-head.tsx +0 -280
  410. package/src/components/data-table-labels.ts +0 -198
  411. package/src/components/data-table-leading-row.tsx +0 -58
  412. package/src/components/data-table-mobile.tsx +0 -1117
  413. package/src/components/data-table-pagination.tsx +0 -202
  414. package/src/components/data-table-resize.ts +0 -188
  415. package/src/components/data-table-row-actions.tsx +0 -302
  416. package/src/components/data-table-row.tsx +0 -496
  417. package/src/components/data-table-selection.ts +0 -71
  418. package/src/components/data-table-shared.tsx +0 -287
  419. package/src/components/data-table-sort.ts +0 -163
  420. package/src/components/data-table-virtual.ts +0 -576
  421. package/src/components/data-table.tsx +0 -2598
  422. package/src/components/date-field.tsx +0 -684
  423. package/src/components/date-format-setting.tsx +0 -64
  424. package/src/components/date-picker.tsx +0 -404
  425. package/src/components/date-range-picker.tsx +0 -518
  426. package/src/components/description-list-labels.ts +0 -9
  427. package/src/components/description-list.tsx +0 -386
  428. package/src/components/dialog-frame-labels.ts +0 -7
  429. package/src/components/dialog-frame.tsx +0 -284
  430. package/src/components/disclosure.tsx +0 -476
  431. package/src/components/dropdown.tsx +0 -461
  432. package/src/components/empty-state.tsx +0 -136
  433. package/src/components/entity-combobox.tsx +0 -422
  434. package/src/components/error-boundary-labels.ts +0 -20
  435. package/src/components/error-boundary.tsx +0 -675
  436. package/src/components/facing-pair.ts +0 -93
  437. package/src/components/field-base-labels.ts +0 -20
  438. package/src/components/field-base.tsx +0 -656
  439. package/src/components/field-parts.tsx +0 -825
  440. package/src/components/field-strip.tsx +0 -129
  441. package/src/components/field.tsx +0 -206
  442. package/src/components/file-button.tsx +0 -295
  443. package/src/components/file-dropzone.tsx +0 -559
  444. package/src/components/floating-panel-labels.ts +0 -10
  445. package/src/components/floating-panel.tsx +0 -828
  446. package/src/components/focus-ring.ts +0 -16
  447. package/src/components/form-actions-labels.ts +0 -11
  448. package/src/components/form-actions.tsx +0 -578
  449. package/src/components/full-bleed-dialog.tsx +0 -294
  450. package/src/components/grouped-picker.tsx +0 -184
  451. package/src/components/help-popover.tsx +0 -117
  452. package/src/components/hover-menu.tsx +0 -343
  453. package/src/components/iban-input-labels.ts +0 -14
  454. package/src/components/iban-input.tsx +0 -236
  455. package/src/components/icon-button.tsx +0 -959
  456. package/src/components/icon-picker-labels.ts +0 -13
  457. package/src/components/icon-picker.tsx +0 -232
  458. package/src/components/image-grid-labels.ts +0 -11
  459. package/src/components/image-grid.tsx +0 -202
  460. package/src/components/inline-confirm.tsx +0 -116
  461. package/src/components/inline-edit-field-labels.ts +0 -11
  462. package/src/components/inline-edit-field.tsx +0 -552
  463. package/src/components/inline-entity-combobox.tsx +0 -849
  464. package/src/components/input.tsx +0 -394
  465. package/src/components/jump-calendar.tsx +0 -265
  466. package/src/components/language-select.tsx +0 -93
  467. package/src/components/legal-labels.ts +0 -105
  468. package/src/components/legal-page.tsx +0 -711
  469. package/src/components/legal.tsx +0 -668
  470. package/src/components/lightbox-labels.ts +0 -18
  471. package/src/components/lightbox.tsx +0 -399
  472. package/src/components/line-items-labels.ts +0 -14
  473. package/src/components/line-items.tsx +0 -602
  474. package/src/components/list-labels.ts +0 -12
  475. package/src/components/list.tsx +0 -870
  476. package/src/components/loading-state.tsx +0 -78
  477. package/src/components/measured-grid-labels.ts +0 -25
  478. package/src/components/measured-grid.tsx +0 -837
  479. package/src/components/menu-item.tsx +0 -241
  480. package/src/components/mini-calendar-labels.ts +0 -17
  481. package/src/components/mini-calendar.tsx +0 -792
  482. package/src/components/modal.tsx +0 -534
  483. package/src/components/money-draft.ts +0 -83
  484. package/src/components/money-field.tsx +0 -76
  485. package/src/components/month-grid.tsx +0 -229
  486. package/src/components/month-picker-labels.ts +0 -22
  487. package/src/components/month-picker.tsx +0 -1087
  488. package/src/components/multi-entity-combobox.tsx +0 -369
  489. package/src/components/multi-select.tsx +0 -376
  490. package/src/components/nav-pills.tsx +0 -198
  491. package/src/components/number-field.tsx +0 -327
  492. package/src/components/number-input.tsx +0 -559
  493. package/src/components/numeric-field.ts +0 -169
  494. package/src/components/numpad-sheet.tsx +0 -285
  495. package/src/components/one-time-code-input.tsx +0 -270
  496. package/src/components/page-contents-labels.ts +0 -9
  497. package/src/components/page-contents.tsx +0 -282
  498. package/src/components/page-header-context.ts +0 -8
  499. package/src/components/page-header.tsx +0 -298
  500. package/src/components/password-strength-labels.ts +0 -22
  501. package/src/components/password-strength.tsx +0 -241
  502. package/src/components/phone-input-labels.ts +0 -10
  503. package/src/components/phone-input.tsx +0 -282
  504. package/src/components/picker-sheet.tsx +0 -330
  505. package/src/components/pie-chart-labels.ts +0 -40
  506. package/src/components/pie-chart.tsx +0 -480
  507. package/src/components/popover-labels.ts +0 -14
  508. package/src/components/popover.tsx +0 -268
  509. package/src/components/progress-bar-labels.ts +0 -10
  510. package/src/components/progress-bar.tsx +0 -479
  511. package/src/components/qr-code.tsx +0 -76
  512. package/src/components/reauth-dialog-labels.ts +0 -13
  513. package/src/components/reauth-dialog.tsx +0 -265
  514. package/src/components/row-actions-labels.ts +0 -12
  515. package/src/components/row-actions.tsx +0 -795
  516. package/src/components/scroll-area.tsx +0 -123
  517. package/src/components/search-field.tsx +0 -192
  518. package/src/components/select.tsx +0 -294
  519. package/src/components/separator.tsx +0 -33
  520. package/src/components/series-chart-axes.ts +0 -342
  521. package/src/components/series-chart-budget.ts +0 -150
  522. package/src/components/series-chart-labels.ts +0 -33
  523. package/src/components/series-chart-thin.ts +0 -180
  524. package/src/components/series-chart-ticks.ts +0 -194
  525. package/src/components/series-chart.tsx +0 -1906
  526. package/src/components/server-wake-labels.ts +0 -11
  527. package/src/components/server-wake.tsx +0 -129
  528. package/src/components/settings-fields.tsx +0 -237
  529. package/src/components/share-card-labels.ts +0 -30
  530. package/src/components/share-card.tsx +0 -675
  531. package/src/components/signature-pad-labels.ts +0 -24
  532. package/src/components/signature-pad.tsx +0 -747
  533. package/src/components/signed-amount-labels.ts +0 -10
  534. package/src/components/signed-amount.tsx +0 -336
  535. package/src/components/skeleton.tsx +0 -80
  536. package/src/components/slider.tsx +0 -338
  537. package/src/components/sparkline-labels.ts +0 -14
  538. package/src/components/sparkline.tsx +0 -322
  539. package/src/components/spinner.tsx +0 -81
  540. package/src/components/stat-tile-labels.ts +0 -15
  541. package/src/components/stat-tile.tsx +0 -754
  542. package/src/components/status-dot.tsx +0 -170
  543. package/src/components/swatch-picker-labels.ts +0 -10
  544. package/src/components/swatch-picker.tsx +0 -283
  545. package/src/components/swipeable-row.tsx +0 -386
  546. package/src/components/switch.tsx +0 -273
  547. package/src/components/table-skeleton.tsx +0 -136
  548. package/src/components/table.tsx +0 -647
  549. package/src/components/tabs-labels.ts +0 -13
  550. package/src/components/tabs.tsx +0 -693
  551. package/src/components/text-link.tsx +0 -359
  552. package/src/components/text.tsx +0 -150
  553. package/src/components/textarea.tsx +0 -330
  554. package/src/components/tile-radio.tsx +0 -332
  555. package/src/components/time-input.tsx +0 -121
  556. package/src/components/toast-labels.ts +0 -12
  557. package/src/components/toast.tsx +0 -519
  558. package/src/components/toggle-group.tsx +0 -752
  559. package/src/components/toggle-legend.tsx +0 -394
  560. package/src/components/tooltip.tsx +0 -1149
  561. package/src/components/translation-review-editor.tsx +0 -290
  562. package/src/components/translation-review-labels.ts +0 -181
  563. package/src/components/translation-review-parts.tsx +0 -272
  564. package/src/components/translation-review.tsx +0 -1240
  565. package/src/components/tree-view.tsx +0 -589
  566. package/src/components/treemap-labels.ts +0 -47
  567. package/src/components/treemap-layout.ts +0 -210
  568. package/src/components/treemap.tsx +0 -1184
  569. package/src/components/trigger-aria.ts +0 -44
  570. package/src/components/use-anchor-dir.ts +0 -20
  571. package/src/components/use-mobile-reveal.ts +0 -62
  572. package/src/components/use-table-state.ts +0 -753
  573. package/src/components/user-avatar.tsx +0 -116
  574. package/src/components/wizard-stepper.tsx +0 -42
  575. package/src/components/write-lock-labels.ts +0 -10
  576. package/src/components/write-lock.tsx +0 -253
  577. package/src/currencies.ts +0 -90
  578. package/src/data-table.ts +0 -42
  579. package/src/demo/demo-banner.tsx +0 -153
  580. package/src/demo/demo-countdown.ts +0 -136
  581. package/src/demo/demo-ended.tsx +0 -90
  582. package/src/demo/demo-labels.ts +0 -78
  583. package/src/demo/demo-session.ts +0 -32
  584. package/src/demo/demo-start.tsx +0 -156
  585. package/src/eslint/index.ts +0 -161
  586. package/src/eslint/role-utilities.generated.ts +0 -146
  587. package/src/eslint/role-utilities.ts +0 -233
  588. package/src/feedback/feedback-attachment-download.tsx +0 -77
  589. package/src/feedback/feedback-attachment-labels.ts +0 -37
  590. package/src/feedback/feedback-attachment.tsx +0 -1239
  591. package/src/feedback/feedback-capture.ts +0 -287
  592. package/src/feedback/feedback-comment-thread.tsx +0 -353
  593. package/src/feedback/feedback-context-labels.ts +0 -11
  594. package/src/feedback/feedback-context.tsx +0 -245
  595. package/src/feedback/feedback-crash.ts +0 -547
  596. package/src/feedback/feedback-diagnostics.tsx +0 -41
  597. package/src/feedback/feedback-dialog-labels.ts +0 -29
  598. package/src/feedback/feedback-dialog.tsx +0 -452
  599. package/src/feedback/feedback-entry-file.tsx +0 -150
  600. package/src/feedback/feedback-inbox.tsx +0 -552
  601. package/src/feedback/feedback-labels.ts +0 -144
  602. package/src/feedback/feedback-menu-labels.ts +0 -12
  603. package/src/feedback/feedback-menu.tsx +0 -177
  604. package/src/feedback/feedback-mutation.ts +0 -20
  605. package/src/feedback/feedback-page-link.ts +0 -90
  606. package/src/feedback/feedback-public-labels.ts +0 -81
  607. package/src/feedback/feedback-public-list.tsx +0 -524
  608. package/src/feedback/feedback-public-switch.tsx +0 -102
  609. package/src/feedback/feedback-public-types.ts +0 -101
  610. package/src/feedback/feedback-record.ts +0 -428
  611. package/src/feedback/feedback-replies-context.ts +0 -9
  612. package/src/feedback/feedback-replies.tsx +0 -343
  613. package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
  614. package/src/feedback/feedback-row-detail-labels.ts +0 -31
  615. package/src/feedback/feedback-row-detail.tsx +0 -871
  616. package/src/feedback/feedback-status-undo.ts +0 -109
  617. package/src/feedback/feedback-submit-dialog.tsx +0 -131
  618. package/src/feedback/feedback-submit.tsx +0 -270
  619. package/src/feedback/feedback-swipe.tsx +0 -192
  620. package/src/feedback/feedback-table-labels.ts +0 -27
  621. package/src/feedback/feedback-table.tsx +0 -912
  622. package/src/feedback/feedback-thread-labels.ts +0 -22
  623. package/src/feedback/feedback-thread-parts-labels.ts +0 -41
  624. package/src/feedback/feedback-thread.tsx +0 -905
  625. package/src/feedback/feedback-vocabulary.ts +0 -263
  626. package/src/feedback/feedback-vote-button.tsx +0 -124
  627. package/src/feedback.ts +0 -116
  628. package/src/hooks/use-anchored-panel.ts +0 -396
  629. package/src/hooks/use-anchored-rect.ts +0 -77
  630. package/src/hooks/use-announce.ts +0 -85
  631. package/src/hooks/use-authed-src.ts +0 -167
  632. package/src/hooks/use-body-scroll-lock.ts +0 -119
  633. package/src/hooks/use-breakpoint.ts +0 -133
  634. package/src/hooks/use-close-transition.ts +0 -107
  635. package/src/hooks/use-copy-to-clipboard.ts +0 -122
  636. package/src/hooks/use-debounce.ts +0 -114
  637. package/src/hooks/use-dismiss.ts +0 -371
  638. package/src/hooks/use-document-title.ts +0 -33
  639. package/src/hooks/use-file-drop.ts +0 -121
  640. package/src/hooks/use-file-picker-labels.ts +0 -28
  641. package/src/hooks/use-file-picker.tsx +0 -359
  642. package/src/hooks/use-focus-trap.ts +0 -199
  643. package/src/hooks/use-hotkey.ts +0 -212
  644. package/src/hooks/use-large-text.ts +0 -41
  645. package/src/hooks/use-long-press.ts +0 -140
  646. package/src/hooks/use-media-query.ts +0 -39
  647. package/src/hooks/use-mounted.ts +0 -39
  648. package/src/hooks/use-noindex.ts +0 -37
  649. package/src/hooks/use-overlay-history.ts +0 -714
  650. package/src/hooks/use-row-swipe.ts +0 -207
  651. package/src/hooks/use-search-param-state.ts +0 -434
  652. package/src/hooks/use-windowed-rows.ts +0 -225
  653. package/src/i18n/defaults.ts +0 -267
  654. package/src/i18n/german.ts +0 -2059
  655. package/src/i18n/kit-labels.tsx +0 -1003
  656. package/src/i18n/languages.ts +0 -349
  657. package/src/i18n/locales/de-CH.ts +0 -24
  658. package/src/i18n/locales/en.ts +0 -267
  659. package/src/i18n/locales/es.ts +0 -1999
  660. package/src/i18n/locales/fr.ts +0 -2037
  661. package/src/i18n/locales/hu.ts +0 -2004
  662. package/src/i18n/locales/it.ts +0 -2014
  663. package/src/i18n/locales/zh.ts +0 -1912
  664. package/src/i18n/plurals.ts +0 -86
  665. package/src/i18n/review.ts +0 -475
  666. package/src/i18n/shared-labels.ts +0 -138
  667. package/src/i18n/swiss.ts +0 -29
  668. package/src/index.ts +0 -1191
  669. package/src/landing/access.ts +0 -93
  670. package/src/landing/landing-actions.tsx +0 -97
  671. package/src/landing/landing-labels.ts +0 -59
  672. package/src/landing/landing-sections.tsx +0 -341
  673. package/src/landing/page-seo.ts +0 -261
  674. package/src/landing/public-header.tsx +0 -121
  675. package/src/landing/public-page.tsx +0 -106
  676. package/src/landing/routing.tsx +0 -225
  677. package/src/lib/broadcast.ts +0 -52
  678. package/src/lib/calc.ts +0 -323
  679. package/src/lib/chip-edge-snap.ts +0 -212
  680. package/src/lib/clipboard-minus.ts +0 -107
  681. package/src/lib/clipping.ts +0 -34
  682. package/src/lib/cn.ts +0 -28
  683. package/src/lib/column-mapping.ts +0 -234
  684. package/src/lib/countries.ts +0 -91
  685. package/src/lib/data-attributes.ts +0 -14
  686. package/src/lib/date-format.ts +0 -227
  687. package/src/lib/dates.ts +0 -288
  688. package/src/lib/day-format.ts +0 -96
  689. package/src/lib/decimal-marks.ts +0 -108
  690. package/src/lib/describe-failure.ts +0 -18
  691. package/src/lib/device-settings.ts +0 -147
  692. package/src/lib/direction.ts +0 -74
  693. package/src/lib/document-navigation.ts +0 -17
  694. package/src/lib/document-title.ts +0 -41
  695. package/src/lib/download.ts +0 -172
  696. package/src/lib/float-clearance.ts +0 -70
  697. package/src/lib/floating-stack.ts +0 -70
  698. package/src/lib/focus-left.ts +0 -156
  699. package/src/lib/format.ts +0 -585
  700. package/src/lib/http-status.ts +0 -38
  701. package/src/lib/iban.ts +0 -251
  702. package/src/lib/ime.ts +0 -24
  703. package/src/lib/intl-cache.ts +0 -27
  704. package/src/lib/iso-day.ts +0 -13
  705. package/src/lib/lazy-with-fallback.ts +0 -82
  706. package/src/lib/logger.ts +0 -69
  707. package/src/lib/minus.ts +0 -50
  708. package/src/lib/path-pattern.ts +0 -55
  709. package/src/lib/person-name.ts +0 -155
  710. package/src/lib/phone.ts +0 -208
  711. package/src/lib/plain-text.ts +0 -22
  712. package/src/lib/presence.ts +0 -18
  713. package/src/lib/qr-encode.ts +0 -444
  714. package/src/lib/quiet-focus.ts +0 -32
  715. package/src/lib/reduced-motion.ts +0 -22
  716. package/src/lib/refs.ts +0 -22
  717. package/src/lib/round.ts +0 -43
  718. package/src/lib/safe-storage.ts +0 -119
  719. package/src/lib/server-wake.ts +0 -315
  720. package/src/lib/session-refresh.ts +0 -472
  721. package/src/lib/share-format.ts +0 -18
  722. package/src/lib/status-tone.ts +0 -43
  723. package/src/lib/strip-fade.ts +0 -287
  724. package/src/lib/table-text.ts +0 -554
  725. package/src/lib/text-case.ts +0 -19
  726. package/src/lib/text-match.ts +0 -169
  727. package/src/lib/thenable.ts +0 -19
  728. package/src/lib/translation-review.ts +0 -769
  729. package/src/notifications/device-zone-report.ts +0 -67
  730. package/src/notifications/feedback-notification-types-labels.ts +0 -33
  731. package/src/notifications/feedback-notification-types.ts +0 -71
  732. package/src/notifications/notification-bell.tsx +0 -119
  733. package/src/notifications/notification-inbox.tsx +0 -309
  734. package/src/notifications/notification-parts.tsx +0 -81
  735. package/src/notifications/notification-types-setting.tsx +0 -406
  736. package/src/notifications/notification-types.ts +0 -89
  737. package/src/notifications/notifications-labels.ts +0 -287
  738. package/src/notifications/push-device-setting.tsx +0 -230
  739. package/src/notifications/push-devices-setting.tsx +0 -374
  740. package/src/notifications/push-worker.ts +0 -168
  741. package/src/notifications/quiet-hours-setting.tsx +0 -238
  742. package/src/notifications/unsubscribe-panel.tsx +0 -200
  743. package/src/notifications/use-push-device.ts +0 -448
  744. package/src/offline/local-first.ts +0 -100
  745. package/src/offline/pwa-update-prompt-labels.ts +0 -9
  746. package/src/offline/pwa-update-prompt.tsx +0 -78
  747. package/src/offline/query-persistence.ts +0 -391
  748. package/src/offline/service-worker-updates.ts +0 -81
  749. package/src/offline/shared-computer-labels.ts +0 -8
  750. package/src/offline/shared-computer.tsx +0 -87
  751. package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
  752. package/src/offline/sign-out-pending-dialog.tsx +0 -135
  753. package/src/offline.ts +0 -37
  754. package/src/push-worker.ts +0 -25
  755. package/src/rhf/fields.tsx +0 -2187
  756. package/src/rhf/form-core.tsx +0 -324
  757. package/src/rhf/form.tsx +0 -12
  758. package/src/rhf/line-items.tsx +0 -135
  759. package/src/rhf/use-rhf-wizard-step.ts +0 -104
  760. package/src/rhf.ts +0 -21
  761. package/src/search/command-palette-labels.ts +0 -16
  762. package/src/search/command-palette.tsx +0 -624
  763. package/src/search/global-search-labels.ts +0 -13
  764. package/src/search/global-search.tsx +0 -660
  765. package/src/search/search-index.ts +0 -283
  766. package/src/search/use-command-key.ts +0 -23
  767. package/src/search.ts +0 -14
  768. package/src/settings/device-reset-setting-labels.ts +0 -20
  769. package/src/settings/device-reset-setting.tsx +0 -116
  770. package/src/settings/settings-card-classes.ts +0 -11
  771. package/src/settings/settings-catalogue.ts +0 -150
  772. package/src/settings/settings-context.ts +0 -33
  773. package/src/settings/settings-heading.tsx +0 -67
  774. package/src/settings/settings-labels.ts +0 -87
  775. package/src/settings/settings-layout.tsx +0 -471
  776. package/src/settings/settings-section.tsx +0 -108
  777. package/src/settings/use-account-appearance.ts +0 -148
  778. package/src/settings/use-account-language.ts +0 -146
  779. package/src/settings/use-settings-focus.ts +0 -128
  780. package/src/settings/use-settings-route.ts +0 -258
  781. package/src/shell/account-menu-language.tsx +0 -130
  782. package/src/shell/account-menu-text-size.tsx +0 -80
  783. package/src/shell/admin-menu.tsx +0 -183
  784. package/src/shell/app-shell-labels.ts +0 -11
  785. package/src/shell/app-shell.tsx +0 -1560
  786. package/src/shell/auth-layout.tsx +0 -186
  787. package/src/shell/company-switcher-labels.ts +0 -13
  788. package/src/shell/company-switcher.tsx +0 -136
  789. package/src/shell/dev-menu.tsx +0 -257
  790. package/src/shell/fill-height.tsx +0 -45
  791. package/src/shell/language-code.ts +0 -5
  792. package/src/shell/option-switcher-menu.tsx +0 -84
  793. package/src/shell/sync-status-indicator.tsx +0 -303
  794. package/src/shell/top-bar-actions.tsx +0 -87
  795. package/src/shell/top-bar-brand.tsx +0 -78
  796. package/src/shell/top-bar-parts-labels.ts +0 -148
  797. package/src/shell/top-bar.tsx +0 -40
  798. package/src/shell/topbar-action-menu.tsx +0 -567
  799. package/src/shell/topbar-controls.tsx +0 -269
  800. package/src/shell/tour-menu.tsx +0 -187
  801. package/src/shell.ts +0 -108
  802. package/src/sync/db.ts +0 -129
  803. package/src/sync/engine.ts +0 -1011
  804. package/src/sync/hooks.ts +0 -98
  805. package/src/sync/testing.ts +0 -73
  806. package/src/sync/wire.ts +0 -61
  807. package/src/sync.ts +0 -37
  808. package/src/table-text.ts +0 -8
  809. package/src/testing/css-variables.generated.ts +0 -112
  810. package/src/testing/css-variables.ts +0 -189
  811. package/src/testing/index.ts +0 -29
  812. package/src/testing/react.ts +0 -58
  813. package/src/testing/tour.ts +0 -41
  814. package/src/testing/viewport.ts +0 -357
  815. package/src/theme/chart-palette.ts +0 -232
  816. package/src/theme/color.ts +0 -272
  817. package/src/theme/contrast-tokens.ts +0 -268
  818. package/src/theme/contrast.ts +0 -250
  819. package/src/theme/palette-derive.ts +0 -825
  820. package/src/theme/palette-presets.ts +0 -544
  821. package/src/theme/palette-store.ts +0 -108
  822. package/src/theme/text-size.ts +0 -289
  823. package/src/theme/theme-store.ts +0 -157
  824. package/src/tour/tour-catalogue-labels.ts +0 -75
  825. package/src/tour/tour-catalogue.tsx +0 -335
  826. package/src/tour/tour-dock.ts +0 -134
  827. package/src/tour/tour-engine.ts +0 -37
  828. package/src/tour/tour-gates.ts +0 -218
  829. package/src/tour/tour-guide-button.tsx +0 -64
  830. package/src/tour/tour-guide-labels.ts +0 -15
  831. package/src/tour/tour-info.ts +0 -144
  832. package/src/tour/tour-labels.ts +0 -23
  833. package/src/tour/tour-overlay.tsx +0 -1170
  834. package/src/tour/tour.tsx +0 -750
  835. package/src/tour/use-tour-progress.ts +0 -671
  836. package/src/tour/use-tour-url-sync.ts +0 -266
  837. package/src/tour.ts +0 -21
  838. package/src/vite-env.d.ts +0 -23
  839. package/src/wizard/stepper-nav.tsx +0 -360
  840. package/src/wizard/types.ts +0 -275
  841. package/src/wizard/use-wizard.ts +0 -560
  842. package/src/wizard/validation.ts +0 -39
  843. package/src/wizard/wizard-context.tsx +0 -74
  844. package/src/wizard/wizard-labels.ts +0 -29
  845. package/src/wizard/wizard-step.tsx +0 -76
  846. package/src/wizard/wizard-summary.tsx +0 -84
  847. package/src/wizard.ts +0 -15
@@ -1,871 +0,0 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import type { ReactNode } from "react";
3
- import { RotateCcw } from "lucide-react";
4
- import { AuthedImage } from "../components/authed-image";
5
- import { CopyButton } from "../components/copy-button";
6
- import { TextLink } from "../components/text-link";
7
- import { toast } from "../components/toast";
8
- import { Button } from "../components/button";
9
- import type { AuthedFetcher } from "../hooks/use-authed-src";
10
- import type { PathPattern } from "../landing/routing";
11
- import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
12
- import { useDayFormatter } from "../lib/day-format";
13
- import { DEFAULT_MAX_ATTACHMENT_BYTES } from "./feedback-attachment";
14
- import { DEFAULT_FEEDBACK_DIALOG_LABELS } from "./feedback-dialog";
15
- import {
16
- FeedbackCategoryBadge,
17
- FeedbackDetail,
18
- FeedbackDetailSection,
19
- FeedbackNoteEditor,
20
- FeedbackProse,
21
- FeedbackStatusTransitions,
22
- selectableFeedbackStatuses,
23
- visibleFeedbackStatuses,
24
- } from "./feedback-inbox";
25
- import type { FeedbackNoteAttachment, FeedbackStatus } from "./feedback-inbox";
26
- import { useFeedbackToastLabels } from "./feedback-labels";
27
- import {
28
- FEEDBACK_ATTACHMENT_ACCEPT,
29
- FEEDBACK_AUTHOR_EDITABLE_STATUSES,
30
- FEEDBACK_REWORKABLE_STATUSES,
31
- appendRework,
32
- isImageAttachment,
33
- replaceDescription,
34
- splitBodyAttachments,
35
- splitDescription,
36
- } from "./feedback-record";
37
- import type { FeedbackContext, FeedbackRecord } from "./feedback-record";
38
- import { diagnosticsEntries, FeedbackDiagnosticsList } from "./feedback-diagnostics";
39
- import { runMutation } from "./feedback-mutation";
40
- import { feedbackPage, feedbackPageLinkTarget } from "./feedback-page-link";
41
- import { useFeedbackStatusUndo } from "./feedback-status-undo";
42
- import type { FeedbackStatusChange } from "./feedback-status-undo";
43
- import type { CommitScope } from "../components/write-lock";
44
- import { DEFAULT_FEEDBACK_DETAIL_LABELS } from "./feedback-row-detail-labels";
45
- import { FeedbackReplyComposer, FeedbackReplyTimeline, feedbackReplyNudge } from "./feedback-replies";
46
- import { FeedbackAttachmentDownload, plainFeedbackFetch } from "./feedback-attachment-download";
47
- import { FeedbackPublicSwitch } from "./feedback-public-switch";
48
- import { FeedbackRepliesDrawnAboveContext } from "./feedback-replies-context";
49
- import { DEFAULT_FEEDBACK_COMMENTS_LABELS } from "./feedback-thread-parts-labels";
50
-
51
- /**
52
- * One report, opened — the panel a feedback table unfolds under its row (§4.4 of
53
- * docs/feedback-harmonization.md), lifted from keksdose's `FeedbackRow`
54
- * (`frontend/src/features/feedback/feedback-page.tsx:329-612`) with the contract's
55
- * changes applied.
56
- *
57
- * Until 0.27 each app wrote this panel itself out of the kit's shell
58
- * (`FeedbackDetail` / `FeedbackDetailSection` / `FeedbackNoteEditor`), and the three
59
- * copies had drifted in exactly the places a user notices:
60
- *
61
- * - **the description editor held the raw body** — keksdose `initial={fb.body}`
62
- * (`:420`), kastlan the same (`pages/feedback-page.tsx:226`) — so an author fixing a
63
- * typo could delete the `--- REWORK … ---` rounds and the `[screenshot]` file lines
64
- * with it, and the history was gone. Here the editor holds the ORIGINAL description
65
- * only ({@link splitDescription}) and saves through {@link replaceDescription}, which
66
- * puts every appended block and file line back unchanged;
67
- * - **kastlan's rework sent `status: "OPEN"`** from the client (`:189-195`) and offered it
68
- * on three statuses; keksdose sends the body alone and lets the server reopen the row
69
- * on five (live #331). The contract is keksdose's (§3.4) — {@link appendRework}, one
70
- * file, the server reopens;
71
- * - **kastlan showed only `screenshot_url`** (`:265-276`) and no downloads; keksdose the
72
- * screenshot, the other files and the rework pictures, a PDF as a download (dev #578);
73
- * - **the URL fell away on Kurvenschmiede's rows**, whose backfilled `context.url` is a
74
- * path (`/accounts?p=2`): keksdose's `new URL(…)` throws on one and the section
75
- * vanished. kastlan already fell back to `context.route` (`feedbackRaw`, `:97`).
76
- *
77
- * The sections, in the contract's order: **Subject** (the category and the title, §8.1;
78
- * `showSubject={false}` leaves it out), **Description** (the body; the author's
79
- * Edit while OPEN / READY / IN_PROGRESS), **URL**, **Attachment**, **Replies** (0.38,
80
- * §9.7: the timeline, the admin's reply composer with its status picker and the nudge,
81
- * Rework — on a row without `replies`, a server before 0.38, the frozen
82
- * **Outcome** read-only in its place), **Comments** (0.38: the app's
83
- * `FeedbackCommentThread`, when passed), **Send for rework** (only while reworking) and
84
- * **Status** (with the **Visible to others** switch when `onPublicChange` is passed).
85
- *
86
- * The app keeps its data and its API: the row it renders, the PATCH (`onUpdate`), the
87
- * upload (`onUpload`), the authenticated GET (`fetcher`) and who is looking (`canEdit`,
88
- * `viewerId`). Every word is the kit's `feedbackDetail` namespace.
89
- */
90
-
91
- /* ── Labels ───────────────────────────────────────────────────────────────── */
92
-
93
- /**
94
- * `feedbackDetail` — the row detail's words (§4.4). English: keksdose's `en.json`
95
- * (`feedback.*`, `common.*`, `more.copy_url`) with the contract's changes; the de-CH
96
- * canon (keksdose `de-CH.json`, ss never ß, "Nacharbeit" throughout — §7.14) on each key.
97
- */
98
- export interface FeedbackDetailLabels {
99
- /** The first section's heading: what the report is called (feedback contract §8.1,
100
- * keksdose live #395 — with the row expanded and the table scrolled, nothing said
101
- * which entry was being answered). de-CH: "Betreff" */
102
- subject: string;
103
- /** The description section's heading — keksdose's `feedback.body` (§7.3). The dialog's field asks
104
- * "What happened? (optional)"; the description, once filed, is headed as what it is
105
- * — and as the author's "Edit description" calls it. de-CH: "Beschreibung" */
106
- body: string;
107
- /** The author's button on that heading. de-CH: "Bearbeiten" */
108
- edit: string;
109
- /** Its accessible name — says WHAT is edited; contains the visible word.
110
- * de-CH: "Beschreibung bearbeiten" */
111
- editDescription: string;
112
- /** The editors' save button (description, outcome). de-CH: "Speichern" */
113
- save: string;
114
- /** Every editor's cancel button. de-CH: "Abbrechen" */
115
- cancel: string;
116
- /** Section 2's heading. de-CH: "URL" */
117
- url: string;
118
- /** The copy button beside the link — copies the FULL `context.url`.
119
- * de-CH: "URL kopieren" */
120
- copyUrl: string;
121
- /** The heading over `context.diagnostics`, between the URL and the attachment (keksdose
122
- * live #481). de-CH: "Diagnose" */
123
- diagnostics: string;
124
- /** Section 3's heading, and each picture's alt text. de-CH: "Anhang" */
125
- attachment: string;
126
- /** A PDF's / text file's download button, given the file's name.
127
- * de-CH: "{{name}} herunterladen" */
128
- download: (name: string) => string;
129
- /** The toast when that download failed. de-CH: "Der Anhang konnte nicht
130
- * heruntergeladen werden." */
131
- downloadFailed: string;
132
- /** Section 4's heading on a row without `replies` (a server before 0.38), where the
133
- * frozen outcome is shown read-only. de-CH: "Ergebnis" */
134
- outcome: string;
135
- /** Section 4's heading since 0.38: the replies' timeline (§9.7). de-CH: "Antworten" */
136
- replies: string;
137
- /** On section 4's heading line once the row is settled, given the formatted
138
- * `resolved_at` date. de-CH: "Erledigt am: {{date}}" */
139
- resolvedAt: (date: string) => string;
140
- /** The button that opens section 5 on an answered row. de-CH: "Nacharbeit" */
141
- rework: string;
142
- /** Section 5's heading. de-CH: "Zur Nacharbeit senden" */
143
- reworkTitle: string;
144
- /** Section 5's send button. de-CH: "Nacharbeit senden" */
145
- reworkSend: string;
146
- /** The line above the rework note. de-CH: "Was muss noch angepasst werden? Neue
147
- * Anforderungen oder Richtungswechsel." */
148
- reworkPlaceholder: string;
149
- /** The toast when the rework's file did not upload — and so nothing was sent. Names
150
- * no screenshot: it fires for a PDF or a log too (§7.14; keksdose's said
151
- * "screenshot"). de-CH: "Die Datei konnte nicht hochgeladen werden. Die Nacharbeit
152
- * wurde nicht gesendet." */
153
- reworkUploadFailed: string;
154
- /** Section 6's heading. de-CH: "Status" */
155
- status: string;
156
- /** A `FeedbackNoteEditor`'s box, named when no `placeholder` line names it and the
157
- * caller gives no `label` — without it the box was read out as just "edit text"
158
- * (round 0.34, the showcase's axe check). de-CH: "Notiz" */
159
- note: string;
160
- }
161
-
162
- // Defined in ./feedback-row-detail-labels, which holds no component code (0.34, KS U8).
163
- export { DEFAULT_FEEDBACK_DETAIL_LABELS };
164
-
165
- /** `feedbackDetail` resolved: English, then `<UiKitProvider labels>`, then `labels`. */
166
- export function useFeedbackDetailLabels(labels?: LabelOverride<FeedbackDetailLabels>): FeedbackDetailLabels {
167
- return useKitLabels("feedbackDetail", DEFAULT_FEEDBACK_DETAIL_LABELS, labels);
168
- }
169
-
170
- /* ── The page a report was filed on (§3.2, §4.4.2) ────────────────────────── */
171
-
172
- // The page as the reporter had it (path + query + hash) and the full URL "Copy URL"
173
- // copies were public too, as `feedbackPageHref` and `feedbackPageUrl`, until 0.53 (deprecated
174
- // in 0.52, API-4): `feedbackPage` (./feedback-page-link) is the one reading, and the kit
175
- // links only its path.
176
-
177
- /** The page's path alone — the compact text a URL column shows (§4.3), and the only part
178
- * of the page the kit links. */
179
- export function feedbackPagePath(context: FeedbackContext | null | undefined): string | null {
180
- return feedbackPage(context)?.path ?? null;
181
- }
182
-
183
- /* ── Attachments (§3.5, §4.4.3) ───────────────────────────────────────────── */
184
-
185
- /**
186
- * Every file a report carries, in the order the detail shows them (§4.4.3): the
187
- * screenshot it was filed with, then its other files, then whatever the rework rounds
188
- * brought, in body order (keksdose dev #578, live #291). One list rather than three —
189
- * a reader looking for "the picture" should not have to know at which point in the
190
- * conversation it was taken.
191
- *
192
- * Each URL once: keksdose and Kurvenschmiede content-address their keys, so the same
193
- * screenshot pasted twice is one URL — shown twice it is the same picture twice (and,
194
- * keyed by URL, a React key clash keksdose had).
195
- */
196
- export function feedbackAttachmentUrls(
197
- row: Pick<FeedbackRecord, "screenshot_url" | "attachment_urls" | "body"> & Partial<Pick<FeedbackRecord, "replies">>,
198
- ): string[] {
199
- const urls = [
200
- ...(row.screenshot_url ? [row.screenshot_url] : []),
201
- // `?? []`: NULL on rows filed before the column, and no key at all from a server
202
- // that predates it (keksdose dev #578).
203
- ...(row.attachment_urls ?? []),
204
- ...splitBodyAttachments(row.body).urls,
205
- // 0.40 (§10.3): a rework entry's one file, in entry order — where the rework
206
- // pictures of the body were before.
207
- ...(row.replies ?? []).flatMap((reply) =>
208
- reply.kind === "rework" && reply.attachment_url ? [reply.attachment_url] : [],
209
- ),
210
- ];
211
- return [...new Set(urls)];
212
- }
213
-
214
- /* ── Who may do what (§3.4, §4.3, §4.4) ───────────────────────────────────── */
215
-
216
- /** What the person looking at a row may do with it — {@link feedbackRowAccess}. */
217
- export interface FeedbackRowAccess {
218
- /** The viewer filed it (`viewerId === row.user_id`; never for an erased author). */
219
- isAuthor: boolean;
220
- /** "Edit description": the author, while the row is OPEN, READY or IN_PROGRESS — on either
221
- * page (keksdose `canAuthorEdit`, `feedback-page.tsx:398`, is not gated on `mine`). */
222
- canEditDescription: boolean;
223
- /** The admin on the inbox (`canEdit`): since 0.38 the reply composer (the outcome
224
- * itself is frozen, §9.7). */
225
- canEditOutcome: boolean;
226
- /** "Rework": the author, on an answered row ({@link FEEDBACK_REWORKABLE_STATUSES}).
227
- * Since 0.40 (§10.2 decision 6) the author's only — an admin sends a report back with
228
- * a reply whose status is `REWORK`; the server answers anyone else 403. */
229
- canRework: boolean;
230
- /** The status pills: the admin on the inbox; everyone else sees them read-only. */
231
- canChangeStatus: boolean;
232
- }
233
-
234
- /**
235
- * The detail's permission rules in one place — the same answers the server gives
236
- * (§3.4), so the panel never offers what the PATCH would refuse.
237
- *
238
- * `canEdit` is the app's "admin on `/feedback`": an admin on `/my-feedback` edits no
239
- * status and no outcome there (§4.3), but as the author still edits the description
240
- * and sends for rework. `viewerId` is the signed-in user's id.
241
- */
242
- export function feedbackRowAccess(
243
- row: Pick<FeedbackRecord, "user_id" | "status">,
244
- { canEdit, viewerId }: { canEdit: boolean; viewerId?: number | null },
245
- ): FeedbackRowAccess {
246
- // `user_id: null` is an erased author (keksdose live #275): nobody is that author,
247
- // least of all a viewer whose id happens to be missing too.
248
- const isAuthor = row.user_id !== null && viewerId !== undefined && viewerId !== null && viewerId === row.user_id;
249
- return {
250
- isAuthor,
251
- canEditDescription: isAuthor && FEEDBACK_AUTHOR_EDITABLE_STATUSES.includes(row.status),
252
- canEditOutcome: canEdit,
253
- canRework: isAuthor && FEEDBACK_REWORKABLE_STATUSES.includes(row.status),
254
- canChangeStatus: canEdit,
255
- };
256
- }
257
-
258
- /* ── The PATCH ─────────────────────────────────────────────────────────────── */
259
-
260
- /** What the detail sends as `PATCH /feedback/{id}` (§3.4): the body (a description
261
- * edit, a rework append) or the outcome — and, through {@link useFeedbackStatusUndo}
262
- * when no `statusChange` is given, the status. Never two at once: a rework PATCH must
263
- * carry the body ALONE for the server to read it as an append (keksdose live #331). */
264
- export interface FeedbackDetailPatch {
265
- id: number;
266
- body?: string;
267
- /** `null` clears it — a real edit. **Frozen since 0.38** (§9.7): server-kit 0.11
268
- * answers 422; the detail no longer sends it (a reply is written instead). */
269
- outcome?: string | null;
270
- status?: FeedbackStatus;
271
- /** 0.38.1: the **Visible to others** flip (§9.3) — what `onPublicChange`'s
272
- * `PATCH /feedback/{id} {"public": next}` carries, alone, so an app can send it
273
- * through the same `onUpdate` mutation. */
274
- public?: boolean;
275
- }
276
-
277
- /**
278
- * The page's update mutation (0.52): **TanStack Query's `mutateAsync`** — pass
279
- * `update.mutateAsync` (and `pending={update.isPending}`), the same function
280
- * `useFeedbackStatusUndo` takes. An editor closes when the promise resolves, which it does
281
- * for every call — also when a status pill was pressed while the save was in flight
282
- * (refactor audit 2026-10-30, FLW-3). A hand-written one resolves once the PATCH has
283
- * landed. A failure is the mutation's own to toast — the server's `detail`, else
284
- * `feedbackToast.updateFailed` (§4.4) — and leaves the editor open with its draft.
285
- */
286
- export type FeedbackDetailUpdateAsync = (patch: FeedbackDetailPatch) => Promise<unknown>;
287
-
288
- /** `POST /feedback/attachments` (§3.3): one file up, its URL
289
- * (`/api/v1/feedback/attachments/<key>`) back. Reject on failure. */
290
- export type FeedbackUpload = (file: File) => Promise<string>;
291
-
292
- /* ── Send for rework (§4.4.5) ─────────────────────────────────────────────── */
293
-
294
- /** 0.40 (§10.3): `POST /feedback/{id}/rework` — the trimmed note and the uploaded file's
295
- * URL. Return the promise: the section closes when it resolves and keeps the note when
296
- * it rejects (the toast is the app's: the server's `detail`, else
297
- * `feedbackToast.updateFailed`). */
298
- export type FeedbackReworkSend = (note: string, attachmentUrl?: string) => void | Promise<unknown>;
299
-
300
- export interface FeedbackReworkSectionProps {
301
- /** The row being sent back: its id, and the body the round is appended to. */
302
- row: Pick<FeedbackRecord, "id" | "body">;
303
- /** 0.40: the rework as an entry of its own — see {@link FeedbackReworkSend}. With it,
304
- * `onUpdate` is not called. */
305
- onRework?: FeedbackReworkSend;
306
- /** The PATCH — see {@link FeedbackDetailUpdateAsync}. Called with `{ id, body }` only,
307
- * and only without `onRework`: the legacy append (§3.4), which server-kit 0.13 still
308
- * turns into an entry for one release. Optional since 0.40; pass one of the two. */
309
- onUpdate?: FeedbackDetailUpdateAsync;
310
- /** The PATCH is in flight (`update.isPending`). The upload adds its own. */
311
- pending?: boolean;
312
- /** The upload. Left out, the note goes without a file field. */
313
- onUpload?: FeedbackUpload;
314
- /** Snapshot the app view as a File — the kit's `captureAppScreenshot`, or the app's
315
- * own. A "Capture screenshot" button appears only with it; a rejection (no
316
- * `modern-screenshot`, a canvas that would not draw) toasts
317
- * `feedbackToast.captureFailed` and adds nothing. */
318
- onCaptureScreenshot?: () => Promise<File | null>;
319
- /** The round landed — the server has the note and, on an answered row, reopened it. */
320
- onSent?: () => void;
321
- onCancel: () => void;
322
- /** Over the field's defaults: the contract's types and 10 MB (§3.5), the
323
- * `feedbackToast` refusals, the `feedbackAttachment` words. */
324
- attachment?: Partial<FeedbackNoteAttachment>;
325
- /** The send COMMITS — see `FeedbackNoteEditor`'s `commit`. */
326
- commit?: CommitScope;
327
- labels?: LabelOverride<FeedbackDetailLabels>;
328
- }
329
-
330
- /**
331
- * The rework editor (§4.4.5): the submitter sends an answered report
332
- * back with a note and at most one file, and the server reopens it (§3.4, keksdose
333
- * `submitRework`, `feedback-page.tsx:350`).
334
- *
335
- * - **The note is required** and trimmed: Send stays disabled on a blank box (a file
336
- * alone cannot be sent; keksdose `:577` dropped that click silently).
337
- * - **One file**, added, captured or pasted — the dialog's types and 10 MB. It is
338
- * uploaded FIRST and awaited: a body naming a file that never arrived would be a
339
- * rework whose evidence is missing, and the upload is the half that fails on its
340
- * own. If it fails nothing is sent and the toast says so; the note stays in the box.
341
- * - **0.40: an entry of its own** (§10.3) — with `onRework`, the note and the file's URL
342
- * go to `POST /feedback/{id}/rework` and the body is not touched. Without it, the
343
- * legacy append below, which server-kit 0.13 still converts (one minor).
344
- * - **The body alone goes in the PATCH** — {@link appendRework}'s strict extension of
345
- * the current body, which is how the server recognises the append and reopens the
346
- * row. Never a `status` (kastlan's client sent `OPEN`; an author may not write one,
347
- * so the server refused the whole PATCH, note and all — keksdose live #331).
348
- *
349
- * Exported on its own for an app that offers rework somewhere other than the row
350
- * detail. Kurvenschmiede's author verdict ("That is it, done") is NOT here: an answered
351
- * item stays answered unless its author sends it back (§7.2).
352
- */
353
- export function FeedbackReworkSection({
354
- row,
355
- onRework,
356
- onUpdate,
357
- pending = false,
358
- onUpload,
359
- onCaptureScreenshot,
360
- onSent,
361
- onCancel,
362
- attachment,
363
- commit,
364
- labels: labelsProp,
365
- }: FeedbackReworkSectionProps) {
366
- const labels = useFeedbackDetailLabels(labelsProp);
367
- const toasts = useFeedbackToastLabels();
368
- const [uploading, setUploading] = useState(false);
369
- const [sending, setSending] = useState(false);
370
- // The body as it is NOW, not as it was when Send was pressed: the list can refresh
371
- // while the file uploads, and an append to a stale body is no longer a strict
372
- // extension of the stored one — the server would read it as an edit, and refuse it.
373
- const latestBody = useRef(row.body);
374
- useEffect(() => {
375
- latestBody.current = row.body;
376
- }, [row.body]);
377
-
378
- const capture = onCaptureScreenshot
379
- ? async () => {
380
- try {
381
- return await onCaptureScreenshot();
382
- } catch {
383
- toast.error(toasts.captureFailed);
384
- return null;
385
- }
386
- }
387
- : undefined;
388
-
389
- const send = async (value: string, file?: File | null) => {
390
- const note = value.trim();
391
- if (!note) return;
392
- let url: string | null = null;
393
- if (file && onUpload) {
394
- setUploading(true);
395
- try {
396
- url = await onUpload(file);
397
- } catch {
398
- toast.error(labels.reworkUploadFailed);
399
- return;
400
- } finally {
401
- setUploading(false);
402
- }
403
- }
404
- if (onRework) {
405
- // 0.40 (§10.3): the entry, not the body — the server checks the URL (a 422 outside
406
- // the app's attachment prefix).
407
- setSending(true);
408
- try {
409
- await onRework(note, url ?? undefined);
410
- } catch {
411
- return; // The app's toast; the note stays in the box.
412
- } finally {
413
- setSending(false);
414
- }
415
- onSent?.();
416
- return;
417
- }
418
- if (!onUpdate) return;
419
- let body: string | null;
420
- try {
421
- body = appendRework(latestBody.current, note, url);
422
- } catch {
423
- // The upload answered with something that is not an attachment URL of this
424
- // contract — written anyway it would sit in the body as prose no reader knows to
425
- // be a file. As far as the person is concerned, the file did not arrive.
426
- toast.error(labels.reworkUploadFailed);
427
- return;
428
- }
429
- if (body === null) return;
430
- runMutation(onUpdate, { id: row.id, body }, () => onSent?.());
431
- };
432
-
433
- return (
434
- <FeedbackDetailSection title={labels.reworkTitle}>
435
- <FeedbackNoteEditor
436
- key={row.id}
437
- initial=""
438
- required
439
- commit={commit}
440
- pending={pending || uploading || sending}
441
- onSave={(value, file) => void send(value, file)}
442
- onCancel={onCancel}
443
- saveLabel={labels.reworkSend}
444
- cancelLabel={labels.cancel}
445
- placeholder={labels.reworkPlaceholder}
446
- attachment={
447
- onUpload
448
- ? {
449
- accept: FEEDBACK_ATTACHMENT_ACCEPT,
450
- maxBytes: DEFAULT_MAX_ATTACHMENT_BYTES,
451
- onError: (kind) => {
452
- toast.error(kind === "type" ? toasts.attachmentUnsupported : toasts.attachmentTooLarge);
453
- },
454
- onCaptureScreenshot: capture,
455
- ...attachment,
456
- }
457
- : undefined
458
- }
459
- />
460
- </FeedbackDetailSection>
461
- );
462
- }
463
-
464
- /* ── The detail (§4.4) ─────────────────────────────────────────────────────── */
465
-
466
- export interface FeedbackRowDetailProps {
467
- /** The report — the list's own row, as `GET /feedback` / `GET /feedback/my` sent it. */
468
- row: FeedbackRecord;
469
- /** The admin on the inbox (`/feedback`): status pills and the outcome editor. `false`
470
- * on `/my-feedback`, for an admin too (§4.3). */
471
- canEdit: boolean;
472
- /** The signed-in user's id — who the AUTHOR is: the description editor and rework. */
473
- viewerId?: number | null;
474
- /** The page's PATCH — `update.mutateAsync` (see {@link FeedbackDetailUpdateAsync}). The
475
- * callback form, `update.mutate`, went in 0.53 (deprecated in 0.52). */
476
- onUpdate: FeedbackDetailUpdateAsync;
477
- /** `update.isPending`: the editors' save buttons wait for it. */
478
- pending?: boolean;
479
- /** `POST /feedback/attachments` for the rework's one file and, since 0.47 (§12) with
480
- * `replyAttachments`, the admin reply's. Left out, a rework or a reply is text alone. */
481
- onUpload?: FeedbackUpload;
482
- /** The app's authenticated GET (`AuthedImage`'s) — the pictures and the downloads go
483
- * through it, since the attachment route wants the bearer token (§3.5). Left out,
484
- * the browser's own fetch with same-origin cookies. */
485
- fetcher?: AuthedFetcher | null;
486
- /**
487
- * The undoable status change — what `useFeedbackStatusUndo(update.mutateAsync)` returns,
488
- * the SAME one the table's status cell and the swipes use (§4.5). Left out, the
489
- * detail builds one from `onUpdate`, which is equivalent as long as `onUpdate` is the
490
- * page's mutation (its observer outlives the row a status filter removes).
491
- */
492
- statusChange?: FeedbackStatusChange;
493
- /** For the rework's and (0.47, with `replyAttachments`) the reply composer's "Capture screenshot" — see
494
- * {@link FeedbackReworkSectionProps}. */
495
- onCaptureScreenshot?: () => Promise<File | null>;
496
- /** The rework's and (0.47, with `replyAttachments`) the reply composer's file field,
497
- * over the contract's defaults. */
498
- reworkAttachment?: Partial<FeedbackNoteAttachment>;
499
- /** How the `resolved_at` date reads — the app's date cell, as a string. Default
500
- * (0.52): the `<UiKitProvider formatDate>` when the app set one, else the kit's
501
- * `formatDate` in the provider's locale and time zone, `medium` style. */
502
- renderDate?: (iso: string) => string;
503
- /**
504
- * 0.52 (FLW-7): the app's one-shot routes, ON TOP of the kit's — `/join`,
505
- * `/register`, `/verify-email`, `/reset-password` (a string is that path and everything
506
- * under it, a RegExp is tested on the path, as `useLastVisitedPage`'s `exclude`). The
507
- * URL section shows such a page as text with Copy, never as a link: it acts on load,
508
- * and a report's page is the reporter's to write. Any other page links its PATH alone;
509
- * the query, where tokens and `?next=` targets travel, is text. keksdose:
510
- * `["/banks/callback", "/share-target"]`. Keep it stable (module scope).
511
- */
512
- pageLinkExclude?: readonly PathPattern[];
513
- /**
514
- * The detail's saves COMMIT (description, outcome, rework, status): under a locked
515
- * `WriteLockProvider` each is `aria-disabled` with the lock's reason, and nothing
516
- * reaches `onUpdate`. Off by default — keksdose's shell lock is a read-only demo
517
- * BUDGET, and a person viewing one still owns their own reports.
518
- */
519
- commit?: CommitScope;
520
- /**
521
- * Open with the subject: the category badge and the title (feedback contract §8.1,
522
- * keksdose live #395). On by default; `false` for a page that already shows the title
523
- * beside the detail.
524
- */
525
- showSubject?: boolean;
526
- /**
527
- * 0.38: `POST /feedback/{id}/replies` (§9.7) — the body and the status picked
528
- * (`undefined`: "No change"). With `canEdit` and a row that carries `replies`, the
529
- * reply composer stands under the timeline. Return the promise: the box clears when it
530
- * resolves. A failure is the app's to toast — the server's `detail`, else
531
- * `feedbackToast.replyFailed` (0.38.1).
532
- *
533
- * 0.47 (§12, keksdose live #447): with `replyAttachments` (and `onUpload`) the
534
- * composer takes one file as the rework note does — pasted into the box, captured or
535
- * picked — uploaded first, and its URL is the third argument (`attachment_url` in the
536
- * body; server-kit 0.18).
537
- */
538
- onReply?: (body: string, status?: FeedbackStatus, attachmentUrl?: string) => void | Promise<unknown>;
539
- /**
540
- * 0.47 (§12): the reply composer takes one file — through `onUpload`,
541
- * `onCaptureScreenshot` and `reworkAttachment`, the rework note's. Off by default:
542
- * `onUpload` alone stays the rework's, so a page that passes it and an `onReply` of
543
- * `(body, status)` does not grow a file field whose file its reply would drop (round
544
- * 0.47 build reviews, keksdose and kastlan B1). Turn it on in the commit that makes
545
- * `onReply` send its third argument as `attachment_url`, with server-kit 0.18 (an
546
- * older server answers the field with a 422).
547
- */
548
- replyAttachments?: boolean;
549
- /** 0.38: the reply is in flight. */
550
- replying?: boolean;
551
- /**
552
- * 0.40 (§10.3): `POST /feedback/{id}/rework` — the author's rework as an entry of its
553
- * own (see {@link FeedbackReworkSend}). The **Rework** button shows only to the author
554
- * on an answered row, and only where the reply composer is not shown (§10.2 decision 6:
555
- * an admin answering a report sends it back with a reply whose status is `REWORK`).
556
- * Left out, the rework goes through `onUpdate` as the legacy body append — for one
557
- * minor, while the server converts it.
558
- */
559
- onRework?: FeedbackReworkSend;
560
- /** 0.38: the report's comments — the app's `FeedbackCommentThread` — in a section of
561
- * their own under the replies. A thread here draws the comments alone (0.38.1): the
562
- * Replies section above has the replies, so whatever `replies` the thread is handed
563
- * are dropped, and nothing is drawn twice. */
564
- comments?: ReactNode;
565
- /** 0.38: `PATCH /feedback/{id} {"public": next}` — draws the **Visible to others**
566
- * switch (`FeedbackPublicSwitch`) in the Status section, for the admin (`canEdit`)
567
- * and, within §9.3's window, the author. The page's own mutation fits:
568
- * `onPublicChange={(next) => update.mutate({ id: row.id, public: next })}` —
569
- * {@link FeedbackDetailPatch}'s `public` (0.38.1). */
570
- onPublicChange?: (next: boolean) => void;
571
- labels?: LabelOverride<FeedbackDetailLabels>;
572
- className?: string;
573
- }
574
-
575
- /**
576
- * The expanded row of a feedback table (§4.4): what was reported, where, with which
577
- * files, what the answer was, and where it stands — with the edits each viewer may
578
- * make. Hand it to `DataTable`'s `expandedRow`:
579
- *
580
- * ```tsx
581
- * const update = useMutation({ mutationFn: ({ id, ...patch }) => api.updateFeedback(id, patch),
582
- * onSuccess: invalidate, onError: (e) => toast.error(detailOf(e) ?? toastLabels.updateFailed) });
583
- * const changeStatus = useFeedbackStatusUndo(update.mutateAsync);
584
- * <DataTable
585
- * isExpanded={(row) => expandedId === row.id}
586
- * expandedRow={(row) => (
587
- * <FeedbackRowDetail row={row} canEdit={isAdmin && !mine} viewerId={user?.id}
588
- * onUpdate={update.mutateAsync} pending={update.isPending} statusChange={changeStatus}
589
- * onUpload={api.uploadFeedbackAttachment} fetcher={authedImageFetcher}
590
- * onCaptureScreenshot={captureAppScreenshot} />
591
- * )} … />
592
- * ```
593
- *
594
- * Mounted only while its row is expanded, so which editor is open lives here, and
595
- * collapsing the row closes it. Each editor is keyed by the row's id, so a draft is
596
- * never thrown away by a list refresh under it.
597
- */
598
- export function FeedbackRowDetail({
599
- row,
600
- canEdit,
601
- viewerId,
602
- onUpdate,
603
- pending = false,
604
- onUpload,
605
- fetcher,
606
- statusChange,
607
- onCaptureScreenshot,
608
- reworkAttachment,
609
- renderDate,
610
- pageLinkExclude,
611
- commit,
612
- showSubject = true,
613
- onReply,
614
- replyAttachments = false,
615
- replying = false,
616
- onRework,
617
- comments,
618
- onPublicChange,
619
- labels: labelsProp,
620
- className,
621
- }: FeedbackRowDetailProps) {
622
- const labels = useFeedbackDetailLabels(labelsProp);
623
- // "placeholder = the dialog's body label" (§4.4.1): read from the dialog's own
624
- // namespace, so the two can never say different things.
625
- const dialogText = useKitLabels("feedbackDialog", DEFAULT_FEEDBACK_DIALOG_LABELS);
626
- const ownStatusChange = useFeedbackStatusUndo(onUpdate);
627
- const changeStatus = statusChange ?? ownStatusChange;
628
- const [editingBody, setEditingBody] = useState(false);
629
- const [reworking, setReworking] = useState(false);
630
-
631
- const access = feedbackRowAccess(row, { canEdit, viewerId });
632
- // The body as written, without its file lines (they are shown as files below) — the
633
- // rework rounds stay in the prose: they are what was said after the answer.
634
- const bodyText = splitBodyAttachments(row.body).text;
635
- const { description } = splitDescription(row.body);
636
- const page = feedbackPage(row.context);
637
- const pageLink = page && feedbackPageLinkTarget(page, pageLinkExclude);
638
- // What the app attached is for whoever handles the report and whoever sent it, never
639
- // for another viewer of a shared row (keksdose live #481).
640
- const diagnostics = canEdit || access.isAuthor ? diagnosticsEntries(row.context?.diagnostics) : [];
641
- // 0.47 (§12): with the entries, each entry's file is drawn inline in the Replies
642
- // timeline, so the Attachment section holds the report's own files.
643
- const files = feedbackAttachmentUrls(row.replies ? { ...row, replies: undefined } : row);
644
- const fetchFile = fetcher ?? plainFeedbackFetch;
645
- // A date in a sentence ("Resolved: …"), so no weekday — through the kit's one day
646
- // ladder, which reaches the provider's `formatDate` (0.52, refactor audit 2026-10-30,
647
- // DUP-2).
648
- const day = useDayFormatter<string>(renderDate);
649
- const dateText = (iso: string) => day(iso);
650
-
651
- const saveDescription = (value: string) => {
652
- // Only a real change makes a round trip; clearing it is one ("" — the description
653
- // is optional, §7.4), and the rounds and file lines go back unchanged.
654
- if (value.trim() === description.trim()) {
655
- setEditingBody(false);
656
- return;
657
- }
658
- runMutation(onUpdate, { id: row.id, body: replaceDescription(row.body, value) }, () => setEditingBody(false));
659
- };
660
-
661
- // 0.38 (§9.7): the replies replace the outcome; a row without them is a server before
662
- // 0.38, whose frozen outcome is shown as it is, read-only.
663
- const replies = row.replies;
664
- const commentLabels = useKitLabels("feedbackComments", DEFAULT_FEEDBACK_COMMENTS_LABELS);
665
- // 0.40 (§10.2 decision 6): whoever has the reply composer answers with it — REWORK is
666
- // one of its statuses — so the Rework button is for an author without it.
667
- const composerShown = Boolean(replies && access.canEditOutcome && onReply);
668
- const canRework = access.canRework && !composerShown;
669
- const showRework = canRework && reworking;
670
-
671
- return (
672
- <FeedbackDetail className={className}>
673
- {showSubject && (
674
- <FeedbackDetailSection title={labels.subject}>
675
- <p className="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm" data-feedback-subject="">
676
- <FeedbackCategoryBadge category={row.category} />
677
- <span className="min-w-0 font-medium text-primary [overflow-wrap:anywhere]">{row.title}</span>
678
- </p>
679
- </FeedbackDetailSection>
680
- )}
681
- <FeedbackDetailSection
682
- title={labels.body}
683
- action={
684
- access.canEditDescription && !editingBody ? (
685
- <Button
686
- type="button"
687
- variant="ghost"
688
- size="sm"
689
- onClick={(event) => {
690
- event.stopPropagation();
691
- setEditingBody(true);
692
- }}
693
- aria-label={labels.editDescription}
694
- >
695
- {labels.edit}
696
- </Button>
697
- ) : undefined
698
- }
699
- >
700
- {access.canEditDescription && editingBody ? (
701
- <FeedbackNoteEditor
702
- key={row.id}
703
- // The ORIGINAL description only — see the module note.
704
- initial={description}
705
- pending={pending}
706
- commit={commit}
707
- onSave={saveDescription}
708
- onCancel={() => setEditingBody(false)}
709
- saveLabel={labels.save}
710
- cancelLabel={labels.cancel}
711
- placeholder={dialogText.bodyOptional ?? dialogText.body}
712
- />
713
- ) : (
714
- <FeedbackProse>{bodyText.trim() ? bodyText : undefined}</FeedbackProse>
715
- )}
716
- </FeedbackDetailSection>
717
-
718
- {page && (
719
- // The page it was filed on, with the full URL a click away (keksdose #278). Only
720
- // the path is a link; the query and hash, the reporter's to write, are text — and
721
- // a one-shot path is text too (FLW-7, 0.52 code review: see feedback-page-link).
722
- <FeedbackDetailSection title={labels.url}>
723
- <div className="flex min-w-0 items-center gap-1.5">
724
- <code
725
- className="min-w-0 break-all text-xs text-secondary"
726
- data-feedback-page=""
727
- data-feedback-page-unlinked={pageLink ? undefined : ""}
728
- >
729
- {pageLink ? (
730
- <TextLink href={pageLink} tone="secondary" underline="hover" stopPropagation>
731
- {page.path}
732
- </TextLink>
733
- ) : (
734
- page.path
735
- )}
736
- {page.href.slice(page.path.length)}
737
- </code>
738
- <CopyButton size="xs" className="shrink-0" text={page.url} label={labels.copyUrl} stopPropagation />
739
- </div>
740
- </FeedbackDetailSection>
741
- )}
742
-
743
- {diagnostics.length > 0 && (
744
- <FeedbackDetailSection title={labels.diagnostics}>
745
- <FeedbackDiagnosticsList entries={diagnostics} />
746
- </FeedbackDetailSection>
747
- )}
748
-
749
- {files.length > 0 && (
750
- <FeedbackDetailSection title={labels.attachment}>
751
- <div className="flex min-w-0 flex-wrap items-start gap-2">
752
- {files.map((url) =>
753
- isImageAttachment(url) ? (
754
- <AuthedImage
755
- key={url}
756
- src={url}
757
- alt={labels.attachment}
758
- fetcher={fetchFile}
759
- link
760
- stopPropagation
761
- // A broken attachment is simply not in the row (keksdose's
762
- // AuthedImage default) rather than a grey tile per failure.
763
- errorFallback={null}
764
- wrapperClassName="inline-block max-w-full"
765
- className="max-h-64 max-w-full rounded border border-subtle"
766
- />
767
- ) : (
768
- <FeedbackAttachmentDownload key={url} url={url} fetcher={fetchFile} />
769
- ),
770
- )}
771
- </div>
772
- </FeedbackDetailSection>
773
- )}
774
-
775
- <FeedbackDetailSection
776
- title={replies ? labels.replies : labels.outcome}
777
- // When the row entered DONE / WONT_DO (keksdose feedback #96).
778
- action={
779
- row.resolved_at ? (
780
- <span className="text-xs text-muted">{labels.resolvedAt(dateText(row.resolved_at))}</span>
781
- ) : undefined
782
- }
783
- >
784
- <div className="space-y-3">
785
- {replies ? (
786
- <FeedbackReplyTimeline replies={replies} fetcher={fetchFile} />
787
- ) : (
788
- <FeedbackProse>{row.outcome || undefined}</FeedbackProse>
789
- )}
790
- {composerShown && replies && onReply && (
791
- <FeedbackReplyComposer
792
- key={row.id}
793
- status={row.status}
794
- onReply={onReply}
795
- pending={replying}
796
- onUpload={replyAttachments ? onUpload : undefined}
797
- onCaptureScreenshot={replyAttachments ? onCaptureScreenshot : undefined}
798
- attachment={replyAttachments ? reworkAttachment : undefined}
799
- suggestedStatus={feedbackReplyNudge(row)}
800
- commit={commit}
801
- />
802
- )}
803
- {/* No "Open page" button here since 0.46 (keksdose live #449): the URL section
804
- above already links the page, with the path on screen. */}
805
- {canRework && !reworking && (
806
- <div className="flex flex-wrap gap-2">
807
- <Button
808
- type="button"
809
- variant="secondary"
810
- onClick={(event) => {
811
- event.stopPropagation();
812
- setReworking(true);
813
- }}
814
- >
815
- <RotateCcw className="size-3.5" aria-hidden /> {labels.rework}
816
- </Button>
817
- </div>
818
- )}
819
- </div>
820
- </FeedbackDetailSection>
821
-
822
- {comments != null && (
823
- <FeedbackDetailSection title={commentLabels.comments}>
824
- <FeedbackRepliesDrawnAboveContext.Provider value>{comments}</FeedbackRepliesDrawnAboveContext.Provider>
825
- </FeedbackDetailSection>
826
- )}
827
-
828
- {showRework && (
829
- <FeedbackReworkSection
830
- row={row}
831
- onRework={onRework}
832
- onUpdate={onUpdate}
833
- pending={pending}
834
- onUpload={onUpload}
835
- onCaptureScreenshot={onCaptureScreenshot}
836
- onSent={() => setReworking(false)}
837
- onCancel={() => setReworking(false)}
838
- attachment={reworkAttachment}
839
- commit={commit}
840
- labels={labelsProp}
841
- />
842
- )}
843
-
844
- <FeedbackDetailSection title={labels.status}>
845
- {/* Expanded: the whole enum in one click for the admin (keksdose feedback #421);
846
- everyone else the narrow set, read-only — a picture of the workflow. */}
847
- <FeedbackStatusTransitions
848
- status={row.status}
849
- statuses={
850
- access.canChangeStatus ? selectableFeedbackStatuses(row.status) : visibleFeedbackStatuses(row.status)
851
- }
852
- canEdit={access.canChangeStatus}
853
- commit={commit}
854
- onPick={(status) => changeStatus(row, status)}
855
- variant="pill"
856
- />
857
- {onPublicChange && (
858
- <FeedbackPublicSwitch
859
- row={row}
860
- isAdmin={canEdit}
861
- viewerId={viewerId}
862
- onChange={onPublicChange}
863
- pending={pending}
864
- commit={commit}
865
- className="mt-3"
866
- />
867
- )}
868
- </FeedbackDetailSection>
869
- </FeedbackDetail>
870
- );
871
- }