@eifi1/ui-kit 0.53.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 (902) hide show
  1. package/README.md +96 -82
  2. package/dist/account/delete-account-setting.d.ts +3 -2
  3. package/dist/account/delete-account-setting.js.map +1 -1
  4. package/dist/admin/plan-change.js +2 -2
  5. package/dist/admin/plan-change.js.map +1 -1
  6. package/dist/admin/user-roster.d.ts +6 -0
  7. package/dist/admin/user-roster.js +4 -0
  8. package/dist/admin/user-roster.js.map +1 -1
  9. package/dist/auth/auth-errors.d.ts +36 -0
  10. package/dist/auth/auth-errors.js +20 -0
  11. package/dist/auth/auth-errors.js.map +1 -1
  12. package/dist/billing/billing-labels.d.ts +26 -0
  13. package/dist/billing/billing-labels.js +9 -0
  14. package/dist/billing/billing-labels.js.map +1 -1
  15. package/dist/billing/subscription-standing.d.ts +61 -0
  16. package/dist/billing/subscription-standing.js +51 -0
  17. package/dist/billing/subscription-standing.js.map +1 -0
  18. package/dist/billing/usage-meter.d.ts +52 -0
  19. package/dist/billing/usage-meter.js +52 -0
  20. package/dist/billing/usage-meter.js.map +1 -0
  21. package/dist/chart.d.ts +1 -0
  22. package/dist/chart.js +4 -0
  23. package/dist/chart.js.map +1 -1
  24. package/dist/components/alert-banner.js +2 -3
  25. package/dist/components/alert-banner.js.map +1 -1
  26. package/dist/components/amount-input.d.ts +2 -1
  27. package/dist/components/amount-input.js +3 -15
  28. package/dist/components/amount-input.js.map +1 -1
  29. package/dist/components/autocomplete.js +2 -2
  30. package/dist/components/autocomplete.js.map +1 -1
  31. package/dist/components/bulk-action-bar.js +2 -1
  32. package/dist/components/bulk-action-bar.js.map +1 -1
  33. package/dist/components/button.d.ts +35 -1
  34. package/dist/components/button.js +5 -9
  35. package/dist/components/button.js.map +1 -1
  36. package/dist/components/calendar-heatmap.js +6 -4
  37. package/dist/components/calendar-heatmap.js.map +1 -1
  38. package/dist/components/camera-button.d.ts +89 -0
  39. package/dist/components/camera-button.js +122 -0
  40. package/dist/components/camera-button.js.map +1 -0
  41. package/dist/components/camera-capture.d.ts +66 -0
  42. package/dist/components/camera-capture.js +190 -0
  43. package/dist/components/camera-capture.js.map +1 -0
  44. package/dist/components/camera-labels.d.ts +20 -0
  45. package/dist/components/camera-labels.js +15 -0
  46. package/dist/components/camera-labels.js.map +1 -0
  47. package/dist/components/chart-edge.d.ts +9 -0
  48. package/dist/components/chart-edge.js +14 -3
  49. package/dist/components/chart-edge.js.map +1 -1
  50. package/dist/components/chart-zoom-core.js +34 -29
  51. package/dist/components/chart-zoom-core.js.map +1 -1
  52. package/dist/components/checkbox-group.js +1 -1
  53. package/dist/components/checkbox-group.js.map +1 -1
  54. package/dist/components/combobox-core.js +3 -2
  55. package/dist/components/combobox-core.js.map +1 -1
  56. package/dist/components/combobox.js +2 -2
  57. package/dist/components/combobox.js.map +1 -1
  58. package/dist/components/consent-again-notice-labels.d.ts +25 -0
  59. package/dist/components/consent-again-notice-labels.js +15 -0
  60. package/dist/components/consent-again-notice-labels.js.map +1 -0
  61. package/dist/components/consent-again-notice.d.ts +85 -0
  62. package/dist/components/consent-again-notice.js +94 -0
  63. package/dist/components/consent-again-notice.js.map +1 -0
  64. package/dist/components/country-select.js +2 -7
  65. package/dist/components/country-select.js.map +1 -1
  66. package/dist/components/currency-option-list.d.ts +2 -1
  67. package/dist/components/currency-option-list.js +10 -3
  68. package/dist/components/currency-option-list.js.map +1 -1
  69. package/dist/components/currency-select.d.ts +3 -1
  70. package/dist/components/currency-select.js +2 -2
  71. package/dist/components/currency-select.js.map +1 -1
  72. package/dist/components/danger-confirm.d.ts +22 -1
  73. package/dist/components/danger-confirm.js +52 -30
  74. package/dist/components/danger-confirm.js.map +1 -1
  75. package/dist/components/data-table-column-settings.js +2 -2
  76. package/dist/components/data-table-column-settings.js.map +1 -1
  77. package/dist/components/data-table-filter-popover.d.ts +2 -1
  78. package/dist/components/data-table-filter-popover.js +3 -2
  79. package/dist/components/data-table-filter-popover.js.map +1 -1
  80. package/dist/components/data-table-filters.d.ts +33 -3
  81. package/dist/components/data-table-filters.js +6 -4
  82. package/dist/components/data-table-filters.js.map +1 -1
  83. package/dist/components/data-table-fit.js.map +1 -1
  84. package/dist/components/data-table-virtual.js +13 -3
  85. package/dist/components/data-table-virtual.js.map +1 -1
  86. package/dist/components/date-field.js +2 -2
  87. package/dist/components/date-field.js.map +1 -1
  88. package/dist/components/date-picker.js +2 -2
  89. package/dist/components/date-picker.js.map +1 -1
  90. package/dist/components/date-range-picker.js +2 -6
  91. package/dist/components/date-range-picker.js.map +1 -1
  92. package/dist/components/dialog-frame.d.ts +5 -1
  93. package/dist/components/dialog-frame.js +6 -2
  94. package/dist/components/dialog-frame.js.map +1 -1
  95. package/dist/components/dropdown.js +7 -3
  96. package/dist/components/dropdown.js.map +1 -1
  97. package/dist/components/entity-combobox.js +2 -2
  98. package/dist/components/entity-combobox.js.map +1 -1
  99. package/dist/components/field-parts.d.ts +108 -6
  100. package/dist/components/field-parts.js +59 -6
  101. package/dist/components/field-parts.js.map +1 -1
  102. package/dist/components/field-suggestion-labels.d.ts +2 -0
  103. package/dist/components/field-suggestion-labels.js +10 -0
  104. package/dist/components/field-suggestion-labels.js.map +1 -0
  105. package/dist/components/field.js +1 -1
  106. package/dist/components/field.js.map +1 -1
  107. package/dist/components/file-button.d.ts +1 -1
  108. package/dist/components/file-button.js.map +1 -1
  109. package/dist/components/floating-panel.d.ts +7 -6
  110. package/dist/components/floating-panel.js +3 -17
  111. package/dist/components/floating-panel.js.map +1 -1
  112. package/dist/components/form-actions.d.ts +3 -2
  113. package/dist/components/form-actions.js.map +1 -1
  114. package/dist/components/hover-menu.js +3 -2
  115. package/dist/components/hover-menu.js.map +1 -1
  116. package/dist/components/icon-button.d.ts +23 -5
  117. package/dist/components/icon-button.js +6 -8
  118. package/dist/components/icon-button.js.map +1 -1
  119. package/dist/components/inline-confirm.js +2 -1
  120. package/dist/components/inline-confirm.js.map +1 -1
  121. package/dist/components/inline-entity-combobox.js +2 -2
  122. package/dist/components/inline-entity-combobox.js.map +1 -1
  123. package/dist/components/input.js +2 -2
  124. package/dist/components/input.js.map +1 -1
  125. package/dist/components/jump-calendar.js +3 -3
  126. package/dist/components/jump-calendar.js.map +1 -1
  127. package/dist/components/legal.d.ts +13 -1
  128. package/dist/components/legal.js +12 -0
  129. package/dist/components/legal.js.map +1 -1
  130. package/dist/components/legended-series-chart.d.ts +80 -0
  131. package/dist/components/legended-series-chart.js +70 -0
  132. package/dist/components/legended-series-chart.js.map +1 -0
  133. package/dist/components/lightbox.js +2 -1
  134. package/dist/components/lightbox.js.map +1 -1
  135. package/dist/components/mini-calendar.js +16 -7
  136. package/dist/components/mini-calendar.js.map +1 -1
  137. package/dist/components/modal.d.ts +48 -0
  138. package/dist/components/modal.js +26 -6
  139. package/dist/components/modal.js.map +1 -1
  140. package/dist/components/month-picker.d.ts +1 -1
  141. package/dist/components/month-picker.js +6 -6
  142. package/dist/components/month-picker.js.map +1 -1
  143. package/dist/components/multi-entity-combobox.js +2 -2
  144. package/dist/components/multi-entity-combobox.js.map +1 -1
  145. package/dist/components/multi-select.js +2 -6
  146. package/dist/components/multi-select.js.map +1 -1
  147. package/dist/components/number-input.js +2 -2
  148. package/dist/components/number-input.js.map +1 -1
  149. package/dist/components/page-header-layout.d.ts +18 -0
  150. package/dist/components/page-header-layout.js +23 -0
  151. package/dist/components/page-header-layout.js.map +1 -0
  152. package/dist/components/page-header-skeleton.d.ts +41 -0
  153. package/dist/components/page-header-skeleton.js +52 -0
  154. package/dist/components/page-header-skeleton.js.map +1 -0
  155. package/dist/components/page-header.js +4 -17
  156. package/dist/components/page-header.js.map +1 -1
  157. package/dist/components/popover.js +7 -2
  158. package/dist/components/popover.js.map +1 -1
  159. package/dist/components/release-notes-labels.d.ts +16 -0
  160. package/dist/components/release-notes-labels.js +18 -0
  161. package/dist/components/release-notes-labels.js.map +1 -0
  162. package/dist/components/release-notes.d.ts +65 -0
  163. package/dist/components/release-notes.js +65 -0
  164. package/dist/components/release-notes.js.map +1 -0
  165. package/dist/components/select.js +2 -2
  166. package/dist/components/select.js.map +1 -1
  167. package/dist/components/series-chart-labels.d.ts +9 -0
  168. package/dist/components/series-chart-labels.js +3 -1
  169. package/dist/components/series-chart-labels.js.map +1 -1
  170. package/dist/components/series-chart.d.ts +5 -0
  171. package/dist/components/series-chart.js +89 -36
  172. package/dist/components/series-chart.js.map +1 -1
  173. package/dist/components/stat-tile.d.ts +21 -2
  174. package/dist/components/stat-tile.js +4 -2
  175. package/dist/components/stat-tile.js.map +1 -1
  176. package/dist/components/toggle-group.js +3 -2
  177. package/dist/components/toggle-group.js.map +1 -1
  178. package/dist/components/treemap-layout.js.map +1 -1
  179. package/dist/components/treemap.d.ts +17 -15
  180. package/dist/components/treemap.js +167 -85
  181. package/dist/components/treemap.js.map +1 -1
  182. package/dist/currencies.d.ts +16 -2
  183. package/dist/currencies.js +2 -1
  184. package/dist/currencies.js.map +1 -1
  185. package/dist/eslint/index.js +1 -1
  186. package/dist/eslint/role-utilities.d.ts +2 -2
  187. package/dist/eslint/role-utilities.js.map +1 -1
  188. package/dist/feedback/feedback-context-labels.js +2 -1
  189. package/dist/feedback/feedback-context-labels.js.map +1 -1
  190. package/dist/feedback/feedback-context.d.ts +19 -3
  191. package/dist/feedback/feedback-context.js +12 -1
  192. package/dist/feedback/feedback-context.js.map +1 -1
  193. package/dist/feedback/feedback-diagnostics.d.ts +17 -0
  194. package/dist/feedback/feedback-diagnostics.js +27 -0
  195. package/dist/feedback/feedback-diagnostics.js.map +1 -0
  196. package/dist/feedback/feedback-dialog.d.ts +10 -0
  197. package/dist/feedback/feedback-dialog.js +6 -4
  198. package/dist/feedback/feedback-dialog.js.map +1 -1
  199. package/dist/feedback/feedback-inbox-page.d.ts +260 -0
  200. package/dist/feedback/feedback-inbox-page.js +207 -0
  201. package/dist/feedback/feedback-inbox-page.js.map +1 -0
  202. package/dist/feedback/feedback-record.d.ts +5 -0
  203. package/dist/feedback/feedback-record.js.map +1 -1
  204. package/dist/feedback/feedback-row-detail-labels.js +1 -0
  205. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  206. package/dist/feedback/feedback-row-detail.d.ts +3 -0
  207. package/dist/feedback/feedback-row-detail.js +3 -0
  208. package/dist/feedback/feedback-row-detail.js.map +1 -1
  209. package/dist/feedback/feedback-submit-dialog.d.ts +5 -1
  210. package/dist/feedback/feedback-submit-dialog.js +15 -3
  211. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  212. package/dist/feedback/feedback-submit.d.ts +30 -2
  213. package/dist/feedback/feedback-submit.js +5 -2
  214. package/dist/feedback/feedback-submit.js.map +1 -1
  215. package/dist/feedback/feedback-vocabulary.js +2 -2
  216. package/dist/feedback/feedback-vocabulary.js.map +1 -1
  217. package/dist/feedback.d.ts +1 -0
  218. package/dist/feedback.js +6 -0
  219. package/dist/feedback.js.map +1 -1
  220. package/dist/hooks/use-debounce.d.ts +32 -5
  221. package/dist/hooks/use-debounce.js +6 -5
  222. package/dist/hooks/use-debounce.js.map +1 -1
  223. package/dist/hooks/use-file-picker.d.ts +3 -1
  224. package/dist/hooks/use-file-picker.js.map +1 -1
  225. package/dist/hooks/use-focus-trap.d.ts +19 -3
  226. package/dist/hooks/use-focus-trap.js +15 -5
  227. package/dist/hooks/use-focus-trap.js.map +1 -1
  228. package/dist/hooks/use-has-camera.d.ts +36 -0
  229. package/dist/hooks/use-has-camera.js +53 -0
  230. package/dist/hooks/use-has-camera.js.map +1 -0
  231. package/dist/hooks/use-hotkey.js +2 -1
  232. package/dist/hooks/use-hotkey.js.map +1 -1
  233. package/dist/hooks/use-overlay-history.d.ts +6 -1
  234. package/dist/hooks/use-overlay-history.js +10 -2
  235. package/dist/hooks/use-overlay-history.js.map +1 -1
  236. package/dist/i18n/defaults.js +11 -1
  237. package/dist/i18n/defaults.js.map +1 -1
  238. package/dist/i18n/german.js +78 -4
  239. package/dist/i18n/german.js.map +1 -1
  240. package/dist/i18n/kit-labels.d.ts +20 -0
  241. package/dist/i18n/kit-labels.js.map +1 -1
  242. package/dist/i18n/locales/en.js +95 -5
  243. package/dist/i18n/locales/en.js.map +3 -3
  244. package/dist/i18n/locales/es.js +74 -4
  245. package/dist/i18n/locales/es.js.map +1 -1
  246. package/dist/i18n/locales/fr.js +75 -3
  247. package/dist/i18n/locales/fr.js.map +1 -1
  248. package/dist/i18n/locales/hu.js +77 -4
  249. package/dist/i18n/locales/hu.js.map +1 -1
  250. package/dist/i18n/locales/it.js +77 -4
  251. package/dist/i18n/locales/it.js.map +1 -1
  252. package/dist/i18n/locales/zh.js +74 -4
  253. package/dist/i18n/locales/zh.js.map +1 -1
  254. package/dist/i18n/review.js +22 -1
  255. package/dist/i18n/review.js.map +1 -1
  256. package/dist/index.d.ts +27 -8
  257. package/dist/index.js +41 -2
  258. package/dist/index.js.map +1 -1
  259. package/dist/landing/landing-labels.d.ts +8 -0
  260. package/dist/landing/landing-labels.js +2 -1
  261. package/dist/landing/landing-labels.js.map +1 -1
  262. package/dist/lib/changelog.d.ts +130 -0
  263. package/dist/lib/changelog.js +137 -0
  264. package/dist/lib/changelog.js.map +1 -0
  265. package/dist/lib/clipboard-minus.js +2 -2
  266. package/dist/lib/clipboard-minus.js.map +1 -1
  267. package/dist/lib/dates.d.ts +36 -4
  268. package/dist/lib/dates.js +49 -13
  269. package/dist/lib/dates.js.map +1 -1
  270. package/dist/lib/editable-content.d.ts +33 -0
  271. package/dist/lib/editable-content.js +15 -0
  272. package/dist/lib/editable-content.js.map +1 -0
  273. package/dist/lib/focus-left.d.ts +47 -1
  274. package/dist/lib/focus-left.js +11 -2
  275. package/dist/lib/focus-left.js.map +1 -1
  276. package/dist/lib/format.d.ts +37 -2
  277. package/dist/lib/format.js +25 -1
  278. package/dist/lib/format.js.map +1 -1
  279. package/dist/lib/intl-cache.d.ts +4 -2
  280. package/dist/lib/intl-cache.js.map +1 -1
  281. package/dist/lib/server-wake.d.ts +49 -9
  282. package/dist/lib/server-wake.js +25 -14
  283. package/dist/lib/server-wake.js.map +1 -1
  284. package/dist/lib/session-refresh.d.ts +53 -0
  285. package/dist/lib/session-refresh.js +27 -1
  286. package/dist/lib/session-refresh.js.map +1 -1
  287. package/dist/lib/translation-review.d.ts +26 -0
  288. package/dist/lib/translation-review.js +14 -0
  289. package/dist/lib/translation-review.js.map +1 -1
  290. package/dist/rhf/fields.js +3 -3
  291. package/dist/rhf/fields.js.map +1 -1
  292. package/dist/shell/app-shell.d.ts +25 -1
  293. package/dist/shell/app-shell.js +3 -1
  294. package/dist/shell/app-shell.js.map +1 -1
  295. package/dist/shell/dev-menu.d.ts +3 -0
  296. package/dist/shell/dev-menu.js +4 -2
  297. package/dist/shell/dev-menu.js.map +1 -1
  298. package/dist/shell/held-changes-banner-labels.d.ts +23 -0
  299. package/dist/shell/held-changes-banner-labels.js +14 -0
  300. package/dist/shell/held-changes-banner-labels.js.map +1 -0
  301. package/dist/shell/held-changes-banner.d.ts +75 -0
  302. package/dist/shell/held-changes-banner.js +106 -0
  303. package/dist/shell/held-changes-banner.js.map +1 -0
  304. package/dist/shell/sync-status-indicator.d.ts +27 -12
  305. package/dist/shell/sync-status-indicator.js +13 -4
  306. package/dist/shell/sync-status-indicator.js.map +1 -1
  307. package/dist/shell/top-bar-parts-labels.d.ts +5 -0
  308. package/dist/shell/top-bar-parts-labels.js +3 -1
  309. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  310. package/dist/shell.d.ts +2 -0
  311. package/dist/shell.js +3 -0
  312. package/dist/shell.js.map +1 -1
  313. package/dist/sync/engine.d.ts +11 -2
  314. package/dist/sync/engine.js +13 -5
  315. package/dist/sync/engine.js.map +1 -1
  316. package/dist/sync/hooks.d.ts +3 -2
  317. package/dist/sync/hooks.js +4 -2
  318. package/dist/sync/hooks.js.map +1 -1
  319. package/dist/testing/css-variables.generated.d.ts +2 -2
  320. package/dist/testing/css-variables.generated.js +1 -1
  321. package/dist/testing/css-variables.generated.js.map +1 -1
  322. package/dist/theme/chart-palette.d.ts +18 -0
  323. package/dist/theme/chart-palette.js +17 -1
  324. package/dist/theme/chart-palette.js.map +1 -1
  325. package/dist/theme/contrast-tokens.d.ts +3 -3
  326. package/dist/theme/contrast-tokens.js.map +1 -1
  327. package/dist/theme/contrast.d.ts +4 -4
  328. package/dist/theme/contrast.js.map +1 -1
  329. package/dist/tour/tour-overlay.js +2 -1
  330. package/dist/tour/tour-overlay.js.map +1 -1
  331. package/package.json +5 -9
  332. package/tokens.css +19 -54
  333. package/src/account/account-parts.ts +0 -47
  334. package/src/account/account-settings-labels.ts +0 -240
  335. package/src/account/account-settings.tsx +0 -698
  336. package/src/account/data-export-setting-labels.ts +0 -20
  337. package/src/account/data-export-setting.tsx +0 -200
  338. package/src/account/delete-account-setting-labels.ts +0 -33
  339. package/src/account/delete-account-setting.tsx +0 -341
  340. package/src/account/email-change-setting-labels.ts +0 -31
  341. package/src/account/email-change-setting.tsx +0 -443
  342. package/src/account/passkeys-setting.tsx +0 -445
  343. package/src/account/sessions-setting-labels.ts +0 -24
  344. package/src/account/sessions-setting.tsx +0 -283
  345. package/src/admin/admin-action-confirm-labels.ts +0 -19
  346. package/src/admin/admin-action-confirm.tsx +0 -509
  347. package/src/admin/admin-action-log-labels.ts +0 -83
  348. package/src/admin/admin-action-log.tsx +0 -464
  349. package/src/admin/admin-area-labels.ts +0 -114
  350. package/src/admin/admin-forbidden.tsx +0 -75
  351. package/src/admin/admin-overview.tsx +0 -258
  352. package/src/admin/admin-parts.ts +0 -68
  353. package/src/admin/admin-sections.tsx +0 -208
  354. package/src/admin/admin-tool-links.tsx +0 -90
  355. package/src/admin/invitations-panel-labels.ts +0 -31
  356. package/src/admin/invitations-panel.tsx +0 -516
  357. package/src/admin/mail-test-card-labels.ts +0 -19
  358. package/src/admin/mail-test-card.tsx +0 -189
  359. package/src/admin/plan-change-labels.ts +0 -5
  360. package/src/admin/plan-change.tsx +0 -474
  361. package/src/admin/reviewer-scope-editor-labels.ts +0 -16
  362. package/src/admin/reviewer-scope-editor.tsx +0 -224
  363. package/src/admin/role-select-labels.ts +0 -16
  364. package/src/admin/role-select.tsx +0 -282
  365. package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
  366. package/src/admin/transfer-ownership-dialog.tsx +0 -162
  367. package/src/admin/user-roster-labels.ts +0 -17
  368. package/src/admin/user-roster.tsx +0 -559
  369. package/src/auth/accept-invitation-labels.ts +0 -21
  370. package/src/auth/accept-invitation.tsx +0 -210
  371. package/src/auth/auth-errors-labels.ts +0 -23
  372. package/src/auth/auth-errors.ts +0 -370
  373. package/src/auth/complete-name-dialog-labels.ts +0 -16
  374. package/src/auth/complete-name-dialog.tsx +0 -253
  375. package/src/auth/email-tag.ts +0 -75
  376. package/src/auth/forgot-password-form-labels.ts +0 -20
  377. package/src/auth/forgot-password-form.tsx +0 -221
  378. package/src/auth/form-rules.ts +0 -40
  379. package/src/auth/new-password-fields.tsx +0 -85
  380. package/src/auth/not-found-page-labels.ts +0 -12
  381. package/src/auth/not-found-page.tsx +0 -95
  382. package/src/auth/register-form-labels.ts +0 -31
  383. package/src/auth/register-form.tsx +0 -456
  384. package/src/auth/reset-password-form-labels.ts +0 -27
  385. package/src/auth/reset-password-form.tsx +0 -341
  386. package/src/auth/sign-in-form-labels.ts +0 -44
  387. package/src/auth/sign-in-form.tsx +0 -858
  388. package/src/auth/status-parts.tsx +0 -132
  389. package/src/auth/verify-email-labels.ts +0 -26
  390. package/src/auth/verify-email.tsx +0 -445
  391. package/src/billing/billing-banner.tsx +0 -258
  392. package/src/billing/billing-labels.ts +0 -381
  393. package/src/billing/billing-lock.ts +0 -108
  394. package/src/billing/billing-overview.ts +0 -157
  395. package/src/billing/billing-standing.ts +0 -80
  396. package/src/billing/cancel-request.ts +0 -97
  397. package/src/billing/cancel-subscription.tsx +0 -98
  398. package/src/billing/checkout-processing.ts +0 -394
  399. package/src/billing/checkout-return.ts +0 -90
  400. package/src/billing/pay-page.ts +0 -330
  401. package/src/billing/plan-card.tsx +0 -562
  402. package/src/billing/plan-change-labels.ts +0 -66
  403. package/src/billing/plan-limit-notice.tsx +0 -148
  404. package/src/billing/plan-limit-toast.tsx +0 -90
  405. package/src/billing/plan-limit.ts +0 -52
  406. package/src/billing/plan-price.ts +0 -98
  407. package/src/billing/plan-switch.tsx +0 -216
  408. package/src/billing/provider-page.ts +0 -84
  409. package/src/billing/subscription-actions.tsx +0 -247
  410. package/src/billing/subscription-status-chip.tsx +0 -95
  411. package/src/chart.ts +0 -103
  412. package/src/components/account-chips-labels.ts +0 -16
  413. package/src/components/account-chips.tsx +0 -474
  414. package/src/components/alert-banner.tsx +0 -670
  415. package/src/components/amount-input.tsx +0 -815
  416. package/src/components/appearance-labels.ts +0 -63
  417. package/src/components/authed-image-labels.ts +0 -11
  418. package/src/components/authed-image.tsx +0 -209
  419. package/src/components/autocomplete.tsx +0 -645
  420. package/src/components/breadcrumbs-labels.ts +0 -10
  421. package/src/components/breadcrumbs.tsx +0 -205
  422. package/src/components/bulk-action-bar-labels.ts +0 -11
  423. package/src/components/bulk-action-bar.tsx +0 -443
  424. package/src/components/button-group.tsx +0 -223
  425. package/src/components/button-look.ts +0 -256
  426. package/src/components/button.tsx +0 -339
  427. package/src/components/calculator.tsx +0 -341
  428. package/src/components/calendar-heatmap-labels.ts +0 -15
  429. package/src/components/calendar-heatmap.tsx +0 -594
  430. package/src/components/card.tsx +0 -377
  431. package/src/components/chart-edge.ts +0 -106
  432. package/src/components/chart-figure.tsx +0 -35
  433. package/src/components/chart-height.ts +0 -30
  434. package/src/components/chart-zoom-core.tsx +0 -627
  435. package/src/components/chart-zoom.tsx +0 -22
  436. package/src/components/chart.tsx +0 -554
  437. package/src/components/checkbox-group.tsx +0 -247
  438. package/src/components/checkbox.tsx +0 -346
  439. package/src/components/chip-input.tsx +0 -370
  440. package/src/components/chip-labels.ts +0 -13
  441. package/src/components/chip.tsx +0 -843
  442. package/src/components/choice-card.tsx +0 -544
  443. package/src/components/column-mapper-labels.ts +0 -38
  444. package/src/components/column-mapper.tsx +0 -655
  445. package/src/components/combobox-core.tsx +0 -1321
  446. package/src/components/combobox-suggestions.tsx +0 -131
  447. package/src/components/combobox.tsx +0 -716
  448. package/src/components/confirm-context.ts +0 -7
  449. package/src/components/confirm-dialog-labels.ts +0 -13
  450. package/src/components/confirm-dialog.tsx +0 -341
  451. package/src/components/copy-button-labels.ts +0 -13
  452. package/src/components/copy-button.tsx +0 -192
  453. package/src/components/country-select-labels.ts +0 -11
  454. package/src/components/country-select.tsx +0 -539
  455. package/src/components/currency-option-list.tsx +0 -180
  456. package/src/components/currency-select.tsx +0 -341
  457. package/src/components/danger-confirm-labels.ts +0 -20
  458. package/src/components/danger-confirm.tsx +0 -934
  459. package/src/components/data-table-cells.tsx +0 -118
  460. package/src/components/data-table-column-settings.tsx +0 -198
  461. package/src/components/data-table-filter-popover.tsx +0 -281
  462. package/src/components/data-table-filters.ts +0 -287
  463. package/src/components/data-table-fit.ts +0 -301
  464. package/src/components/data-table-groups.tsx +0 -288
  465. package/src/components/data-table-head.tsx +0 -280
  466. package/src/components/data-table-labels.ts +0 -198
  467. package/src/components/data-table-leading-row.tsx +0 -58
  468. package/src/components/data-table-mobile.tsx +0 -1117
  469. package/src/components/data-table-pagination.tsx +0 -202
  470. package/src/components/data-table-resize.ts +0 -188
  471. package/src/components/data-table-row-actions.tsx +0 -302
  472. package/src/components/data-table-row.tsx +0 -496
  473. package/src/components/data-table-selection.ts +0 -71
  474. package/src/components/data-table-shared.tsx +0 -287
  475. package/src/components/data-table-sort.ts +0 -163
  476. package/src/components/data-table-virtual.ts +0 -576
  477. package/src/components/data-table.tsx +0 -2598
  478. package/src/components/date-field.tsx +0 -684
  479. package/src/components/date-format-setting.tsx +0 -64
  480. package/src/components/date-picker.tsx +0 -404
  481. package/src/components/date-range-picker.tsx +0 -518
  482. package/src/components/description-list-labels.ts +0 -9
  483. package/src/components/description-list.tsx +0 -386
  484. package/src/components/dialog-frame-labels.ts +0 -7
  485. package/src/components/dialog-frame.tsx +0 -276
  486. package/src/components/disclosure.tsx +0 -476
  487. package/src/components/dropdown.tsx +0 -461
  488. package/src/components/empty-state.tsx +0 -136
  489. package/src/components/entity-combobox.tsx +0 -422
  490. package/src/components/error-boundary-labels.ts +0 -20
  491. package/src/components/error-boundary.tsx +0 -675
  492. package/src/components/facing-pair.ts +0 -93
  493. package/src/components/field-base-labels.ts +0 -20
  494. package/src/components/field-base.tsx +0 -656
  495. package/src/components/field-parts.tsx +0 -825
  496. package/src/components/field-strip.tsx +0 -129
  497. package/src/components/field.tsx +0 -206
  498. package/src/components/file-button.tsx +0 -295
  499. package/src/components/file-dropzone.tsx +0 -559
  500. package/src/components/floating-panel-labels.ts +0 -10
  501. package/src/components/floating-panel.tsx +0 -828
  502. package/src/components/focus-ring.ts +0 -16
  503. package/src/components/form-actions-labels.ts +0 -11
  504. package/src/components/form-actions.tsx +0 -578
  505. package/src/components/full-bleed-dialog.tsx +0 -294
  506. package/src/components/grouped-picker.tsx +0 -184
  507. package/src/components/help-popover.tsx +0 -117
  508. package/src/components/hover-menu.tsx +0 -343
  509. package/src/components/iban-input-labels.ts +0 -14
  510. package/src/components/iban-input.tsx +0 -236
  511. package/src/components/icon-button.tsx +0 -959
  512. package/src/components/icon-picker-labels.ts +0 -13
  513. package/src/components/icon-picker.tsx +0 -232
  514. package/src/components/image-grid-labels.ts +0 -11
  515. package/src/components/image-grid.tsx +0 -202
  516. package/src/components/inline-confirm.tsx +0 -116
  517. package/src/components/inline-edit-field-labels.ts +0 -11
  518. package/src/components/inline-edit-field.tsx +0 -552
  519. package/src/components/inline-entity-combobox.tsx +0 -849
  520. package/src/components/input.tsx +0 -394
  521. package/src/components/jump-calendar.tsx +0 -265
  522. package/src/components/language-select.tsx +0 -93
  523. package/src/components/legal-labels.ts +0 -105
  524. package/src/components/legal-page.tsx +0 -711
  525. package/src/components/legal.tsx +0 -668
  526. package/src/components/lightbox-labels.ts +0 -18
  527. package/src/components/lightbox.tsx +0 -399
  528. package/src/components/line-items-labels.ts +0 -14
  529. package/src/components/line-items.tsx +0 -602
  530. package/src/components/list-labels.ts +0 -12
  531. package/src/components/list.tsx +0 -870
  532. package/src/components/loading-state.tsx +0 -78
  533. package/src/components/measured-grid-labels.ts +0 -25
  534. package/src/components/measured-grid.tsx +0 -837
  535. package/src/components/menu-item.tsx +0 -241
  536. package/src/components/mini-calendar-labels.ts +0 -17
  537. package/src/components/mini-calendar.tsx +0 -789
  538. package/src/components/modal.tsx +0 -505
  539. package/src/components/money-draft.ts +0 -83
  540. package/src/components/money-field.tsx +0 -76
  541. package/src/components/month-grid.tsx +0 -229
  542. package/src/components/month-picker-labels.ts +0 -22
  543. package/src/components/month-picker.tsx +0 -1087
  544. package/src/components/multi-entity-combobox.tsx +0 -369
  545. package/src/components/multi-select.tsx +0 -376
  546. package/src/components/nav-pills.tsx +0 -198
  547. package/src/components/number-field.tsx +0 -327
  548. package/src/components/number-input.tsx +0 -558
  549. package/src/components/numeric-field.ts +0 -169
  550. package/src/components/numpad-sheet.tsx +0 -285
  551. package/src/components/one-time-code-input.tsx +0 -270
  552. package/src/components/page-contents-labels.ts +0 -9
  553. package/src/components/page-contents.tsx +0 -282
  554. package/src/components/page-header-context.ts +0 -8
  555. package/src/components/page-header.tsx +0 -298
  556. package/src/components/password-strength-labels.ts +0 -22
  557. package/src/components/password-strength.tsx +0 -241
  558. package/src/components/phone-input-labels.ts +0 -10
  559. package/src/components/phone-input.tsx +0 -282
  560. package/src/components/picker-sheet.tsx +0 -330
  561. package/src/components/pie-chart-labels.ts +0 -40
  562. package/src/components/pie-chart.tsx +0 -480
  563. package/src/components/popover-labels.ts +0 -14
  564. package/src/components/popover.tsx +0 -268
  565. package/src/components/progress-bar-labels.ts +0 -10
  566. package/src/components/progress-bar.tsx +0 -479
  567. package/src/components/qr-code.tsx +0 -76
  568. package/src/components/reauth-dialog-labels.ts +0 -13
  569. package/src/components/reauth-dialog.tsx +0 -265
  570. package/src/components/row-actions-labels.ts +0 -12
  571. package/src/components/row-actions.tsx +0 -795
  572. package/src/components/scroll-area.tsx +0 -123
  573. package/src/components/search-field.tsx +0 -192
  574. package/src/components/select.tsx +0 -294
  575. package/src/components/separator.tsx +0 -33
  576. package/src/components/series-chart-axes.ts +0 -342
  577. package/src/components/series-chart-budget.ts +0 -150
  578. package/src/components/series-chart-labels.ts +0 -33
  579. package/src/components/series-chart-thin.ts +0 -180
  580. package/src/components/series-chart-ticks.ts +0 -194
  581. package/src/components/series-chart.tsx +0 -1906
  582. package/src/components/server-wake-labels.ts +0 -11
  583. package/src/components/server-wake.tsx +0 -129
  584. package/src/components/settings-fields.tsx +0 -237
  585. package/src/components/share-card-labels.ts +0 -30
  586. package/src/components/share-card.tsx +0 -675
  587. package/src/components/signature-pad-labels.ts +0 -24
  588. package/src/components/signature-pad.tsx +0 -747
  589. package/src/components/signed-amount-labels.ts +0 -10
  590. package/src/components/signed-amount.tsx +0 -336
  591. package/src/components/skeleton.tsx +0 -80
  592. package/src/components/slider.tsx +0 -338
  593. package/src/components/sparkline-labels.ts +0 -14
  594. package/src/components/sparkline.tsx +0 -322
  595. package/src/components/spinner.tsx +0 -81
  596. package/src/components/stat-tile-labels.ts +0 -15
  597. package/src/components/stat-tile.tsx +0 -725
  598. package/src/components/status-dot.tsx +0 -170
  599. package/src/components/swatch-picker-labels.ts +0 -10
  600. package/src/components/swatch-picker.tsx +0 -283
  601. package/src/components/swipeable-row.tsx +0 -386
  602. package/src/components/switch.tsx +0 -273
  603. package/src/components/table-skeleton.tsx +0 -136
  604. package/src/components/table.tsx +0 -647
  605. package/src/components/tabs-labels.ts +0 -13
  606. package/src/components/tabs.tsx +0 -693
  607. package/src/components/text-link.tsx +0 -359
  608. package/src/components/text.tsx +0 -150
  609. package/src/components/textarea.tsx +0 -330
  610. package/src/components/tile-radio.tsx +0 -332
  611. package/src/components/time-input.tsx +0 -121
  612. package/src/components/toast-labels.ts +0 -12
  613. package/src/components/toast.tsx +0 -519
  614. package/src/components/toggle-group.tsx +0 -752
  615. package/src/components/toggle-legend.tsx +0 -394
  616. package/src/components/tooltip.tsx +0 -1149
  617. package/src/components/translation-review-editor.tsx +0 -290
  618. package/src/components/translation-review-labels.ts +0 -181
  619. package/src/components/translation-review-parts.tsx +0 -272
  620. package/src/components/translation-review.tsx +0 -1240
  621. package/src/components/tree-view.tsx +0 -589
  622. package/src/components/treemap-labels.ts +0 -47
  623. package/src/components/treemap-layout.ts +0 -210
  624. package/src/components/treemap.tsx +0 -1184
  625. package/src/components/trigger-aria.ts +0 -44
  626. package/src/components/use-anchor-dir.ts +0 -20
  627. package/src/components/use-mobile-reveal.ts +0 -62
  628. package/src/components/use-table-state.ts +0 -753
  629. package/src/components/user-avatar.tsx +0 -116
  630. package/src/components/wizard-stepper.tsx +0 -42
  631. package/src/components/write-lock-labels.ts +0 -10
  632. package/src/components/write-lock.tsx +0 -253
  633. package/src/currencies.ts +0 -70
  634. package/src/data-table.ts +0 -42
  635. package/src/demo/demo-banner.tsx +0 -153
  636. package/src/demo/demo-countdown.ts +0 -136
  637. package/src/demo/demo-ended.tsx +0 -90
  638. package/src/demo/demo-labels.ts +0 -78
  639. package/src/demo/demo-session.ts +0 -32
  640. package/src/demo/demo-start.tsx +0 -156
  641. package/src/eslint/index.ts +0 -161
  642. package/src/eslint/role-utilities.generated.ts +0 -146
  643. package/src/eslint/role-utilities.ts +0 -233
  644. package/src/feedback/feedback-attachment-download.tsx +0 -77
  645. package/src/feedback/feedback-attachment-labels.ts +0 -37
  646. package/src/feedback/feedback-attachment.tsx +0 -1239
  647. package/src/feedback/feedback-capture.ts +0 -287
  648. package/src/feedback/feedback-comment-thread.tsx +0 -353
  649. package/src/feedback/feedback-context-labels.ts +0 -10
  650. package/src/feedback/feedback-context.tsx +0 -213
  651. package/src/feedback/feedback-crash.ts +0 -547
  652. package/src/feedback/feedback-dialog-labels.ts +0 -29
  653. package/src/feedback/feedback-dialog.tsx +0 -440
  654. package/src/feedback/feedback-entry-file.tsx +0 -150
  655. package/src/feedback/feedback-inbox.tsx +0 -552
  656. package/src/feedback/feedback-labels.ts +0 -144
  657. package/src/feedback/feedback-menu-labels.ts +0 -12
  658. package/src/feedback/feedback-menu.tsx +0 -177
  659. package/src/feedback/feedback-mutation.ts +0 -20
  660. package/src/feedback/feedback-page-link.ts +0 -90
  661. package/src/feedback/feedback-public-labels.ts +0 -81
  662. package/src/feedback/feedback-public-list.tsx +0 -524
  663. package/src/feedback/feedback-public-switch.tsx +0 -102
  664. package/src/feedback/feedback-public-types.ts +0 -101
  665. package/src/feedback/feedback-record.ts +0 -423
  666. package/src/feedback/feedback-replies-context.ts +0 -9
  667. package/src/feedback/feedback-replies.tsx +0 -343
  668. package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
  669. package/src/feedback/feedback-row-detail-labels.ts +0 -30
  670. package/src/feedback/feedback-row-detail.tsx +0 -858
  671. package/src/feedback/feedback-status-undo.ts +0 -109
  672. package/src/feedback/feedback-submit-dialog.tsx +0 -118
  673. package/src/feedback/feedback-submit.tsx +0 -237
  674. package/src/feedback/feedback-swipe.tsx +0 -192
  675. package/src/feedback/feedback-table-labels.ts +0 -27
  676. package/src/feedback/feedback-table.tsx +0 -912
  677. package/src/feedback/feedback-thread-labels.ts +0 -22
  678. package/src/feedback/feedback-thread-parts-labels.ts +0 -41
  679. package/src/feedback/feedback-thread.tsx +0 -905
  680. package/src/feedback/feedback-vocabulary.ts +0 -263
  681. package/src/feedback/feedback-vote-button.tsx +0 -124
  682. package/src/feedback.ts +0 -116
  683. package/src/hooks/use-anchored-panel.ts +0 -396
  684. package/src/hooks/use-anchored-rect.ts +0 -77
  685. package/src/hooks/use-announce.ts +0 -85
  686. package/src/hooks/use-authed-src.ts +0 -167
  687. package/src/hooks/use-body-scroll-lock.ts +0 -119
  688. package/src/hooks/use-breakpoint.ts +0 -133
  689. package/src/hooks/use-close-transition.ts +0 -107
  690. package/src/hooks/use-copy-to-clipboard.ts +0 -122
  691. package/src/hooks/use-debounce.ts +0 -114
  692. package/src/hooks/use-dismiss.ts +0 -371
  693. package/src/hooks/use-document-title.ts +0 -33
  694. package/src/hooks/use-file-drop.ts +0 -121
  695. package/src/hooks/use-file-picker-labels.ts +0 -28
  696. package/src/hooks/use-file-picker.tsx +0 -359
  697. package/src/hooks/use-focus-trap.ts +0 -199
  698. package/src/hooks/use-hotkey.ts +0 -189
  699. package/src/hooks/use-large-text.ts +0 -41
  700. package/src/hooks/use-long-press.ts +0 -140
  701. package/src/hooks/use-media-query.ts +0 -39
  702. package/src/hooks/use-mounted.ts +0 -39
  703. package/src/hooks/use-noindex.ts +0 -37
  704. package/src/hooks/use-overlay-history.ts +0 -714
  705. package/src/hooks/use-row-swipe.ts +0 -207
  706. package/src/hooks/use-search-param-state.ts +0 -434
  707. package/src/hooks/use-windowed-rows.ts +0 -225
  708. package/src/i18n/defaults.ts +0 -267
  709. package/src/i18n/german.ts +0 -2057
  710. package/src/i18n/kit-labels.tsx +0 -1003
  711. package/src/i18n/languages.ts +0 -349
  712. package/src/i18n/locales/de-CH.ts +0 -24
  713. package/src/i18n/locales/en.ts +0 -267
  714. package/src/i18n/locales/es.ts +0 -1997
  715. package/src/i18n/locales/fr.ts +0 -2035
  716. package/src/i18n/locales/hu.ts +0 -2002
  717. package/src/i18n/locales/it.ts +0 -2012
  718. package/src/i18n/locales/zh.ts +0 -1910
  719. package/src/i18n/plurals.ts +0 -86
  720. package/src/i18n/review.ts +0 -475
  721. package/src/i18n/shared-labels.ts +0 -138
  722. package/src/i18n/swiss.ts +0 -29
  723. package/src/index.ts +0 -1179
  724. package/src/landing/access.ts +0 -93
  725. package/src/landing/landing-actions.tsx +0 -97
  726. package/src/landing/landing-labels.ts +0 -59
  727. package/src/landing/landing-sections.tsx +0 -341
  728. package/src/landing/page-seo.ts +0 -261
  729. package/src/landing/public-header.tsx +0 -121
  730. package/src/landing/public-page.tsx +0 -106
  731. package/src/landing/routing.tsx +0 -225
  732. package/src/lib/broadcast.ts +0 -52
  733. package/src/lib/calc.ts +0 -323
  734. package/src/lib/chip-edge-snap.ts +0 -212
  735. package/src/lib/clipboard-minus.ts +0 -107
  736. package/src/lib/clipping.ts +0 -34
  737. package/src/lib/cn.ts +0 -28
  738. package/src/lib/column-mapping.ts +0 -234
  739. package/src/lib/countries.ts +0 -91
  740. package/src/lib/data-attributes.ts +0 -14
  741. package/src/lib/date-format.ts +0 -227
  742. package/src/lib/dates.ts +0 -266
  743. package/src/lib/day-format.ts +0 -96
  744. package/src/lib/decimal-marks.ts +0 -108
  745. package/src/lib/describe-failure.ts +0 -18
  746. package/src/lib/device-settings.ts +0 -147
  747. package/src/lib/direction.ts +0 -74
  748. package/src/lib/document-navigation.ts +0 -17
  749. package/src/lib/document-title.ts +0 -41
  750. package/src/lib/download.ts +0 -172
  751. package/src/lib/float-clearance.ts +0 -70
  752. package/src/lib/floating-stack.ts +0 -70
  753. package/src/lib/focus-left.ts +0 -156
  754. package/src/lib/format.ts +0 -522
  755. package/src/lib/http-status.ts +0 -38
  756. package/src/lib/iban.ts +0 -251
  757. package/src/lib/ime.ts +0 -24
  758. package/src/lib/intl-cache.ts +0 -25
  759. package/src/lib/iso-day.ts +0 -13
  760. package/src/lib/lazy-with-fallback.ts +0 -82
  761. package/src/lib/logger.ts +0 -69
  762. package/src/lib/minus.ts +0 -50
  763. package/src/lib/path-pattern.ts +0 -55
  764. package/src/lib/person-name.ts +0 -155
  765. package/src/lib/phone.ts +0 -208
  766. package/src/lib/plain-text.ts +0 -22
  767. package/src/lib/presence.ts +0 -18
  768. package/src/lib/qr-encode.ts +0 -444
  769. package/src/lib/quiet-focus.ts +0 -32
  770. package/src/lib/reduced-motion.ts +0 -22
  771. package/src/lib/refs.ts +0 -22
  772. package/src/lib/round.ts +0 -43
  773. package/src/lib/safe-storage.ts +0 -119
  774. package/src/lib/server-wake.ts +0 -315
  775. package/src/lib/session-refresh.ts +0 -472
  776. package/src/lib/share-format.ts +0 -18
  777. package/src/lib/status-tone.ts +0 -43
  778. package/src/lib/strip-fade.ts +0 -287
  779. package/src/lib/table-text.ts +0 -554
  780. package/src/lib/text-case.ts +0 -19
  781. package/src/lib/text-match.ts +0 -169
  782. package/src/lib/thenable.ts +0 -19
  783. package/src/lib/translation-review.ts +0 -717
  784. package/src/notifications/device-zone-report.ts +0 -67
  785. package/src/notifications/feedback-notification-types-labels.ts +0 -33
  786. package/src/notifications/feedback-notification-types.ts +0 -71
  787. package/src/notifications/notification-bell.tsx +0 -119
  788. package/src/notifications/notification-inbox.tsx +0 -309
  789. package/src/notifications/notification-parts.tsx +0 -81
  790. package/src/notifications/notification-types-setting.tsx +0 -406
  791. package/src/notifications/notification-types.ts +0 -89
  792. package/src/notifications/notifications-labels.ts +0 -287
  793. package/src/notifications/push-device-setting.tsx +0 -230
  794. package/src/notifications/push-devices-setting.tsx +0 -374
  795. package/src/notifications/push-worker.ts +0 -168
  796. package/src/notifications/quiet-hours-setting.tsx +0 -238
  797. package/src/notifications/unsubscribe-panel.tsx +0 -200
  798. package/src/notifications/use-push-device.ts +0 -448
  799. package/src/offline/local-first.ts +0 -100
  800. package/src/offline/pwa-update-prompt-labels.ts +0 -9
  801. package/src/offline/pwa-update-prompt.tsx +0 -78
  802. package/src/offline/query-persistence.ts +0 -391
  803. package/src/offline/service-worker-updates.ts +0 -81
  804. package/src/offline/shared-computer-labels.ts +0 -8
  805. package/src/offline/shared-computer.tsx +0 -87
  806. package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
  807. package/src/offline/sign-out-pending-dialog.tsx +0 -135
  808. package/src/offline.ts +0 -37
  809. package/src/push-worker.ts +0 -25
  810. package/src/rhf/fields.tsx +0 -2187
  811. package/src/rhf/form-core.tsx +0 -324
  812. package/src/rhf/form.tsx +0 -12
  813. package/src/rhf/line-items.tsx +0 -135
  814. package/src/rhf/use-rhf-wizard-step.ts +0 -104
  815. package/src/rhf.ts +0 -21
  816. package/src/search/command-palette-labels.ts +0 -16
  817. package/src/search/command-palette.tsx +0 -624
  818. package/src/search/global-search-labels.ts +0 -13
  819. package/src/search/global-search.tsx +0 -660
  820. package/src/search/search-index.ts +0 -283
  821. package/src/search/use-command-key.ts +0 -23
  822. package/src/search.ts +0 -14
  823. package/src/settings/device-reset-setting-labels.ts +0 -20
  824. package/src/settings/device-reset-setting.tsx +0 -116
  825. package/src/settings/settings-card-classes.ts +0 -11
  826. package/src/settings/settings-catalogue.ts +0 -150
  827. package/src/settings/settings-context.ts +0 -33
  828. package/src/settings/settings-heading.tsx +0 -67
  829. package/src/settings/settings-labels.ts +0 -87
  830. package/src/settings/settings-layout.tsx +0 -471
  831. package/src/settings/settings-section.tsx +0 -108
  832. package/src/settings/use-account-appearance.ts +0 -148
  833. package/src/settings/use-account-language.ts +0 -146
  834. package/src/settings/use-settings-focus.ts +0 -128
  835. package/src/settings/use-settings-route.ts +0 -258
  836. package/src/shell/account-menu-language.tsx +0 -130
  837. package/src/shell/account-menu-text-size.tsx +0 -80
  838. package/src/shell/admin-menu.tsx +0 -183
  839. package/src/shell/app-shell-labels.ts +0 -11
  840. package/src/shell/app-shell.tsx +0 -1560
  841. package/src/shell/auth-layout.tsx +0 -186
  842. package/src/shell/company-switcher-labels.ts +0 -13
  843. package/src/shell/company-switcher.tsx +0 -136
  844. package/src/shell/dev-menu.tsx +0 -257
  845. package/src/shell/fill-height.tsx +0 -45
  846. package/src/shell/language-code.ts +0 -5
  847. package/src/shell/option-switcher-menu.tsx +0 -84
  848. package/src/shell/sync-status-indicator.tsx +0 -303
  849. package/src/shell/top-bar-actions.tsx +0 -87
  850. package/src/shell/top-bar-brand.tsx +0 -78
  851. package/src/shell/top-bar-parts-labels.ts +0 -148
  852. package/src/shell/top-bar.tsx +0 -40
  853. package/src/shell/topbar-action-menu.tsx +0 -567
  854. package/src/shell/topbar-controls.tsx +0 -269
  855. package/src/shell/tour-menu.tsx +0 -187
  856. package/src/shell.ts +0 -108
  857. package/src/sync/db.ts +0 -129
  858. package/src/sync/engine.ts +0 -1011
  859. package/src/sync/hooks.ts +0 -98
  860. package/src/sync/testing.ts +0 -73
  861. package/src/sync/wire.ts +0 -61
  862. package/src/sync.ts +0 -37
  863. package/src/table-text.ts +0 -8
  864. package/src/testing/css-variables.generated.ts +0 -112
  865. package/src/testing/css-variables.ts +0 -189
  866. package/src/testing/index.ts +0 -29
  867. package/src/testing/react.ts +0 -58
  868. package/src/testing/tour.ts +0 -41
  869. package/src/testing/viewport.ts +0 -357
  870. package/src/theme/chart-palette.ts +0 -232
  871. package/src/theme/color.ts +0 -272
  872. package/src/theme/contrast-tokens.ts +0 -268
  873. package/src/theme/contrast.ts +0 -250
  874. package/src/theme/palette-derive.ts +0 -825
  875. package/src/theme/palette-presets.ts +0 -544
  876. package/src/theme/palette-store.ts +0 -108
  877. package/src/theme/text-size.ts +0 -289
  878. package/src/theme/theme-store.ts +0 -157
  879. package/src/tour/tour-catalogue-labels.ts +0 -75
  880. package/src/tour/tour-catalogue.tsx +0 -335
  881. package/src/tour/tour-dock.ts +0 -134
  882. package/src/tour/tour-engine.ts +0 -37
  883. package/src/tour/tour-gates.ts +0 -218
  884. package/src/tour/tour-guide-button.tsx +0 -64
  885. package/src/tour/tour-guide-labels.ts +0 -15
  886. package/src/tour/tour-info.ts +0 -144
  887. package/src/tour/tour-labels.ts +0 -23
  888. package/src/tour/tour-overlay.tsx +0 -1170
  889. package/src/tour/tour.tsx +0 -750
  890. package/src/tour/use-tour-progress.ts +0 -671
  891. package/src/tour/use-tour-url-sync.ts +0 -266
  892. package/src/tour.ts +0 -21
  893. package/src/vite-env.d.ts +0 -23
  894. package/src/wizard/stepper-nav.tsx +0 -360
  895. package/src/wizard/types.ts +0 -275
  896. package/src/wizard/use-wizard.ts +0 -560
  897. package/src/wizard/validation.ts +0 -39
  898. package/src/wizard/wizard-context.tsx +0 -74
  899. package/src/wizard/wizard-labels.ts +0 -29
  900. package/src/wizard/wizard-step.tsx +0 -76
  901. package/src/wizard/wizard-summary.tsx +0 -84
  902. package/src/wizard.ts +0 -15
@@ -0,0 +1,260 @@
1
+ import type { ReactNode } from "react";
2
+ import { type DataTableColumn, type DataTableProps } from "../components/data-table.js";
3
+ import type { CommitScope } from "../components/write-lock.js";
4
+ import type { AuthedFetcher } from "../hooks/use-authed-src.js";
5
+ import type { LabelOverride } from "../i18n/kit-labels.js";
6
+ import type { PathPattern } from "../landing/routing.js";
7
+ import type { FeedbackRecord } from "./feedback-record.js";
8
+ import { type FeedbackDetailPatch, type FeedbackRowDetailProps, type FeedbackUpload } from "./feedback-row-detail.js";
9
+ import { type FeedbackStatusChange } from "./feedback-status-undo.js";
10
+ import { type FeedbackSwipeBinding } from "./feedback-swipe.js";
11
+ import { type FeedbackPageLabels, type FeedbackRenderDate } from "./feedback-table.js";
12
+ import type { FeedbackStatus } from "./feedback-vocabulary.js";
13
+ /**
14
+ * The feedback inbox, ASSEMBLED ONCE (0.55; kastlan reuse audit 2026-11-02, proposal 2;
15
+ * docs/feedback-harmonization.md §13).
16
+ *
17
+ * Since 0.27 every part of `/feedback` and `/my-feedback` has been the kit's — the columns,
18
+ * the phone card and its day headers, the detail, the Undo, the swipes, the awaiting toggle
19
+ * (feedback-table.tsx, feedback-row-detail.tsx, feedback-swipe.tsx). What was not the kit's
20
+ * was the WIRING between them, and each app wrote the same ~150 lines of it:
21
+ * kastlan `frontend/src/features/feedback/pages/feedback-page.tsx:40-205`, keksdose
22
+ * `frontend/src/features/feedback/feedback-page.tsx:51-303`, Kurvenschmiede
23
+ * `frontend/src/features/feedback/feedback-page.tsx:88-245`. The open row in `?row=` with
24
+ * its numeric parse and its `rowHref`, `useFeedbackStatusUndo` over the page's PATCH, the
25
+ * `DataTable` with a dozen props, `FeedbackRowDetail` with a dozen more, the phone's
26
+ * grouping, card and swipe plan, the awaiting filter and its toggle. So every rename the
27
+ * parts took (0.52's `mutateAsync`, 0.53's removals) was made three times, and three
28
+ * times reviewed.
29
+ *
30
+ * Here that wiring is the kit's: {@link useFeedbackInbox} holds it and returns what the
31
+ * table, the detail and the phone cards need; {@link FeedbackInbox} draws the page from
32
+ * it. What stays the app's is what differs between the three, each a slot: where the rows
33
+ * come from and the three mutations (its API client, TanStack Query in all three — the kit
34
+ * sends no request), who may triage, the votes, the public switch, the comments (the app's
35
+ * `FeedbackCommentThread` over its own queries), its own columns, its swipe binding, its
36
+ * date writer, the page's header and frame, and whatever else `DataTable` takes.
37
+ *
38
+ * Additive: every part it is built from stays exported and unchanged, for a page that
39
+ * wants its own layout — call the hook and spread `inbox.table` into a `DataTable`.
40
+ */
41
+ /**
42
+ * One of the page's mutations, as the inbox calls it: **TanStack Query's `useMutation`
43
+ * result, passed as it is** — `update={update}`. The inbox reads `mutateAsync` (whose
44
+ * promise settles for every call, refactor audit 2026-10-30 FLW-3) and `isPending`, and
45
+ * nothing else. Any object with those two fits, so a page on another data layer hands
46
+ * `{ mutateAsync: api.update, isPending }`.
47
+ *
48
+ * Taking the mutation rather than a callback per control is the point of the round: how
49
+ * the parts call it (0.52 moved them from `mutate` to `mutateAsync`) is then the kit's to
50
+ * change, once. Failure is the mutation's own: its `onError` toasts the server's sentence
51
+ * (§4.4), and the inbox catches the rejection.
52
+ */
53
+ export interface FeedbackInboxMutation<V> {
54
+ mutateAsync: (variables: V) => Promise<unknown>;
55
+ /** In flight: the editors' and the composer's buttons wait for it. */
56
+ isPending?: boolean;
57
+ }
58
+ /** What the reply mutation is sent: `POST /feedback/{id}/replies` (§9.7, §12) — the
59
+ * body, the status picked (absent: "No change") and the uploaded file's URL (absent:
60
+ * none). Keys that carry nothing are left out, so a `mutationFn` may spread them onto
61
+ * the wire. kastlan's `useFeedbackReply` takes exactly this. */
62
+ export interface FeedbackReplyPost {
63
+ id: number;
64
+ body: string;
65
+ status?: FeedbackStatus;
66
+ attachmentUrl?: string;
67
+ }
68
+ /** What the rework mutation is sent: `POST /feedback/{id}/rework` (§10.3) — the author's
69
+ * trimmed note and the uploaded file's URL (absent: none). kastlan's `useFeedbackRework`
70
+ * takes exactly this. */
71
+ export interface FeedbackReworkPost {
72
+ id: number;
73
+ note: string;
74
+ attachmentUrl?: string;
75
+ }
76
+ export interface UseFeedbackInboxOptions<T extends FeedbackRecord> {
77
+ /** The list as the app's query answered it (`GET /feedback`, `GET /feedback/my`) —
78
+ * `list.data ?? []`. Shown newest first and, behind the awaiting toggle, narrowed. */
79
+ rows: readonly T[];
80
+ /** `/my-feedback`: the viewer's own reports — no triage there, for an admin too (§4.3). */
81
+ mine?: boolean;
82
+ /** The viewer may triage: the admin. Only on the inbox — `mine` wins — so `isAdmin`
83
+ * is enough. The status cell, the pills, the reply composer, the swipes, the submitter
84
+ * on the card and the awaiting toggle. */
85
+ canEdit: boolean;
86
+ /** The signed-in user's id: who the AUTHOR is (the description editor, Rework, the
87
+ * public switch's window). */
88
+ viewerId?: number | null;
89
+ /**
90
+ * `PATCH /feedback/{id}` (§3.4): every edit of the report itself — a status change from
91
+ * the cell, the pills or a swipe (with the Undo, `useFeedbackStatusUndo`), the
92
+ * description, the legacy rework append and, with {@link publicSwitch}, the flip. ONE
93
+ * mutation for all of them, the page's, so its observer outlives a row a status filter
94
+ * removes (§4.5).
95
+ */
96
+ update: FeedbackInboxMutation<FeedbackDetailPatch>;
97
+ /** `POST /feedback/{id}/replies` — the admin's answer (§9.7) with its one file (§12).
98
+ * Without it no composer is drawn. */
99
+ reply?: FeedbackInboxMutation<FeedbackReplyPost>;
100
+ /** `POST /feedback/{id}/rework` — the author's rework entry (§10.3). Without it a rework
101
+ * goes through {@link update} as the legacy body append (§3.4). */
102
+ rework?: FeedbackInboxMutation<FeedbackReworkPost>;
103
+ /**
104
+ * The **Visible to others** switch in the detail (§9.3), its flip sent through
105
+ * {@link update} as `{ id, public }` — as keksdose and Kurvenschmiede send it. Off by
106
+ * default: an app without public parts (kastlan) has no switch.
107
+ */
108
+ publicSwitch?: boolean;
109
+ /** The **Votes** column and the card's count (§9.6). Off by default (kastlan); keksdose
110
+ * always, Kurvenschmiede for a reader of the public parts. */
111
+ votes?: boolean;
112
+ /**
113
+ * The report's comments, in a section of their own under the replies (§9.8): the app's
114
+ * `FeedbackCommentThread` over its own queries — a component of its own, since its
115
+ * queries are hooks. Return `null` for a row without a thread (a CRASH, a reader who
116
+ * does not see the public parts; `false` is read as `null`). Called only for the open
117
+ * row.
118
+ *
119
+ * ```tsx
120
+ * comments={(row) => <RowComments id={row.id} isAdmin={isAdmin} canComment={!canEdit} />}
121
+ * ```
122
+ */
123
+ comments?: (row: T) => ReactNode;
124
+ /** The detail as drawn, to wrap or extend — kastlan's tour anchor:
125
+ * `(row, detail) => <div data-tour="feedback-row-detail">{detail}</div>`. */
126
+ renderDetail?: (row: T, detail: ReactNode) => ReactNode;
127
+ /**
128
+ * The app's own columns over the kit's (§4.3's nine, and Votes): add, drop, reorder —
129
+ * the keys are stable (`columns.filter((c) => c.key !== "email")`). A column brings its
130
+ * filter with it. Keep it stable (module scope or `useCallback`): it is a memo's
131
+ * dependency.
132
+ */
133
+ columns?: (columns: readonly DataTableColumn<T>[]) => readonly DataTableColumn<T>[];
134
+ /** Which swipe does what on the phone (§4.5) — keksdose's Settings → Interaction binding,
135
+ * `{ end: prefs.right, start: prefs.left }`. Default `DEFAULT_FEEDBACK_SWIPE`. */
136
+ swipe?: FeedbackSwipeBinding;
137
+ /** The status writes the TABLE offers — the status cell and the desktop's actions
138
+ * column — commit: under a locked `WriteLockProvider` they stay and say why
139
+ * (`FeedbackStatusTransitions`' `commit`). Off by default. The detail's own saves:
140
+ * `detail={{ commit }}`. */
141
+ commit?: CommitScope;
142
+ /** `POST /feedback/attachments` (§3.3): the rework's file and the reply's. */
143
+ onUpload?: FeedbackUpload;
144
+ /** The app's authenticated GET for the pictures and the downloads (§3.5). */
145
+ fetcher?: AuthedFetcher | null;
146
+ /** "Capture screenshot" beside the rework's and the reply's file field. Default: the
147
+ * kit's `captureAppScreenshot()`; `null` for no button. */
148
+ onCaptureScreenshot?: (() => Promise<File | null>) | null;
149
+ /**
150
+ * The app's date writer (keksdose's `useDateCell()`, the date-format setting): the date
151
+ * and resolved columns, the card, the phone's day headers AND the detail's "Resolved:",
152
+ * so all five say the same. Left out, the kit's date with the weekday in the table and
153
+ * on the phone, and in the detail its sentence date — as the parts draw them alone.
154
+ */
155
+ renderDate?: FeedbackRenderDate;
156
+ /** The app's one-shot routes, on top of the kit's (0.52, FLW-7) — for the URL column and
157
+ * the detail's URL section alike. Keep it stable (module scope). */
158
+ pageLinkExclude?: readonly PathPattern[];
159
+ /** The list is still loading (`list.isPending`): the table says "Loading…" where its
160
+ * rows will be, not "None". */
161
+ loading?: boolean;
162
+ /** Over the detail's props the inbox sets — `commit`, `showSubject`,
163
+ * `reworkAttachment`, `replyAttachments` (on here), `labels`, `className`. Merged last,
164
+ * so it wins. */
165
+ detail?: Partial<Omit<FeedbackRowDetailProps, "row">>;
166
+ /** Over the `feedbackPage` namespace: the columns, the card, the empty state, the toggle
167
+ * and the title. Keep it stable: it is a memo's dependency. */
168
+ labels?: LabelOverride<FeedbackPageLabels>;
169
+ }
170
+ /** What {@link useFeedbackInbox} returns: the state, and the props of the parts. */
171
+ export interface FeedbackInboxState<T extends FeedbackRecord> {
172
+ /** `canEdit && !mine`: the admin on the inbox. */
173
+ editable: boolean;
174
+ /** The page's title, `feedbackPage.title` — or `.myTitle` on `/my-feedback`. */
175
+ title: string;
176
+ /** The open row's id, from `?row=`; `null` when none is open or the param named no
177
+ * id (`?row=abc`, `?row=1.5`, `?row=0`). */
178
+ openId: number | null;
179
+ /** Open a row by its id, or close it with `null`: rewrites `?row=`, replacing the
180
+ * history entry rather than stacking one per report looked at. */
181
+ setOpenId: (id: number | null) => void;
182
+ /** A row's own address: this view — the table's page, sort and filters — with the row
183
+ * open. The row's link (a new tab, a copied address); a plain click opens it in place. */
184
+ rowHref: (row: T) => string;
185
+ /** The undoable status change (§4.5): the status cell's, the pills', the swipes'. */
186
+ changeStatus: FeedbackStatusChange;
187
+ /** The phone's "Only what is waiting for you" — page state, not the URL (§4.3). */
188
+ awaiting: boolean;
189
+ setAwaiting: (next: boolean) => void;
190
+ /** The one date writer the columns, the card and the day headers use. */
191
+ renderDate: FeedbackRenderDate;
192
+ /** `FeedbackRowDetail`'s props for a row, slots included. */
193
+ detailProps: (row: T) => FeedbackRowDetailProps;
194
+ /** `DataTable`'s props, ready to spread: the rows (newest first, narrowed by
195
+ * `awaiting`), the columns, the open row, the detail, the phone's card, day headers and
196
+ * swipes, the desktop's actions column, the empty state, `urlSync`,
197
+ * `storageKey="feedback"`, `fillHeight`. */
198
+ table: DataTableProps<T>;
199
+ }
200
+ /**
201
+ * The inbox's wiring, once (§13): from the app's rows and mutations to what the table,
202
+ * the detail and the phone cards take.
203
+ *
204
+ * ```tsx
205
+ * const list = useQuery({ queryKey: keys.feedback.all, queryFn: api.listFeedback });
206
+ * const update = useMutation({ mutationFn: ({ id, ...patch }: FeedbackDetailPatch) => api.update(id, patch), … });
207
+ * const inbox = useFeedbackInbox({ rows: list.data ?? [], canEdit: isAdmin, viewerId: user?.id, update });
208
+ * <DataTable {...inbox.table} edgeFade />
209
+ * ```
210
+ *
211
+ * {@link FeedbackInbox} is this hook drawn — use the hook alone for a layout of your own.
212
+ * Needs a react-router Router (`?row=`, `urlSync`).
213
+ */
214
+ export declare function useFeedbackInbox<T extends FeedbackRecord>({ rows, mine, canEdit, viewerId, update, reply, rework, publicSwitch, votes, comments, renderDetail, columns: ownColumns, swipe, commit, onUpload, fetcher, onCaptureScreenshot, renderDate: renderDateProp, pageLinkExclude, loading, detail, labels, }: UseFeedbackInboxOptions<T>): FeedbackInboxState<T>;
215
+ export interface FeedbackInboxProps<T extends FeedbackRecord> extends UseFeedbackInboxOptions<T> {
216
+ /**
217
+ * Above the table. Default: `<PageHeader title={title} className="mb-4 md:shrink-0" />`.
218
+ * A function gets the page's title (`feedbackPage.title` / `.myTitle`) — the app's own
219
+ * header: `(title) => <PageHeader size="compact" title={title} data-tour="feedback-header" />`.
220
+ * `null` for none.
221
+ */
222
+ header?: ReactNode | ((title: string) => ReactNode);
223
+ /** Over the inbox's `DataTable` props — `edgeFade`, `locale`, `mobileExpandAsDialog`,
224
+ * `className`, another `storageKey`. Merged last, so it wins. */
225
+ table?: Partial<DataTableProps<T>>;
226
+ /** Further `FloatingAction`s on the phone: after the awaiting toggle on the inbox, in a
227
+ * group of their own on `/my-feedback`. */
228
+ phoneActions?: ReactNode;
229
+ /** On the page's frame — the fill-height column (`FILL_HEIGHT_CLASS`); the app's page
230
+ * padding goes here. */
231
+ className?: string;
232
+ }
233
+ /**
234
+ * The feedback inbox (§13): `/feedback` and `/my-feedback` drawn whole from
235
+ * {@link useFeedbackInbox} — the header, the table with its detail, phone cards and swipes,
236
+ * and the phone's awaiting toggle, in the fill-height frame (page layout §1.3) — so a page
237
+ * is its queries and this:
238
+ *
239
+ * ```tsx
240
+ * export function FeedbackPage({ mine = false }: { mine?: boolean }) {
241
+ * const { user, isAdmin } = useAuth();
242
+ * const list = useQuery({ queryKey: mine ? keys.mine : keys.all, queryFn: mine ? api.mine : api.all });
243
+ * const update = useFeedbackUpdate();
244
+ * const reply = useFeedbackReply();
245
+ * const rework = useFeedbackRework();
246
+ * if (!mine && !isAdmin) return <Navigate to="/my-feedback" replace />;
247
+ * return (
248
+ * <FeedbackInbox
249
+ * rows={list.data ?? []} loading={list.isPending} mine={mine} canEdit={isAdmin} viewerId={user?.id}
250
+ * update={update} reply={reply} rework={rework}
251
+ * onUpload={api.upload} fetcher={api.file}
252
+ * />
253
+ * );
254
+ * }
255
+ * ```
256
+ *
257
+ * Every slot is {@link UseFeedbackInboxOptions}' or one of the four below. The redirect of
258
+ * a non-admin, the routes and the queries stay the app's.
259
+ */
260
+ export declare function FeedbackInbox<T extends FeedbackRecord>({ header, table, phoneActions, className, ...options }: FeedbackInboxProps<T>): import("react").JSX.Element;
@@ -0,0 +1,207 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useMemo, useState } from "react";
4
+ import { useHref, useLocation } from "react-router";
5
+ import { cn } from "../lib/cn.js";
6
+ import { DataTable } from "../components/data-table.js";
7
+ import { FloatingActionGroup } from "../components/floating-panel.js";
8
+ import { LoadingState } from "../components/loading-state.js";
9
+ import { PageHeader } from "../components/page-header.js";
10
+ import { useSearchParamState } from "../hooks/use-search-param-state.js";
11
+ import { FILL_HEIGHT_CLASS } from "../shell/fill-height.js";
12
+ import { captureAppScreenshot } from "./feedback-capture.js";
13
+ import { useFeedbackStatusLabels } from "./feedback-labels.js";
14
+ import { runMutation } from "./feedback-mutation.js";
15
+ import {
16
+ FeedbackRowDetail
17
+ } from "./feedback-row-detail.js";
18
+ import { useFeedbackStatusUndo } from "./feedback-status-undo.js";
19
+ import {
20
+ DEFAULT_FEEDBACK_SWIPE,
21
+ feedbackSwipeOmitShown,
22
+ feedbackSwipePlan
23
+ } from "./feedback-swipe.js";
24
+ import {
25
+ FeedbackAwaitingToggle,
26
+ FeedbackEmptyState,
27
+ FeedbackMobileCard,
28
+ feedbackMobileGroupBy,
29
+ isFeedbackAwaiting,
30
+ useFeedbackColumns,
31
+ useFeedbackPageLabels,
32
+ useFeedbackRenderDate
33
+ } from "./feedback-table.js";
34
+ function parseRowId(raw) {
35
+ if (!/^[1-9]\d*$/.test(raw)) return void 0;
36
+ const id = Number(raw);
37
+ return Number.isSafeInteger(id) ? id : void 0;
38
+ }
39
+ const ROW_PARAM = { parse: parseRowId, history: "replace" };
40
+ const newestFirst = (a, b) => a.created_at < b.created_at ? 1 : a.created_at > b.created_at ? -1 : 0;
41
+ const rowId = (row) => row.id;
42
+ const rowTitle = (row) => row.title;
43
+ const captureScreenshot = () => captureAppScreenshot();
44
+ const ignore = () => {
45
+ };
46
+ const threadOf = (node) => node === false || node === "" ? void 0 : node;
47
+ function useFeedbackInbox({
48
+ rows,
49
+ mine = false,
50
+ canEdit,
51
+ viewerId,
52
+ update,
53
+ reply,
54
+ rework,
55
+ publicSwitch = false,
56
+ votes = false,
57
+ comments,
58
+ renderDetail,
59
+ columns: ownColumns,
60
+ swipe = DEFAULT_FEEDBACK_SWIPE,
61
+ commit,
62
+ onUpload,
63
+ fetcher,
64
+ onCaptureScreenshot = captureScreenshot,
65
+ renderDate: renderDateProp,
66
+ pageLinkExclude,
67
+ loading = false,
68
+ detail,
69
+ labels
70
+ }) {
71
+ const editable = canEdit && !mine;
72
+ const pageLabels = useFeedbackPageLabels(labels);
73
+ const statusLabels = useFeedbackStatusLabels();
74
+ const renderDate = useFeedbackRenderDate(renderDateProp);
75
+ const updateAsync = update.mutateAsync;
76
+ const changeStatus = useFeedbackStatusUndo(updateAsync);
77
+ const [openId, setOpenId] = useSearchParamState("row", null, ROW_PARAM);
78
+ const { pathname, search } = useLocation();
79
+ const here = useHref({ pathname });
80
+ const rowHref = useCallback(
81
+ (row) => {
82
+ const params = new URLSearchParams(search);
83
+ params.set("row", String(row.id));
84
+ return `${here}?${params.toString()}`;
85
+ },
86
+ [here, search]
87
+ );
88
+ const [awaiting, setAwaiting] = useState(false);
89
+ const shown = useMemo(
90
+ () => (editable && awaiting ? rows.filter((row) => isFeedbackAwaiting(row.status)) : [...rows]).sort(newestFirst),
91
+ [rows, editable, awaiting]
92
+ );
93
+ const kitColumns = useFeedbackColumns({
94
+ mine,
95
+ canEdit,
96
+ onStatus: changeStatus,
97
+ renderDate,
98
+ commit,
99
+ votes,
100
+ pageLinkExclude,
101
+ labels
102
+ });
103
+ const columns = useMemo(() => ownColumns ? ownColumns(kitColumns) : kitColumns, [ownColumns, kitColumns]);
104
+ const mobileGroupBy = useMemo(() => feedbackMobileGroupBy(renderDate), [renderDate]);
105
+ const pending = Boolean(update.isPending || rework?.isPending);
106
+ const capture = onCaptureScreenshot ?? void 0;
107
+ const detailProps = (row) => ({
108
+ row,
109
+ canEdit: editable,
110
+ viewerId,
111
+ onUpdate: updateAsync,
112
+ pending,
113
+ // The page's change, not one the detail would build: the same Undo as the cell's.
114
+ statusChange: changeStatus,
115
+ onUpload,
116
+ fetcher,
117
+ onCaptureScreenshot: capture,
118
+ // Only the app's own: left out, the detail's "Resolved:" is the kit's sentence date,
119
+ // no weekday — as kastlan's has always been.
120
+ renderDate: renderDateProp,
121
+ pageLinkExclude,
122
+ onReply: reply ? (body, status, attachmentUrl) => reply.mutateAsync({
123
+ id: row.id,
124
+ body,
125
+ ...status ? { status } : {},
126
+ ...attachmentUrl ? { attachmentUrl } : {}
127
+ }) : void 0,
128
+ // The reply's one file (§12): all three apps are on server-kit 0.18, and the reply
129
+ // mutation's `attachmentUrl` is in its type from the start (the B1 risk the detail's
130
+ // default guards against — an `onReply` that drops the file — cannot arise here).
131
+ replyAttachments: true,
132
+ replying: reply?.isPending ?? false,
133
+ onRework: rework ? (note, attachmentUrl) => rework.mutateAsync({ id: row.id, note, ...attachmentUrl ? { attachmentUrl } : {} }) : void 0,
134
+ comments: threadOf(comments?.(row)),
135
+ onPublicChange: publicSwitch ? (next) => runMutation(updateAsync, { id: row.id, public: next }, ignore) : void 0,
136
+ ...detail
137
+ });
138
+ const table = {
139
+ rows: shown,
140
+ columns,
141
+ rowKey: rowId,
142
+ storageKey: "feedback",
143
+ urlSync: true,
144
+ fillHeight: true,
145
+ rowHref,
146
+ // The link covers the row's first cell; a click anywhere on the row opens it — or,
147
+ // on the open one, closes it.
148
+ onRowClick: (row) => setOpenId((id) => id === row.id ? null : row.id),
149
+ isExpanded: (row) => row.id === openId,
150
+ expandedRow: (row) => {
151
+ const node = /* @__PURE__ */ jsx(FeedbackRowDetail, { ...detailProps(row) });
152
+ return renderDetail ? renderDetail(row, node) : node;
153
+ },
154
+ // §7.13: one word, also when a filter or the toggle leaves nothing; and while the
155
+ // first answer is out, what is happening instead.
156
+ empty: loading ? /* @__PURE__ */ jsx(LoadingState, { size: "sm", inline: true }) : /* @__PURE__ */ jsx(FeedbackEmptyState, { labels }),
157
+ mobileGroupBy,
158
+ mobileCard: (row) => /* @__PURE__ */ jsx(FeedbackMobileCard, { row, showSubmitter: editable, renderDate, votes, labels }),
159
+ // The admin inbox only — /my-feedback is read-only by design (keksdose #331) — and
160
+ // every swipe through the same Undo as a tap (§4.5, §7.10).
161
+ mobileSwipeActions: editable ? (row) => feedbackSwipePlan(swipe, row, { change: changeStatus, labels: statusLabels }) : void 0,
162
+ // The swipes as the desktop's last column (0.46, keksdose dev#598), less what the
163
+ // status cell already offers.
164
+ desktopSwipeActions: { omit: feedbackSwipeOmitShown, name: rowTitle, ...commit === void 0 ? {} : { commit } }
165
+ };
166
+ return {
167
+ editable,
168
+ title: mine ? pageLabels.myTitle : pageLabels.title,
169
+ openId,
170
+ setOpenId,
171
+ rowHref,
172
+ changeStatus,
173
+ awaiting,
174
+ setAwaiting,
175
+ renderDate,
176
+ detailProps,
177
+ table
178
+ };
179
+ }
180
+ function FeedbackInbox({
181
+ header,
182
+ table,
183
+ phoneActions,
184
+ className,
185
+ ...options
186
+ }) {
187
+ const inbox = useFeedbackInbox(options);
188
+ const pageLabels = useFeedbackPageLabels(options.labels);
189
+ const head = header === void 0 ? /* @__PURE__ */ jsx(PageHeader, { title: inbox.title, className: "mb-4 md:shrink-0" }) : typeof header === "function" ? header(inbox.title) : header;
190
+ return (
191
+ // A plain element on the way to the table carries the fill (page layout §1.3).
192
+ /* @__PURE__ */ jsxs("div", { className: cn(FILL_HEIGHT_CLASS, className), "aria-busy": options.loading || void 0, "data-feedback-inbox": "", children: [
193
+ head,
194
+ /* @__PURE__ */ jsx(DataTable, { ...inbox.table, ...table }),
195
+ inbox.editable ? (
196
+ // The phone's floating action (keksdose feedback #58): only on the inbox — on
197
+ // /my-feedback the author is not waiting on their own verdict.
198
+ /* @__PURE__ */ jsx(FeedbackAwaitingToggle, { pressed: inbox.awaiting, onPressedChange: inbox.setAwaiting, labels: options.labels, children: phoneActions })
199
+ ) : phoneActions && /* @__PURE__ */ jsx(FloatingActionGroup, { "aria-label": pageLabels.phoneActions, className: "md:hidden", children: phoneActions })
200
+ ] })
201
+ );
202
+ }
203
+ export {
204
+ FeedbackInbox,
205
+ useFeedbackInbox
206
+ };
207
+ //# sourceMappingURL=feedback-inbox-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/feedback/feedback-inbox-page.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useHref, useLocation } from \"react-router\";\nimport { cn } from \"../lib/cn\";\nimport { DataTable, type DataTableColumn, type DataTableProps } from \"../components/data-table\";\nimport { FloatingActionGroup } from \"../components/floating-panel\";\nimport { LoadingState } from \"../components/loading-state\";\nimport { PageHeader } from \"../components/page-header\";\nimport type { CommitScope } from \"../components/write-lock\";\nimport type { AuthedFetcher } from \"../hooks/use-authed-src\";\nimport { useSearchParamState } from \"../hooks/use-search-param-state\";\nimport type { LabelOverride } from \"../i18n/kit-labels\";\nimport type { PathPattern } from \"../landing/routing\";\nimport { FILL_HEIGHT_CLASS } from \"../shell/fill-height\";\nimport { captureAppScreenshot } from \"./feedback-capture\";\nimport { useFeedbackStatusLabels } from \"./feedback-labels\";\nimport { runMutation } from \"./feedback-mutation\";\nimport type { FeedbackRecord } from \"./feedback-record\";\nimport {\n FeedbackRowDetail,\n type FeedbackDetailPatch,\n type FeedbackRowDetailProps,\n type FeedbackUpload,\n} from \"./feedback-row-detail\";\nimport { useFeedbackStatusUndo, type FeedbackStatusChange } from \"./feedback-status-undo\";\nimport {\n DEFAULT_FEEDBACK_SWIPE,\n feedbackSwipeOmitShown,\n feedbackSwipePlan,\n type FeedbackSwipeBinding,\n} from \"./feedback-swipe\";\nimport {\n FeedbackAwaitingToggle,\n FeedbackEmptyState,\n FeedbackMobileCard,\n feedbackMobileGroupBy,\n isFeedbackAwaiting,\n useFeedbackColumns,\n useFeedbackPageLabels,\n useFeedbackRenderDate,\n type FeedbackPageLabels,\n type FeedbackRenderDate,\n} from \"./feedback-table\";\nimport type { FeedbackStatus } from \"./feedback-vocabulary\";\n\n/**\n * The feedback inbox, ASSEMBLED ONCE (0.55; kastlan reuse audit 2026-11-02, proposal 2;\n * docs/feedback-harmonization.md §13).\n *\n * Since 0.27 every part of `/feedback` and `/my-feedback` has been the kit's — the columns,\n * the phone card and its day headers, the detail, the Undo, the swipes, the awaiting toggle\n * (feedback-table.tsx, feedback-row-detail.tsx, feedback-swipe.tsx). What was not the kit's\n * was the WIRING between them, and each app wrote the same ~150 lines of it:\n * kastlan `frontend/src/features/feedback/pages/feedback-page.tsx:40-205`, keksdose\n * `frontend/src/features/feedback/feedback-page.tsx:51-303`, Kurvenschmiede\n * `frontend/src/features/feedback/feedback-page.tsx:88-245`. The open row in `?row=` with\n * its numeric parse and its `rowHref`, `useFeedbackStatusUndo` over the page's PATCH, the\n * `DataTable` with a dozen props, `FeedbackRowDetail` with a dozen more, the phone's\n * grouping, card and swipe plan, the awaiting filter and its toggle. So every rename the\n * parts took (0.52's `mutateAsync`, 0.53's removals) was made three times, and three\n * times reviewed.\n *\n * Here that wiring is the kit's: {@link useFeedbackInbox} holds it and returns what the\n * table, the detail and the phone cards need; {@link FeedbackInbox} draws the page from\n * it. What stays the app's is what differs between the three, each a slot: where the rows\n * come from and the three mutations (its API client, TanStack Query in all three — the kit\n * sends no request), who may triage, the votes, the public switch, the comments (the app's\n * `FeedbackCommentThread` over its own queries), its own columns, its swipe binding, its\n * date writer, the page's header and frame, and whatever else `DataTable` takes.\n *\n * Additive: every part it is built from stays exported and unchanged, for a page that\n * wants its own layout — call the hook and spread `inbox.table` into a `DataTable`.\n */\n\n/* ── The mutations ──────────────────────────────────────────────────────────── */\n\n/**\n * One of the page's mutations, as the inbox calls it: **TanStack Query's `useMutation`\n * result, passed as it is** — `update={update}`. The inbox reads `mutateAsync` (whose\n * promise settles for every call, refactor audit 2026-10-30 FLW-3) and `isPending`, and\n * nothing else. Any object with those two fits, so a page on another data layer hands\n * `{ mutateAsync: api.update, isPending }`.\n *\n * Taking the mutation rather than a callback per control is the point of the round: how\n * the parts call it (0.52 moved them from `mutate` to `mutateAsync`) is then the kit's to\n * change, once. Failure is the mutation's own: its `onError` toasts the server's sentence\n * (§4.4), and the inbox catches the rejection.\n */\nexport interface FeedbackInboxMutation<V> {\n mutateAsync: (variables: V) => Promise<unknown>;\n /** In flight: the editors' and the composer's buttons wait for it. */\n isPending?: boolean;\n}\n\n/** What the reply mutation is sent: `POST /feedback/{id}/replies` (§9.7, §12) — the\n * body, the status picked (absent: \"No change\") and the uploaded file's URL (absent:\n * none). Keys that carry nothing are left out, so a `mutationFn` may spread them onto\n * the wire. kastlan's `useFeedbackReply` takes exactly this. */\nexport interface FeedbackReplyPost {\n id: number;\n body: string;\n status?: FeedbackStatus;\n attachmentUrl?: string;\n}\n\n/** What the rework mutation is sent: `POST /feedback/{id}/rework` (§10.3) — the author's\n * trimmed note and the uploaded file's URL (absent: none). kastlan's `useFeedbackRework`\n * takes exactly this. */\nexport interface FeedbackReworkPost {\n id: number;\n note: string;\n attachmentUrl?: string;\n}\n\n/* ── The hook ───────────────────────────────────────────────────────────────── */\n\nexport interface UseFeedbackInboxOptions<T extends FeedbackRecord> {\n /** The list as the app's query answered it (`GET /feedback`, `GET /feedback/my`) —\n * `list.data ?? []`. Shown newest first and, behind the awaiting toggle, narrowed. */\n rows: readonly T[];\n /** `/my-feedback`: the viewer's own reports — no triage there, for an admin too (§4.3). */\n mine?: boolean;\n /** The viewer may triage: the admin. Only on the inbox — `mine` wins — so `isAdmin`\n * is enough. The status cell, the pills, the reply composer, the swipes, the submitter\n * on the card and the awaiting toggle. */\n canEdit: boolean;\n /** The signed-in user's id: who the AUTHOR is (the description editor, Rework, the\n * public switch's window). */\n viewerId?: number | null;\n /**\n * `PATCH /feedback/{id}` (§3.4): every edit of the report itself — a status change from\n * the cell, the pills or a swipe (with the Undo, `useFeedbackStatusUndo`), the\n * description, the legacy rework append and, with {@link publicSwitch}, the flip. ONE\n * mutation for all of them, the page's, so its observer outlives a row a status filter\n * removes (§4.5).\n */\n update: FeedbackInboxMutation<FeedbackDetailPatch>;\n /** `POST /feedback/{id}/replies` — the admin's answer (§9.7) with its one file (§12).\n * Without it no composer is drawn. */\n reply?: FeedbackInboxMutation<FeedbackReplyPost>;\n /** `POST /feedback/{id}/rework` — the author's rework entry (§10.3). Without it a rework\n * goes through {@link update} as the legacy body append (§3.4). */\n rework?: FeedbackInboxMutation<FeedbackReworkPost>;\n /**\n * The **Visible to others** switch in the detail (§9.3), its flip sent through\n * {@link update} as `{ id, public }` — as keksdose and Kurvenschmiede send it. Off by\n * default: an app without public parts (kastlan) has no switch.\n */\n publicSwitch?: boolean;\n /** The **Votes** column and the card's count (§9.6). Off by default (kastlan); keksdose\n * always, Kurvenschmiede for a reader of the public parts. */\n votes?: boolean;\n /**\n * The report's comments, in a section of their own under the replies (§9.8): the app's\n * `FeedbackCommentThread` over its own queries — a component of its own, since its\n * queries are hooks. Return `null` for a row without a thread (a CRASH, a reader who\n * does not see the public parts; `false` is read as `null`). Called only for the open\n * row.\n *\n * ```tsx\n * comments={(row) => <RowComments id={row.id} isAdmin={isAdmin} canComment={!canEdit} />}\n * ```\n */\n comments?: (row: T) => ReactNode;\n /** The detail as drawn, to wrap or extend — kastlan's tour anchor:\n * `(row, detail) => <div data-tour=\"feedback-row-detail\">{detail}</div>`. */\n renderDetail?: (row: T, detail: ReactNode) => ReactNode;\n /**\n * The app's own columns over the kit's (§4.3's nine, and Votes): add, drop, reorder —\n * the keys are stable (`columns.filter((c) => c.key !== \"email\")`). A column brings its\n * filter with it. Keep it stable (module scope or `useCallback`): it is a memo's\n * dependency.\n */\n columns?: (columns: readonly DataTableColumn<T>[]) => readonly DataTableColumn<T>[];\n /** Which swipe does what on the phone (§4.5) — keksdose's Settings → Interaction binding,\n * `{ end: prefs.right, start: prefs.left }`. Default `DEFAULT_FEEDBACK_SWIPE`. */\n swipe?: FeedbackSwipeBinding;\n /** The status writes the TABLE offers — the status cell and the desktop's actions\n * column — commit: under a locked `WriteLockProvider` they stay and say why\n * (`FeedbackStatusTransitions`' `commit`). Off by default. The detail's own saves:\n * `detail={{ commit }}`. */\n commit?: CommitScope;\n /** `POST /feedback/attachments` (§3.3): the rework's file and the reply's. */\n onUpload?: FeedbackUpload;\n /** The app's authenticated GET for the pictures and the downloads (§3.5). */\n fetcher?: AuthedFetcher | null;\n /** \"Capture screenshot\" beside the rework's and the reply's file field. Default: the\n * kit's `captureAppScreenshot()`; `null` for no button. */\n onCaptureScreenshot?: (() => Promise<File | null>) | null;\n /**\n * The app's date writer (keksdose's `useDateCell()`, the date-format setting): the date\n * and resolved columns, the card, the phone's day headers AND the detail's \"Resolved:\",\n * so all five say the same. Left out, the kit's date with the weekday in the table and\n * on the phone, and in the detail its sentence date — as the parts draw them alone.\n */\n renderDate?: FeedbackRenderDate;\n /** The app's one-shot routes, on top of the kit's (0.52, FLW-7) — for the URL column and\n * the detail's URL section alike. Keep it stable (module scope). */\n pageLinkExclude?: readonly PathPattern[];\n /** The list is still loading (`list.isPending`): the table says \"Loading…\" where its\n * rows will be, not \"None\". */\n loading?: boolean;\n /** Over the detail's props the inbox sets — `commit`, `showSubject`,\n * `reworkAttachment`, `replyAttachments` (on here), `labels`, `className`. Merged last,\n * so it wins. */\n detail?: Partial<Omit<FeedbackRowDetailProps, \"row\">>;\n /** Over the `feedbackPage` namespace: the columns, the card, the empty state, the toggle\n * and the title. Keep it stable: it is a memo's dependency. */\n labels?: LabelOverride<FeedbackPageLabels>;\n}\n\n/** What {@link useFeedbackInbox} returns: the state, and the props of the parts. */\nexport interface FeedbackInboxState<T extends FeedbackRecord> {\n /** `canEdit && !mine`: the admin on the inbox. */\n editable: boolean;\n /** The page's title, `feedbackPage.title` — or `.myTitle` on `/my-feedback`. */\n title: string;\n /** The open row's id, from `?row=`; `null` when none is open or the param named no\n * id (`?row=abc`, `?row=1.5`, `?row=0`). */\n openId: number | null;\n /** Open a row by its id, or close it with `null`: rewrites `?row=`, replacing the\n * history entry rather than stacking one per report looked at. */\n setOpenId: (id: number | null) => void;\n /** A row's own address: this view — the table's page, sort and filters — with the row\n * open. The row's link (a new tab, a copied address); a plain click opens it in place. */\n rowHref: (row: T) => string;\n /** The undoable status change (§4.5): the status cell's, the pills', the swipes'. */\n changeStatus: FeedbackStatusChange;\n /** The phone's \"Only what is waiting for you\" — page state, not the URL (§4.3). */\n awaiting: boolean;\n setAwaiting: (next: boolean) => void;\n /** The one date writer the columns, the card and the day headers use. */\n renderDate: FeedbackRenderDate;\n /** `FeedbackRowDetail`'s props for a row, slots included. */\n detailProps: (row: T) => FeedbackRowDetailProps;\n /** `DataTable`'s props, ready to spread: the rows (newest first, narrowed by\n * `awaiting`), the columns, the open row, the detail, the phone's card, day headers and\n * swipes, the desktop's actions column, the empty state, `urlSync`,\n * `storageKey=\"feedback\"`, `fillHeight`. */\n table: DataTableProps<T>;\n}\n\n/** `?row=`'s value: a report's id is a positive integer, written in digits. Anything\n * else — a hand-edited link, `1e2`, `0x10`, `-3`, `1.5` — opens no row (and the URL\n * keeps it until a row is opened or closed). The three apps parsed with `Number()`, so\n * `?row=1e2` opened #100 in all three. */\nfunction parseRowId(raw: string): number | undefined {\n if (!/^[1-9]\\d*$/.test(raw)) return undefined;\n const id = Number(raw);\n return Number.isSafeInteger(id) ? id : undefined;\n}\n\nconst ROW_PARAM = { parse: parseRowId, history: \"replace\" } as const;\n\n/** Newest first, as `GET /feedback` sends it (§3.3) — the phone's day headers group runs\n * of equal days, so an older row between two of today's would split the day in two.\n * ISO strings from one server sort as their instants; the sort is stable. */\nconst newestFirst = (a: FeedbackRecord, b: FeedbackRecord) =>\n a.created_at < b.created_at ? 1 : a.created_at > b.created_at ? -1 : 0;\n\nconst rowId = (row: FeedbackRecord) => row.id;\nconst rowTitle = (row: FeedbackRecord) => row.title;\nconst captureScreenshot = () => captureAppScreenshot();\nconst ignore = () => {};\n/** A slot's \"nothing\": `cond && <Thread />` answers `false`, which the detail would draw\n * as an empty Comments section (it draws one for anything but `null`). */\nconst threadOf = (node: ReactNode): ReactNode => (node === false || node === \"\" ? undefined : node);\n\n/**\n * The inbox's wiring, once (§13): from the app's rows and mutations to what the table,\n * the detail and the phone cards take.\n *\n * ```tsx\n * const list = useQuery({ queryKey: keys.feedback.all, queryFn: api.listFeedback });\n * const update = useMutation({ mutationFn: ({ id, ...patch }: FeedbackDetailPatch) => api.update(id, patch), … });\n * const inbox = useFeedbackInbox({ rows: list.data ?? [], canEdit: isAdmin, viewerId: user?.id, update });\n * <DataTable {...inbox.table} edgeFade />\n * ```\n *\n * {@link FeedbackInbox} is this hook drawn — use the hook alone for a layout of your own.\n * Needs a react-router Router (`?row=`, `urlSync`).\n */\nexport function useFeedbackInbox<T extends FeedbackRecord>({\n rows,\n mine = false,\n canEdit,\n viewerId,\n update,\n reply,\n rework,\n publicSwitch = false,\n votes = false,\n comments,\n renderDetail,\n columns: ownColumns,\n swipe = DEFAULT_FEEDBACK_SWIPE,\n commit,\n onUpload,\n fetcher,\n onCaptureScreenshot = captureScreenshot,\n renderDate: renderDateProp,\n pageLinkExclude,\n loading = false,\n detail,\n labels,\n}: UseFeedbackInboxOptions<T>): FeedbackInboxState<T> {\n // An admin on /my-feedback reads as any author does (§4.3), as `feedbackColumns` has it.\n const editable = canEdit && !mine;\n const pageLabels = useFeedbackPageLabels(labels);\n const statusLabels = useFeedbackStatusLabels();\n const renderDate = useFeedbackRenderDate(renderDateProp);\n\n // TanStack's `mutateAsync` is stable, so the Undo and the columns' memo hold across\n // renders; the mutation object around it is not.\n const updateAsync = update.mutateAsync;\n const changeStatus = useFeedbackStatusUndo(updateAsync);\n\n // The open row IS the URL (§4.3: `?row=<id>`, every app) — which is what makes a row a\n // real link at all (keksdose feedback #451). Replace, not push: looking through ten\n // reports is not ten steps for Back.\n const [openId, setOpenId] = useSearchParamState<number | null>(\"row\", null, ROW_PARAM);\n const { pathname, search } = useLocation();\n // Through the router, so a basename (and a hash router's `#`) is in the address.\n const here = useHref({ pathname });\n // Built from the CURRENT query, not a bare `?row=`: the table keeps its `f.*`, `sort`\n // and `p` in the URL, and dropping them would open the new tab on an unfiltered list\n // where the row may not be on the first page (keksdose feedback-page.tsx:145).\n const rowHref = useCallback(\n (row: T) => {\n const params = new URLSearchParams(search);\n params.set(\"row\", String(row.id));\n return `${here}?${params.toString()}`;\n },\n [here, search],\n );\n\n // A thumb gesture on one screen, not a view worth linking to (§4.3; keksdose live #330).\n const [awaiting, setAwaiting] = useState(false);\n const shown = useMemo(\n () => (editable && awaiting ? rows.filter((row) => isFeedbackAwaiting(row.status)) : [...rows]).sort(newestFirst),\n [rows, editable, awaiting],\n );\n\n const kitColumns = useFeedbackColumns<T>({\n mine,\n canEdit,\n onStatus: changeStatus,\n renderDate,\n commit,\n votes,\n pageLinkExclude,\n labels,\n });\n const columns = useMemo(() => (ownColumns ? ownColumns(kitColumns) : kitColumns), [ownColumns, kitColumns]);\n const mobileGroupBy = useMemo(() => feedbackMobileGroupBy(renderDate), [renderDate]);\n\n // The rework's sending is the detail's too (keksdose, Kurvenschmiede): its editors and\n // the public switch wait for whichever write is out.\n const pending = Boolean(update.isPending || rework?.isPending);\n const capture = onCaptureScreenshot ?? undefined;\n\n const detailProps = (row: T): FeedbackRowDetailProps => ({\n row,\n canEdit: editable,\n viewerId,\n onUpdate: updateAsync,\n pending,\n // The page's change, not one the detail would build: the same Undo as the cell's.\n statusChange: changeStatus,\n onUpload,\n fetcher,\n onCaptureScreenshot: capture,\n // Only the app's own: left out, the detail's \"Resolved:\" is the kit's sentence date,\n // no weekday — as kastlan's has always been.\n renderDate: renderDateProp,\n pageLinkExclude,\n onReply: reply\n ? (body, status, attachmentUrl) =>\n reply.mutateAsync({\n id: row.id,\n body,\n ...(status ? { status } : {}),\n ...(attachmentUrl ? { attachmentUrl } : {}),\n })\n : undefined,\n // The reply's one file (§12): all three apps are on server-kit 0.18, and the reply\n // mutation's `attachmentUrl` is in its type from the start (the B1 risk the detail's\n // default guards against — an `onReply` that drops the file — cannot arise here).\n replyAttachments: true,\n replying: reply?.isPending ?? false,\n onRework: rework\n ? (note, attachmentUrl) => rework.mutateAsync({ id: row.id, note, ...(attachmentUrl ? { attachmentUrl } : {}) })\n : undefined,\n comments: threadOf(comments?.(row)),\n onPublicChange: publicSwitch ? (next) => runMutation(updateAsync, { id: row.id, public: next }, ignore) : undefined,\n ...detail,\n });\n\n const table: DataTableProps<T> = {\n rows: shown,\n columns,\n rowKey: rowId,\n storageKey: \"feedback\",\n urlSync: true,\n fillHeight: true,\n rowHref,\n // The link covers the row's first cell; a click anywhere on the row opens it — or,\n // on the open one, closes it.\n onRowClick: (row) => setOpenId((id) => (id === row.id ? null : row.id)),\n isExpanded: (row) => row.id === openId,\n expandedRow: (row) => {\n const node = <FeedbackRowDetail {...detailProps(row)} />;\n return renderDetail ? renderDetail(row, node) : node;\n },\n // §7.13: one word, also when a filter or the toggle leaves nothing; and while the\n // first answer is out, what is happening instead.\n empty: loading ? <LoadingState size=\"sm\" inline /> : <FeedbackEmptyState labels={labels} />,\n mobileGroupBy,\n mobileCard: (row) => (\n <FeedbackMobileCard row={row} showSubmitter={editable} renderDate={renderDate} votes={votes} labels={labels} />\n ),\n // The admin inbox only — /my-feedback is read-only by design (keksdose #331) — and\n // every swipe through the same Undo as a tap (§4.5, §7.10).\n mobileSwipeActions: editable\n ? (row) => feedbackSwipePlan(swipe, row, { change: changeStatus, labels: statusLabels })\n : undefined,\n // The swipes as the desktop's last column (0.46, keksdose dev#598), less what the\n // status cell already offers.\n desktopSwipeActions: { omit: feedbackSwipeOmitShown, name: rowTitle, ...(commit === undefined ? {} : { commit }) },\n };\n\n return {\n editable,\n title: mine ? pageLabels.myTitle : pageLabels.title,\n openId,\n setOpenId,\n rowHref,\n changeStatus,\n awaiting,\n setAwaiting,\n renderDate,\n detailProps,\n table,\n };\n}\n\n/* ── The component ──────────────────────────────────────────────────────────── */\n\nexport interface FeedbackInboxProps<T extends FeedbackRecord> extends UseFeedbackInboxOptions<T> {\n /**\n * Above the table. Default: `<PageHeader title={title} className=\"mb-4 md:shrink-0\" />`.\n * A function gets the page's title (`feedbackPage.title` / `.myTitle`) — the app's own\n * header: `(title) => <PageHeader size=\"compact\" title={title} data-tour=\"feedback-header\" />`.\n * `null` for none.\n */\n header?: ReactNode | ((title: string) => ReactNode);\n /** Over the inbox's `DataTable` props — `edgeFade`, `locale`, `mobileExpandAsDialog`,\n * `className`, another `storageKey`. Merged last, so it wins. */\n table?: Partial<DataTableProps<T>>;\n /** Further `FloatingAction`s on the phone: after the awaiting toggle on the inbox, in a\n * group of their own on `/my-feedback`. */\n phoneActions?: ReactNode;\n /** On the page's frame — the fill-height column (`FILL_HEIGHT_CLASS`); the app's page\n * padding goes here. */\n className?: string;\n}\n\n/**\n * The feedback inbox (§13): `/feedback` and `/my-feedback` drawn whole from\n * {@link useFeedbackInbox} — the header, the table with its detail, phone cards and swipes,\n * and the phone's awaiting toggle, in the fill-height frame (page layout §1.3) — so a page\n * is its queries and this:\n *\n * ```tsx\n * export function FeedbackPage({ mine = false }: { mine?: boolean }) {\n * const { user, isAdmin } = useAuth();\n * const list = useQuery({ queryKey: mine ? keys.mine : keys.all, queryFn: mine ? api.mine : api.all });\n * const update = useFeedbackUpdate();\n * const reply = useFeedbackReply();\n * const rework = useFeedbackRework();\n * if (!mine && !isAdmin) return <Navigate to=\"/my-feedback\" replace />;\n * return (\n * <FeedbackInbox\n * rows={list.data ?? []} loading={list.isPending} mine={mine} canEdit={isAdmin} viewerId={user?.id}\n * update={update} reply={reply} rework={rework}\n * onUpload={api.upload} fetcher={api.file}\n * />\n * );\n * }\n * ```\n *\n * Every slot is {@link UseFeedbackInboxOptions}' or one of the four below. The redirect of\n * a non-admin, the routes and the queries stay the app's.\n */\nexport function FeedbackInbox<T extends FeedbackRecord>({\n header,\n table,\n phoneActions,\n className,\n ...options\n}: FeedbackInboxProps<T>) {\n const inbox = useFeedbackInbox<T>(options);\n const pageLabels = useFeedbackPageLabels(options.labels);\n const head =\n header === undefined ? (\n <PageHeader title={inbox.title} className=\"mb-4 md:shrink-0\" />\n ) : typeof header === \"function\" ? (\n header(inbox.title)\n ) : (\n header\n );\n return (\n // A plain element on the way to the table carries the fill (page layout §1.3).\n <div className={cn(FILL_HEIGHT_CLASS, className)} aria-busy={options.loading || undefined} data-feedback-inbox=\"\">\n {head}\n <DataTable {...inbox.table} {...table} />\n {inbox.editable ? (\n // The phone's floating action (keksdose feedback #58): only on the inbox — on\n // /my-feedback the author is not waiting on their own verdict.\n <FeedbackAwaitingToggle pressed={inbox.awaiting} onPressedChange={inbox.setAwaiting} labels={options.labels}>\n {phoneActions}\n </FeedbackAwaitingToggle>\n ) : (\n phoneActions && (\n <FloatingActionGroup aria-label={pageLabels.phoneActions} className=\"md:hidden\">\n {phoneActions}\n </FloatingActionGroup>\n )\n )}\n </div>\n );\n}\n"],"mappings":";AA2ZmB,cAsGf,YAtGe;AA3ZnB,SAAS,aAAa,SAAS,gBAAgB;AAE/C,SAAS,SAAS,mBAAmB;AACrC,SAAS,UAAU;AACnB,SAAS,iBAA4D;AACrE,SAAS,2BAA2B;AACpC,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAG3B,SAAS,2BAA2B;AAGpC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AACxC,SAAS,mBAAmB;AAE5B;AAAA,EACE;AAAA,OAIK;AACP,SAAS,6BAAwD;AACjE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AA4MP,SAAS,WAAW,KAAiC;AACnD,MAAI,CAAC,aAAa,KAAK,GAAG,EAAG,QAAO;AACpC,QAAM,KAAK,OAAO,GAAG;AACrB,SAAO,OAAO,cAAc,EAAE,IAAI,KAAK;AACzC;AAEA,MAAM,YAAY,EAAE,OAAO,YAAY,SAAS,UAAU;AAK1D,MAAM,cAAc,CAAC,GAAmB,MACtC,EAAE,aAAa,EAAE,aAAa,IAAI,EAAE,aAAa,EAAE,aAAa,KAAK;AAEvE,MAAM,QAAQ,CAAC,QAAwB,IAAI;AAC3C,MAAM,WAAW,CAAC,QAAwB,IAAI;AAC9C,MAAM,oBAAoB,MAAM,qBAAqB;AACrD,MAAM,SAAS,MAAM;AAAC;AAGtB,MAAM,WAAW,CAAC,SAAgC,SAAS,SAAS,SAAS,KAAK,SAAY;AAgBvF,SAAS,iBAA2C;AAAA,EACzD;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,YAAY;AAAA,EACZ;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAsD;AAEpD,QAAM,WAAW,WAAW,CAAC;AAC7B,QAAM,aAAa,sBAAsB,MAAM;AAC/C,QAAM,eAAe,wBAAwB;AAC7C,QAAM,aAAa,sBAAsB,cAAc;AAIvD,QAAM,cAAc,OAAO;AAC3B,QAAM,eAAe,sBAAsB,WAAW;AAKtD,QAAM,CAAC,QAAQ,SAAS,IAAI,oBAAmC,OAAO,MAAM,SAAS;AACrF,QAAM,EAAE,UAAU,OAAO,IAAI,YAAY;AAEzC,QAAM,OAAO,QAAQ,EAAE,SAAS,CAAC;AAIjC,QAAM,UAAU;AAAA,IACd,CAAC,QAAW;AACV,YAAM,SAAS,IAAI,gBAAgB,MAAM;AACzC,aAAO,IAAI,OAAO,OAAO,IAAI,EAAE,CAAC;AAChC,aAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AAAA,IACrC;AAAA,IACA,CAAC,MAAM,MAAM;AAAA,EACf;AAGA,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,QAAQ;AAAA,IACZ,OAAO,YAAY,WAAW,KAAK,OAAO,CAAC,QAAQ,mBAAmB,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,WAAW;AAAA,IAChH,CAAC,MAAM,UAAU,QAAQ;AAAA,EAC3B;AAEA,QAAM,aAAa,mBAAsB;AAAA,IACvC;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,UAAU,QAAQ,MAAO,aAAa,WAAW,UAAU,IAAI,YAAa,CAAC,YAAY,UAAU,CAAC;AAC1G,QAAM,gBAAgB,QAAQ,MAAM,sBAAsB,UAAU,GAAG,CAAC,UAAU,CAAC;AAInF,QAAM,UAAU,QAAQ,OAAO,aAAa,QAAQ,SAAS;AAC7D,QAAM,UAAU,uBAAuB;AAEvC,QAAM,cAAc,CAAC,SAAoC;AAAA,IACvD;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,UAAU;AAAA,IACV;AAAA;AAAA,IAEA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA;AAAA;AAAA,IAGrB,YAAY;AAAA,IACZ;AAAA,IACA,SAAS,QACL,CAAC,MAAM,QAAQ,kBACb,MAAM,YAAY;AAAA,MAChB,IAAI,IAAI;AAAA,MACR;AAAA,MACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC3B,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,IAC3C,CAAC,IACH;AAAA;AAAA;AAAA;AAAA,IAIJ,kBAAkB;AAAA,IAClB,UAAU,OAAO,aAAa;AAAA,IAC9B,UAAU,SACN,CAAC,MAAM,kBAAkB,OAAO,YAAY,EAAE,IAAI,IAAI,IAAI,MAAM,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC,EAAG,CAAC,IAC7G;AAAA,IACJ,UAAU,SAAS,WAAW,GAAG,CAAC;AAAA,IAClC,gBAAgB,eAAe,CAAC,SAAS,YAAY,aAAa,EAAE,IAAI,IAAI,IAAI,QAAQ,KAAK,GAAG,MAAM,IAAI;AAAA,IAC1G,GAAG;AAAA,EACL;AAEA,QAAM,QAA2B;AAAA,IAC/B,MAAM;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ;AAAA;AAAA;AAAA,IAGA,YAAY,CAAC,QAAQ,UAAU,CAAC,OAAQ,OAAO,IAAI,KAAK,OAAO,IAAI,EAAG;AAAA,IACtE,YAAY,CAAC,QAAQ,IAAI,OAAO;AAAA,IAChC,aAAa,CAAC,QAAQ;AACpB,YAAM,OAAO,oBAAC,qBAAmB,GAAG,YAAY,GAAG,GAAG;AACtD,aAAO,eAAe,aAAa,KAAK,IAAI,IAAI;AAAA,IAClD;AAAA;AAAA;AAAA,IAGA,OAAO,UAAU,oBAAC,gBAAa,MAAK,MAAK,QAAM,MAAC,IAAK,oBAAC,sBAAmB,QAAgB;AAAA,IACzF;AAAA,IACA,YAAY,CAAC,QACX,oBAAC,sBAAmB,KAAU,eAAe,UAAU,YAAwB,OAAc,QAAgB;AAAA;AAAA;AAAA,IAI/G,oBAAoB,WAChB,CAAC,QAAQ,kBAAkB,OAAO,KAAK,EAAE,QAAQ,cAAc,QAAQ,aAAa,CAAC,IACrF;AAAA;AAAA;AAAA,IAGJ,qBAAqB,EAAE,MAAM,wBAAwB,MAAM,UAAU,GAAI,WAAW,SAAY,CAAC,IAAI,EAAE,OAAO,EAAG;AAAA,EACnH;AAEA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,OAAO,WAAW,UAAU,WAAW;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAkDO,SAAS,cAAwC;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,QAAQ,iBAAoB,OAAO;AACzC,QAAM,aAAa,sBAAsB,QAAQ,MAAM;AACvD,QAAM,OACJ,WAAW,SACT,oBAAC,cAAW,OAAO,MAAM,OAAO,WAAU,oBAAmB,IAC3D,OAAO,WAAW,aACpB,OAAO,MAAM,KAAK,IAElB;AAEJ;AAAA;AAAA,IAEE,qBAAC,SAAI,WAAW,GAAG,mBAAmB,SAAS,GAAG,aAAW,QAAQ,WAAW,QAAW,uBAAoB,IAC5G;AAAA;AAAA,MACD,oBAAC,aAAW,GAAG,MAAM,OAAQ,GAAG,OAAO;AAAA,MACtC,MAAM;AAAA;AAAA;AAAA,QAGL,oBAAC,0BAAuB,SAAS,MAAM,UAAU,iBAAiB,MAAM,aAAa,QAAQ,QAAQ,QAClG,wBACH;AAAA,UAEA,gBACE,oBAAC,uBAAoB,cAAY,WAAW,cAAc,WAAU,aACjE,wBACH;AAAA,OAGN;AAAA;AAEJ;","names":[]}
@@ -53,6 +53,11 @@ export interface FeedbackContext {
53
53
  ua?: string;
54
54
  /** The app build (`__APP_VERSION__`). */
55
55
  version?: string;
56
+ /** What the app attached about the thing reported (keksdose's stuck receipt scan, live
57
+ * #481): a flat record of short values, in the order the app wrote them. The row
58
+ * detail shows it to the admin and the author, never to anyone else; erasure drops it
59
+ * (it is not on server-kit's `FEEDBACK_CONTEXT_KEEP`). */
60
+ diagnostics?: Readonly<Record<string, unknown>>;
56
61
  fingerprint?: string;
57
62
  /** Which error boundary caught it. */
58
63
  boundary?: "app" | "page" | (string & {});