@eifi1/ui-kit 0.52.0 → 0.54.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 (290) hide show
  1. package/README.md +52 -59
  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/auth/auth-errors.d.ts +36 -0
  5. package/dist/auth/auth-errors.js +20 -0
  6. package/dist/auth/auth-errors.js.map +1 -1
  7. package/dist/billing/cancel-subscription.d.ts +5 -14
  8. package/dist/billing/cancel-subscription.js +1 -3
  9. package/dist/billing/cancel-subscription.js.map +1 -1
  10. package/dist/billing/plan-card.d.ts +5 -13
  11. package/dist/billing/plan-card.js +3 -11
  12. package/dist/billing/plan-card.js.map +1 -1
  13. package/dist/billing/plan-switch.d.ts +5 -14
  14. package/dist/billing/plan-switch.js +1 -3
  15. package/dist/billing/plan-switch.js.map +1 -1
  16. package/dist/chart.d.ts +3 -14
  17. package/dist/chart.js +64 -11
  18. package/dist/chart.js.map +1 -1
  19. package/dist/components/amount-input.d.ts +2 -1
  20. package/dist/components/amount-input.js.map +1 -1
  21. package/dist/components/calendar-heatmap.js +4 -2
  22. package/dist/components/calendar-heatmap.js.map +1 -1
  23. package/dist/components/currency-option-list.d.ts +2 -1
  24. package/dist/components/currency-option-list.js +10 -3
  25. package/dist/components/currency-option-list.js.map +1 -1
  26. package/dist/components/currency-select.d.ts +3 -1
  27. package/dist/components/currency-select.js.map +1 -1
  28. package/dist/components/danger-confirm.d.ts +22 -1
  29. package/dist/components/danger-confirm.js +50 -28
  30. package/dist/components/danger-confirm.js.map +1 -1
  31. package/dist/components/data-table-filter-popover.d.ts +2 -1
  32. package/dist/components/data-table-filter-popover.js +3 -2
  33. package/dist/components/data-table-filter-popover.js.map +1 -1
  34. package/dist/components/data-table-filters.d.ts +33 -3
  35. package/dist/components/data-table-filters.js +6 -4
  36. package/dist/components/data-table-filters.js.map +1 -1
  37. package/dist/components/date-field.d.ts +1 -1
  38. package/dist/components/date-field.js.map +1 -1
  39. package/dist/components/date-picker.d.ts +1 -1
  40. package/dist/components/date-picker.js.map +1 -1
  41. package/dist/components/date-range-picker.d.ts +4 -17
  42. package/dist/components/date-range-picker.js +2 -2
  43. package/dist/components/date-range-picker.js.map +1 -1
  44. package/dist/components/dialog-frame.d.ts +3 -1
  45. package/dist/components/dialog-frame.js +6 -2
  46. package/dist/components/dialog-frame.js.map +1 -1
  47. package/dist/components/mini-calendar.js +3 -2
  48. package/dist/components/mini-calendar.js.map +1 -1
  49. package/dist/components/modal.d.ts +27 -0
  50. package/dist/components/modal.js +5 -3
  51. package/dist/components/modal.js.map +1 -1
  52. package/dist/components/nav-pills.d.ts +1 -1
  53. package/dist/components/nav-pills.js.map +1 -1
  54. package/dist/components/number-input.js.map +1 -1
  55. package/dist/components/series-chart-axes.d.ts +1 -1
  56. package/dist/components/series-chart-axes.js.map +1 -1
  57. package/dist/components/series-chart.d.ts +64 -19
  58. package/dist/components/series-chart.js +2 -1
  59. package/dist/components/series-chart.js.map +1 -1
  60. package/dist/components/stat-tile.d.ts +21 -2
  61. package/dist/components/stat-tile.js +4 -2
  62. package/dist/components/stat-tile.js.map +1 -1
  63. package/dist/components/treemap-labels.d.ts +6 -1
  64. package/dist/components/treemap-labels.js +2 -2
  65. package/dist/components/treemap-labels.js.map +1 -1
  66. package/dist/components/treemap.d.ts +29 -4
  67. package/dist/components/treemap.js +22 -9
  68. package/dist/components/treemap.js.map +1 -1
  69. package/dist/currencies.d.ts +16 -2
  70. package/dist/currencies.js +2 -1
  71. package/dist/currencies.js.map +1 -1
  72. package/dist/data-table.d.ts +1 -6
  73. package/dist/data-table.js +1 -9
  74. package/dist/data-table.js.map +1 -1
  75. package/dist/demo/demo-countdown.d.ts +0 -5
  76. package/dist/demo/demo-countdown.js +0 -4
  77. package/dist/demo/demo-countdown.js.map +1 -1
  78. package/dist/eslint/index.js +1 -1
  79. package/dist/feedback/feedback-context-labels.js +2 -1
  80. package/dist/feedback/feedback-context-labels.js.map +1 -1
  81. package/dist/feedback/feedback-context.d.ts +19 -3
  82. package/dist/feedback/feedback-context.js +12 -1
  83. package/dist/feedback/feedback-context.js.map +1 -1
  84. package/dist/feedback/feedback-diagnostics.d.ts +17 -0
  85. package/dist/feedback/feedback-diagnostics.js +27 -0
  86. package/dist/feedback/feedback-diagnostics.js.map +1 -0
  87. package/dist/feedback/feedback-dialog.d.ts +10 -0
  88. package/dist/feedback/feedback-dialog.js +6 -4
  89. package/dist/feedback/feedback-dialog.js.map +1 -1
  90. package/dist/feedback/feedback-mutation.d.ts +11 -23
  91. package/dist/feedback/feedback-mutation.js +1 -9
  92. package/dist/feedback/feedback-mutation.js.map +1 -1
  93. package/dist/feedback/feedback-public-list.d.ts +1 -6
  94. package/dist/feedback/feedback-public-list.js +1 -2
  95. package/dist/feedback/feedback-public-list.js.map +1 -1
  96. package/dist/feedback/feedback-record.d.ts +5 -0
  97. package/dist/feedback/feedback-record.js.map +1 -1
  98. package/dist/feedback/feedback-row-detail-labels.js +1 -8
  99. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  100. package/dist/feedback/feedback-row-detail.d.ts +6 -50
  101. package/dist/feedback/feedback-row-detail.js +3 -8
  102. package/dist/feedback/feedback-row-detail.js.map +1 -1
  103. package/dist/feedback/feedback-status-undo.d.ts +3 -19
  104. package/dist/feedback/feedback-status-undo.js.map +1 -1
  105. package/dist/feedback/feedback-submit-dialog.d.ts +5 -1
  106. package/dist/feedback/feedback-submit-dialog.js +15 -3
  107. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  108. package/dist/feedback/feedback-submit.d.ts +30 -2
  109. package/dist/feedback/feedback-submit.js +5 -2
  110. package/dist/feedback/feedback-submit.js.map +1 -1
  111. package/dist/feedback/feedback-thread.d.ts +0 -9
  112. package/dist/feedback/feedback-thread.js.map +1 -1
  113. package/dist/feedback.d.ts +6 -40
  114. package/dist/feedback.js +88 -46
  115. package/dist/feedback.js.map +1 -1
  116. package/dist/hooks/use-hotkey.js +11 -1
  117. package/dist/hooks/use-hotkey.js.map +1 -1
  118. package/dist/i18n/defaults.js +0 -4
  119. package/dist/i18n/defaults.js.map +1 -1
  120. package/dist/i18n/german.js +5 -20
  121. package/dist/i18n/german.js.map +1 -1
  122. package/dist/i18n/kit-labels.d.ts +5 -14
  123. package/dist/i18n/kit-labels.js.map +1 -1
  124. package/dist/i18n/locales/en.js +5 -31
  125. package/dist/i18n/locales/en.js.map +3 -3
  126. package/dist/i18n/locales/es.js +5 -20
  127. package/dist/i18n/locales/es.js.map +1 -1
  128. package/dist/i18n/locales/fr.js +5 -20
  129. package/dist/i18n/locales/fr.js.map +1 -1
  130. package/dist/i18n/locales/hu.js +5 -20
  131. package/dist/i18n/locales/hu.js.map +1 -1
  132. package/dist/i18n/locales/it.js +5 -21
  133. package/dist/i18n/locales/it.js.map +1 -1
  134. package/dist/i18n/locales/zh.js +5 -20
  135. package/dist/i18n/locales/zh.js.map +1 -1
  136. package/dist/i18n/review.js +9 -4
  137. package/dist/i18n/review.js.map +1 -1
  138. package/dist/i18n/shared-labels.js +0 -1
  139. package/dist/i18n/shared-labels.js.map +1 -1
  140. package/dist/index.d.ts +18 -67
  141. package/dist/index.js +28 -103
  142. package/dist/index.js.map +1 -1
  143. package/dist/lib/dates.d.ts +7 -1
  144. package/dist/lib/dates.js +8 -1
  145. package/dist/lib/dates.js.map +1 -1
  146. package/dist/lib/format.d.ts +37 -2
  147. package/dist/lib/format.js +25 -1
  148. package/dist/lib/format.js.map +1 -1
  149. package/dist/lib/intl-cache.d.ts +4 -2
  150. package/dist/lib/intl-cache.js.map +1 -1
  151. package/dist/lib/translation-review.d.ts +26 -0
  152. package/dist/lib/translation-review.js +14 -0
  153. package/dist/lib/translation-review.js.map +1 -1
  154. package/dist/rhf/fields.d.ts +2 -2
  155. package/dist/rhf/fields.js.map +1 -1
  156. package/dist/search/search-index.d.ts +0 -6
  157. package/dist/search/search-index.js +0 -4
  158. package/dist/search/search-index.js.map +1 -1
  159. package/dist/search.d.ts +1 -8
  160. package/dist/search.js +2 -7
  161. package/dist/search.js.map +1 -1
  162. package/dist/shell/account-menu-language.d.ts +7 -21
  163. package/dist/shell/account-menu-language.js +1 -3
  164. package/dist/shell/account-menu-language.js.map +1 -1
  165. package/dist/shell/account-menu-text-size.d.ts +9 -23
  166. package/dist/shell/account-menu-text-size.js +2 -3
  167. package/dist/shell/account-menu-text-size.js.map +1 -1
  168. package/dist/shell/app-shell.d.ts +0 -10
  169. package/dist/shell/app-shell.js +1 -7
  170. package/dist/shell/app-shell.js.map +1 -1
  171. package/dist/shell/company-switcher.d.ts +1 -1
  172. package/dist/shell/company-switcher.js.map +1 -1
  173. package/dist/shell/dev-menu.d.ts +1 -1
  174. package/dist/shell/dev-menu.js.map +1 -1
  175. package/dist/shell/top-bar-parts-labels.d.ts +1 -1
  176. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  177. package/dist/shell.d.ts +7 -29
  178. package/dist/shell.js +12 -42
  179. package/dist/shell.js.map +1 -1
  180. package/dist/sync.d.ts +2 -6
  181. package/dist/sync.js +2 -15
  182. package/dist/sync.js.map +1 -1
  183. package/dist/theme/chart-palette.d.ts +0 -5
  184. package/dist/theme/chart-palette.js +0 -2
  185. package/dist/theme/chart-palette.js.map +1 -1
  186. package/package.json +1 -1
  187. package/src/account/delete-account-setting.tsx +3 -2
  188. package/src/auth/auth-errors.ts +69 -0
  189. package/src/billing/cancel-subscription.tsx +5 -16
  190. package/src/billing/plan-card.tsx +7 -24
  191. package/src/billing/plan-switch.tsx +5 -16
  192. package/src/chart.ts +62 -13
  193. package/src/components/amount-input.tsx +2 -1
  194. package/src/components/calendar-heatmap.tsx +8 -2
  195. package/src/components/currency-option-list.tsx +12 -4
  196. package/src/components/currency-select.tsx +3 -1
  197. package/src/components/danger-confirm.tsx +80 -27
  198. package/src/components/data-table-filter-popover.tsx +19 -11
  199. package/src/components/data-table-filters.ts +36 -8
  200. package/src/components/date-field.tsx +1 -1
  201. package/src/components/date-picker.tsx +0 -1
  202. package/src/components/date-range-picker.tsx +6 -22
  203. package/src/components/dialog-frame.tsx +12 -4
  204. package/src/components/mini-calendar.tsx +5 -2
  205. package/src/components/modal.tsx +36 -7
  206. package/src/components/nav-pills.tsx +1 -1
  207. package/src/components/number-input.tsx +4 -3
  208. package/src/components/series-chart-axes.ts +6 -1
  209. package/src/components/series-chart.tsx +78 -21
  210. package/src/components/stat-tile.tsx +32 -3
  211. package/src/components/treemap-labels.ts +11 -3
  212. package/src/components/treemap.tsx +65 -12
  213. package/src/currencies.ts +23 -3
  214. package/src/data-table.ts +1 -11
  215. package/src/demo/demo-countdown.ts +3 -8
  216. package/src/feedback/feedback-context-labels.ts +1 -0
  217. package/src/feedback/feedback-context.tsx +34 -2
  218. package/src/feedback/feedback-diagnostics.tsx +41 -0
  219. package/src/feedback/feedback-dialog.tsx +16 -4
  220. package/src/feedback/feedback-mutation.ts +12 -33
  221. package/src/feedback/feedback-public-list.tsx +1 -7
  222. package/src/feedback/feedback-record.ts +5 -0
  223. package/src/feedback/feedback-row-detail-labels.ts +1 -8
  224. package/src/feedback/feedback-row-detail.tsx +21 -58
  225. package/src/feedback/feedback-status-undo.ts +4 -18
  226. package/src/feedback/feedback-submit-dialog.tsx +15 -2
  227. package/src/feedback/feedback-submit.tsx +36 -3
  228. package/src/feedback/feedback-thread.tsx +0 -10
  229. package/src/feedback.ts +89 -48
  230. package/src/hooks/use-hotkey.ts +24 -1
  231. package/src/i18n/defaults.ts +0 -4
  232. package/src/i18n/german.ts +4 -19
  233. package/src/i18n/kit-labels.tsx +5 -14
  234. package/src/i18n/locales/es.ts +4 -19
  235. package/src/i18n/locales/fr.ts +4 -19
  236. package/src/i18n/locales/hu.ts +4 -19
  237. package/src/i18n/locales/it.ts +4 -20
  238. package/src/i18n/locales/zh.ts +4 -19
  239. package/src/i18n/review.ts +9 -4
  240. package/src/i18n/shared-labels.ts +0 -1
  241. package/src/index.ts +44 -114
  242. package/src/lib/dates.ts +24 -2
  243. package/src/lib/format.ts +66 -3
  244. package/src/lib/intl-cache.ts +4 -2
  245. package/src/lib/translation-review.ts +52 -0
  246. package/src/rhf/fields.tsx +2 -2
  247. package/src/search/search-index.ts +0 -15
  248. package/src/search.ts +8 -8
  249. package/src/shell/account-menu-language.tsx +7 -27
  250. package/src/shell/account-menu-text-size.tsx +13 -32
  251. package/src/shell/app-shell.tsx +0 -13
  252. package/src/shell/company-switcher.tsx +1 -1
  253. package/src/shell/dev-menu.tsx +1 -1
  254. package/src/shell/top-bar-parts-labels.ts +1 -1
  255. package/src/shell.ts +17 -44
  256. package/src/sync.ts +2 -15
  257. package/src/theme/chart-palette.ts +0 -2
  258. package/tokens.css +4 -4
  259. package/dist/billing/dialog-close.d.ts +0 -29
  260. package/dist/billing/dialog-close.js +0 -8
  261. package/dist/billing/dialog-close.js.map +0 -1
  262. package/dist/components/field-sync-labels.d.ts +0 -3
  263. package/dist/components/field-sync-labels.js +0 -12
  264. package/dist/components/field-sync-labels.js.map +0 -1
  265. package/dist/components/field-sync.d.ts +0 -186
  266. package/dist/components/field-sync.js +0 -269
  267. package/dist/components/field-sync.js.map +0 -1
  268. package/dist/components/section-nav.d.ts +0 -44
  269. package/dist/components/section-nav.js +0 -33
  270. package/dist/components/section-nav.js.map +0 -1
  271. package/dist/components/sign-chip-labels.d.ts +0 -3
  272. package/dist/components/sign-chip-labels.js +0 -11
  273. package/dist/components/sign-chip-labels.js.map +0 -1
  274. package/dist/components/sign-chip.d.ts +0 -77
  275. package/dist/components/sign-chip.js +0 -47
  276. package/dist/components/sign-chip.js.map +0 -1
  277. package/dist/lib/isin.d.ts +0 -38
  278. package/dist/lib/isin.js +0 -36
  279. package/dist/lib/isin.js.map +0 -1
  280. package/dist/shell/role-switcher.d.ts +0 -28
  281. package/dist/shell/role-switcher.js +0 -31
  282. package/dist/shell/role-switcher.js.map +0 -1
  283. package/src/billing/dialog-close.ts +0 -34
  284. package/src/components/field-sync-labels.ts +0 -14
  285. package/src/components/field-sync.tsx +0 -504
  286. package/src/components/section-nav.tsx +0 -72
  287. package/src/components/sign-chip-labels.ts +0 -13
  288. package/src/components/sign-chip.tsx +0 -133
  289. package/src/lib/isin.ts +0 -72
  290. package/src/shell/role-switcher.tsx +0 -53
@@ -35,7 +35,8 @@ import {
35
35
  splitDescription,
36
36
  } from "./feedback-record";
37
37
  import type { FeedbackContext, FeedbackRecord } from "./feedback-record";
38
- import { runMutation, type FeedbackMutationCall } from "./feedback-mutation";
38
+ import { diagnosticsEntries, FeedbackDiagnosticsList } from "./feedback-diagnostics";
39
+ import { runMutation } from "./feedback-mutation";
39
40
  import { feedbackPage, feedbackPageLinkTarget } from "./feedback-page-link";
40
41
  import { useFeedbackStatusUndo } from "./feedback-status-undo";
41
42
  import type { FeedbackStatusChange } from "./feedback-status-undo";
@@ -117,6 +118,9 @@ export interface FeedbackDetailLabels {
117
118
  /** The copy button beside the link — copies the FULL `context.url`.
118
119
  * de-CH: "URL kopieren" */
119
120
  copyUrl: string;
121
+ /** The heading over `context.diagnostics`, between the URL and the attachment (keksdose
122
+ * live #481). de-CH: "Diagnose" */
123
+ diagnostics: string;
120
124
  /** Section 3's heading, and each picture's alt text. de-CH: "Anhang" */
121
125
  attachment: string;
122
126
  /** A PDF's / text file's download button, given the file's name.
@@ -133,22 +137,6 @@ export interface FeedbackDetailLabels {
133
137
  /** On section 4's heading line once the row is settled, given the formatted
134
138
  * `resolved_at` date. de-CH: "Erledigt am: {{date}}" */
135
139
  resolvedAt: (date: string) => string;
136
- // Deprecated on these members, the ones an app's code reads and overrides through: the
137
- // tags sat on the English default's keys, and reached nothing — the default is typed by
138
- // this interface (0.52 code review, feedback-row-detail-labels.ts; refactor audit
139
- // 2026-10-30, DOC-9).
140
- /** The admin's button while there is no outcome — read by nothing since 0.38 (the
141
- * outcome is frozen, §9.7; a reply is written instead). de-CH: "Ergebnis hinzufügen"
142
- * @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
143
- outcomeAdd: string;
144
- /** The same button once there is one. Unused since 0.38, as `outcomeAdd`.
145
- * de-CH: "Aktualisieren"
146
- * @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
147
- outcomeUpdate: string;
148
- /** The line above the outcome editor. Unused since 0.38, as `outcomeAdd`.
149
- * de-CH: "Was wurde umgesetzt, entschieden oder warum nicht."
150
- * @deprecated 0.52 — a reply: the outcome is frozen since 0.38 (§9.7); removed in 0.53. */
151
- outcomePlaceholder: string;
152
140
  /** The button that opens section 5 on an answered row. de-CH: "Nacharbeit" */
153
141
  rework: string;
154
142
  /** Section 5's heading. de-CH: "Zur Nacharbeit senden" */
@@ -181,23 +169,10 @@ export function useFeedbackDetailLabels(labels?: LabelOverride<FeedbackDetailLab
181
169
 
182
170
  /* ── The page a report was filed on (§3.2, §4.4.2) ────────────────────────── */
183
171
 
184
- /**
185
- * The page a report was filed on as the reporter had it — path + query + hash (keksdose
186
- * `localHref`: the query and hash carry the state, `?tab=import`, a drill-down). Read from
187
- * `context.url`, else `context.route`; a path-only `url` works. `null` when there is no
188
- * page.
189
- *
190
- * Always a path on THIS app, never another origin's address — but the path and query
191
- * are the reporter's to write, so it is TEXT, not a link target: `/join?token=…` acts on
192
- * load, and `/login?next=…` forwards a signed-in admin to whatever its query names
193
- * (refactor audit 2026-10-30, FLW-7; 0.52 code review). The kit's URL cell and section
194
- * link {@link feedbackPagePath} alone, and not even that for a one-shot route
195
- * (`pageLinkExclude`) — `FeedbackRowDetail` and `useFeedbackColumns` draw the page that
196
- * way; an app's own cell should not link this.
197
- */
198
- export function feedbackPageHref(context: FeedbackContext | null | undefined): string | null {
199
- return feedbackPage(context)?.href ?? null;
200
- }
172
+ // The page as the reporter had it (path + query + hash) and the full URL "Copy URL"
173
+ // copies were public too, as `feedbackPageHref` and `feedbackPageUrl`, until 0.53 (deprecated
174
+ // in 0.52, API-4): `feedbackPage` (./feedback-page-link) is the one reading, and the kit
175
+ // links only its path.
201
176
 
202
177
  /** The page's path alone — the compact text a URL column shows (§4.3), and the only part
203
178
  * of the page the kit links. */
@@ -205,15 +180,6 @@ export function feedbackPagePath(context: FeedbackContext | null | undefined): s
205
180
  return feedbackPage(context)?.path ?? null;
206
181
  }
207
182
 
208
- /**
209
- * What "Copy URL" copies: the FULL `context.url` as the reporter's browser had it —
210
- * origin included, which is the one part that says which copy of the app it was
211
- * (feedback #278) — else `context.route`. `null` when there is no page.
212
- */
213
- export function feedbackPageUrl(context: FeedbackContext | null | undefined): string | null {
214
- return feedbackPage(context)?.url ?? null;
215
- }
216
-
217
183
  /* ── Attachments (§3.5, §4.4.3) ───────────────────────────────────────────── */
218
184
 
219
185
  /**
@@ -319,17 +285,6 @@ export interface FeedbackDetailPatch {
319
285
  */
320
286
  export type FeedbackDetailUpdateAsync = (patch: FeedbackDetailPatch) => Promise<unknown>;
321
287
 
322
- /**
323
- * The callback form: TanStack Query's `mutate`, or a function that calls `onSuccess` once
324
- * the PATCH has landed. TanStack calls a per-call `onSuccess` for the LATEST `mutate()`
325
- * only, so an editor whose save was followed by another PATCH before it answered stayed
326
- * open, and the earlier status change lost its Undo.
327
- *
328
- * @deprecated 0.52 — pass `update.mutateAsync` ({@link FeedbackDetailUpdateAsync}); removed
329
- * in 0.53
330
- */
331
- export type FeedbackDetailUpdate = (patch: FeedbackDetailPatch, callbacks: { onSuccess: () => void }) => void;
332
-
333
288
  /** `POST /feedback/attachments` (§3.3): one file up, its URL
334
289
  * (`/api/v1/feedback/attachments/<key>`) back. Reject on failure. */
335
290
  export type FeedbackUpload = (file: File) => Promise<string>;
@@ -351,7 +306,7 @@ export interface FeedbackReworkSectionProps {
351
306
  /** The PATCH — see {@link FeedbackDetailUpdateAsync}. Called with `{ id, body }` only,
352
307
  * and only without `onRework`: the legacy append (§3.4), which server-kit 0.13 still
353
308
  * turns into an entry for one release. Optional since 0.40; pass one of the two. */
354
- onUpdate?: FeedbackMutationCall<FeedbackDetailPatch>;
309
+ onUpdate?: FeedbackDetailUpdateAsync;
355
310
  /** The PATCH is in flight (`update.isPending`). The upload adds its own. */
356
311
  pending?: boolean;
357
312
  /** The upload. Left out, the note goes without a file field. */
@@ -517,9 +472,8 @@ export interface FeedbackRowDetailProps {
517
472
  /** The signed-in user's id — who the AUTHOR is: the description editor and rework. */
518
473
  viewerId?: number | null;
519
474
  /** The page's PATCH — `update.mutateAsync` (see {@link FeedbackDetailUpdateAsync}). The
520
- * callback form ({@link FeedbackDetailUpdate}, `update.mutate`) still fits, deprecated
521
- * since 0.52; the prop's one signature takes both. */
522
- onUpdate: FeedbackMutationCall<FeedbackDetailPatch>;
475
+ * callback form, `update.mutate`, went in 0.53 (deprecated in 0.52). */
476
+ onUpdate: FeedbackDetailUpdateAsync;
523
477
  /** `update.isPending`: the editors' save buttons wait for it. */
524
478
  pending?: boolean;
525
479
  /** `POST /feedback/attachments` for the rework's one file and, since 0.47 (§12) with
@@ -681,6 +635,9 @@ export function FeedbackRowDetail({
681
635
  const { description } = splitDescription(row.body);
682
636
  const page = feedbackPage(row.context);
683
637
  const pageLink = page && feedbackPageLinkTarget(page, pageLinkExclude);
638
+ // What the app attached is for whoever handles the report and whoever sent it, never
639
+ // for another viewer of a shared row (keksdose live #481).
640
+ const diagnostics = canEdit || access.isAuthor ? diagnosticsEntries(row.context?.diagnostics) : [];
684
641
  // 0.47 (§12): with the entries, each entry's file is drawn inline in the Replies
685
642
  // timeline, so the Attachment section holds the report's own files.
686
643
  const files = feedbackAttachmentUrls(row.replies ? { ...row, replies: undefined } : row);
@@ -783,6 +740,12 @@ export function FeedbackRowDetail({
783
740
  </FeedbackDetailSection>
784
741
  )}
785
742
 
743
+ {diagnostics.length > 0 && (
744
+ <FeedbackDetailSection title={labels.diagnostics}>
745
+ <FeedbackDiagnosticsList entries={diagnostics} />
746
+ </FeedbackDetailSection>
747
+ )}
748
+
786
749
  {files.length > 0 && (
787
750
  <FeedbackDetailSection title={labels.attachment}>
788
751
  <div className="flex min-w-0 flex-wrap items-start gap-2">
@@ -9,7 +9,7 @@ import {
9
9
  } from "./feedback-labels";
10
10
  import type { FeedbackRecord } from "./feedback-record";
11
11
  import type { LabelOverride } from "../i18n/kit-labels";
12
- import { runMutation, type FeedbackMutationCall } from "./feedback-mutation";
12
+ import { runMutation } from "./feedback-mutation";
13
13
 
14
14
  /**
15
15
  * A status change that can be taken back — §4.5 of the feedback contract, lifted from
@@ -42,17 +42,6 @@ export interface FeedbackStatusPatch {
42
42
  */
43
43
  export type FeedbackStatusMutateAsync = (patch: FeedbackStatusPatch) => Promise<unknown>;
44
44
 
45
- /**
46
- * The callback form: TanStack Query's `mutate`, or a function that calls `onSuccess` once
47
- * the PATCH has landed. TanStack calls a per-call `onSuccess` for the LATEST `mutate()` on
48
- * its observer only, so a second change sent before the first answered — another swipe,
49
- * another pill, the Undo itself — lost the first change's Undo toast.
50
- *
51
- * @deprecated 0.52 — pass `update.mutateAsync` ({@link FeedbackStatusMutateAsync}), whose
52
- * promise settles for every call; removed in 0.53
53
- */
54
- export type FeedbackStatusMutate = (patch: FeedbackStatusPatch, callbacks: { onSuccess: () => void }) => void;
55
-
56
45
  /** What the change needs to know about the row: which one, what it is called in the
57
46
  * toast, and where it stood (the status Undo goes back to). */
58
47
  export type FeedbackStatusRow = Pick<FeedbackRecord, "id" | "title" | "status">;
@@ -90,14 +79,11 @@ export const FEEDBACK_UNDO_DURATION = 8000;
90
79
  * `{ id, status: previous }` → once that has landed `statusRestored(previousName, title)`.
91
80
  * Each change waits for its OWN answer, so two changes in flight each get their toast.
92
81
  *
93
- * `update.mutate` ({@link FeedbackStatusMutate}) still fits, deprecated since 0.52: with it
94
- * a second change before the first answered loses the first one's Undo. One signature
95
- * takes both rather than two overloads: TypeScript types an inline callback's parameters
96
- * from the FIRST overload, so a hand-written `(patch, { onSuccess }) => …` — the form this
97
- * hook documented until 0.52 — would no longer compile.
82
+ * `update.mutate`, the callback form, went in 0.53 (deprecated in 0.52): with it a second
83
+ * change before the first answered lost the first one's Undo.
98
84
  */
99
85
  export function useFeedbackStatusUndo(
100
- mutate: FeedbackMutationCall<FeedbackStatusPatch>,
86
+ mutate: FeedbackStatusMutateAsync,
101
87
  { labels, statusLabels }: FeedbackStatusUndoOptions = {},
102
88
  ): FeedbackStatusChange {
103
89
  const words = useFeedbackToastLabels(labels);
@@ -12,6 +12,7 @@ import {
12
12
  type FeedbackContext,
13
13
  type FeedbackEnvironment,
14
14
  } from "./feedback-record";
15
+ import type { FeedbackSubmitOpenOptions } from "./feedback-submit";
15
16
  import type { FeedbackCategory } from "./feedback-vocabulary";
16
17
 
17
18
  /**
@@ -49,6 +50,9 @@ export interface FeedbackSubmitDialogProps {
49
50
  capture?: false | (() => Promise<File | null>);
50
51
  /** `UseFeedbackSubmitOptions.publicNotice` (0.38): the line under the body. */
51
52
  publicNotice?: boolean;
53
+ /** `open(category, options)`'s, taken when it opened (keksdose live #481): the box
54
+ * shows the diagnostics and the report carries them; the title and body prefill. */
55
+ opened?: FeedbackSubmitOpenOptions;
52
56
  }
53
57
 
54
58
  /** `FeedbackDialog` as `useFeedbackSubmit` settles it — see the hook for what it settles. */
@@ -66,6 +70,7 @@ export function FeedbackSubmitDialog({
66
70
  version,
67
71
  capture,
68
72
  publicNotice = false,
73
+ opened: { diagnostics, title, body } = {},
69
74
  }: FeedbackSubmitDialogProps) {
70
75
  const toastText = useFeedbackToastLabels();
71
76
  const dialogText = useKitLabels("feedbackDialog", DEFAULT_FEEDBACK_DIALOG_LABELS);
@@ -108,10 +113,18 @@ export function FeedbackSubmitDialog({
108
113
  }
109
114
  onCaptureScreenshot={onCaptureScreenshot}
110
115
  publicNotice={publicNotice ? (dialogText.publicNotice ?? DEFAULT_FEEDBACK_DIALOG_LABELS.publicNotice) : undefined}
116
+ defaultTitle={title}
117
+ defaultBody={body}
111
118
  // The context is read off the very values the box below shows (§3.2).
112
- onSubmit={(data) => onSubmit(data, feedbackContext({ user, attachUrl, url, environment, version }))}
119
+ onSubmit={(data) => onSubmit(data, feedbackContext({ user, attachUrl, url, environment, version, diagnostics }))}
113
120
  contextSlot={
114
- <FeedbackContextBox user={user} url={url} attachUrl={attachUrl} onAttachUrlChange={onAttachUrlChange} />
121
+ <FeedbackContextBox
122
+ user={user}
123
+ url={url}
124
+ attachUrl={attachUrl}
125
+ onAttachUrlChange={onAttachUrlChange}
126
+ diagnostics={diagnostics}
127
+ />
115
128
  }
116
129
  />
117
130
  );
@@ -97,14 +97,42 @@ export interface UseFeedbackSubmitOptions<R = unknown> {
97
97
  publicNotice?: boolean;
98
98
  }
99
99
 
100
+ /**
101
+ * `open`'s second argument (keksdose live #481: "Report this problem" on a receipt scan
102
+ * that never finished, filed with the scan's bookkeeping). All of it optional, and none of
103
+ * it outlives the opening it was handed to.
104
+ */
105
+ export interface FeedbackSubmitOpenOptions {
106
+ /**
107
+ * What the app knows about the thing reported — keksdose's stuck scan: its id, status,
108
+ * attempts, last error. Taken when the dialog opens (a shallow copy, so what the box
109
+ * shows is what goes, even if the app's object changes while the reporter types), shown
110
+ * read-only in the context box, and sent as `context.diagnostics` whatever "Attach
111
+ * current page URL" says: that box withholds the page, not this. Flat, short values,
112
+ * never the reported content itself (§3.2); the row detail shows them to the admin and
113
+ * the author only.
114
+ */
115
+ diagnostics?: Readonly<Record<string, unknown>>;
116
+ /** The subject the form starts with; the reporter can change it. Where the app's reports
117
+ * are public (`publicNotice`), other users read it: what only the admin should see goes
118
+ * in `diagnostics`. */
119
+ title?: string;
120
+ /** The body the form starts with, as `title` is the subject's. */
121
+ body?: string;
122
+ }
123
+
100
124
  export interface FeedbackSubmit {
101
125
  /**
102
126
  * Open the dialog on `category` — a `FeedbackMenu` row's (§4.2: "default category when
103
127
  * opened from a row: that row's"). Without one, or with `CRASH` (never pickable), it
104
128
  * opens on `OTHER`, the server's own default (§3.4). Each open starts a fresh form,
105
129
  * reads `location.href` for the context box and ticks "Attach current page URL" again.
130
+ *
131
+ * `options` (0.54, keksdose live #481) is a screen's own report — `open("BUG", {
132
+ * diagnostics })` from "Report this problem": the diagnostics shown in the box and sent,
133
+ * the subject and body prefilled. An open without them starts empty and sends none.
106
134
  */
107
- open: (category?: FeedbackCategory) => void;
135
+ open: (category?: FeedbackCategory, options?: FeedbackSubmitOpenOptions) => void;
108
136
  /** Close it, as Cancel does. */
109
137
  close: () => void;
110
138
  /**
@@ -140,7 +168,8 @@ export interface FeedbackSubmit {
140
168
  * - The pickable categories — Bug, Idea, Question, Other, in the kit's words. `CRASH` is
141
169
  * filed by the error boundary and is never offered (keksdose feedback #160).
142
170
  * - The context box, built from the same values as the `context` it sends
143
- * ({@link FeedbackContextBox} / `feedbackContext`), the URL read when the dialog OPENS.
171
+ * ({@link FeedbackContextBox} / `feedbackContext`), the URL read when the dialog OPENS,
172
+ * and the diagnostics `open` was handed then (0.54, keksdose live #481).
144
173
  * - Upload every file, then create (keksdose `use-feedback-dialog.tsx:89`): the
145
174
  * screenshot to `screenshot_url`, the rest to `attachment_urls`, all in parallel.
146
175
  * - The toasts, from `feedbackToast`: filed, failed (the server's `detail` through
@@ -161,18 +190,21 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
161
190
  const [category, setCategory] = useState<FeedbackCategory>("OTHER");
162
191
  const [url, setUrl] = useState("");
163
192
  const [attachUrl, setAttachUrl] = useState(true);
193
+ const [opened, setOpened] = useState<FeedbackSubmitOpenOptions>({});
164
194
  const [submitting, setSubmitting] = useState(false);
165
195
  // Which opening a send belongs to — see "closed and opened again" above.
166
196
  const opening = useRef(0);
167
197
  const inFlight = useRef(false);
168
198
 
169
- const open = (next?: FeedbackCategory) => {
199
+ const open = (next?: FeedbackCategory, given?: FeedbackSubmitOpenOptions) => {
170
200
  opening.current += 1;
171
201
  setCategory(next && FEEDBACK_PICKABLE_CATEGORIES.includes(next) ? next : "OTHER");
172
202
  setUrl(typeof window === "undefined" ? "" : window.location.href);
173
203
  // Fresh every time (Kurvenschmiede use-feedback-dialog.tsx:80): a reporter who left the
174
204
  // page out of one idea is not saying the bug report after it is unrelated too.
175
205
  setAttachUrl(true);
206
+ // This opening's own, nothing of the last one's; the diagnostics copied now (#481).
207
+ setOpened({ ...given, diagnostics: given?.diagnostics && { ...given.diagnostics } });
176
208
  setIsOpen(true);
177
209
  };
178
210
  const close = () => setIsOpen(false);
@@ -229,6 +261,7 @@ export function useFeedbackSubmit<R = unknown>(options: UseFeedbackSubmitOptions
229
261
  version={version}
230
262
  capture={capture}
231
263
  publicNotice={publicNotice}
264
+ opened={opened}
232
265
  />
233
266
  </Suspense>
234
267
  ) : null;
@@ -903,13 +903,3 @@ function dataAttributes(props: object): Record<string, unknown> {
903
903
  for (const [key, value] of Object.entries(props)) if (key.startsWith("data-")) out[key] = value;
904
904
  return out;
905
905
  }
906
-
907
- /** @deprecated 0.52 — {@link ChatComposerProps}, the same type; removed in 0.53 */
908
- export type FeedbackComposerProps = ChatComposerProps;
909
- /** @deprecated 0.52 — {@link ChatComposerHandle}, the same type; removed in 0.53 */
910
- export type FeedbackComposerHandle = ChatComposerHandle;
911
- /** @deprecated 0.52 — {@link ChatComposerLabels}, the same type (still the provider's
912
- * `feedbackComposer` namespace); removed in 0.53 */
913
- export type FeedbackComposerLabels = ChatComposerLabels;
914
- /** @deprecated 0.52 — {@link ChatComposerSlotContext}, the same type; removed in 0.53 */
915
- export type FeedbackComposerSlotContext = ChatComposerSlotContext;
package/src/feedback.ts CHANGED
@@ -9,20 +9,103 @@ export * from "./feedback/feedback-inbox";
9
9
  export * from "./feedback/feedback-thread";
10
10
  // 0.27.0: the feedback harmonization (docs/feedback-harmonization.md) — one record,
11
11
  // one menu, dialog, table, detail and crash reporter for keksdose, kastlan, Kurvenschmiede.
12
- export * from "./feedback/feedback-record";
12
+ //
13
+ // Named, not `*`, for six of its modules: 0.53 took the slice's share of the 55 names no app
14
+ // reads off the surface (deprecated in 0.52, refactor audit 2026-10-30, API-4) —
15
+ // `feedbackAttachmentLine`, `FEEDBACK_UNDO_DURATION`, `FEEDBACK_SWIPE_ACTIONS`,
16
+ // `feedbackColumns`, `feedbackSubmitter`, `feedbackSubmitterEmail`, `feedbackEnvironment`,
17
+ // `feedbackPagePath`, `feedbackAttachmentUrls`, `feedbackRowAccess`, `useFeedbackDetailLabels`
18
+ // and `feedbackPublicSwitchAllowed`, which their modules keep for the kit's own use.
19
+ // `feedbackPageHref` and `feedbackPageUrl` went whole: nothing read them.
20
+ export {
21
+ DEFAULT_ATTACHMENT_ACCEPT,
22
+ DEFAULT_MAX_ATTACHMENT_BYTES,
23
+ DEFAULT_MAX_ATTACHMENTS,
24
+ FEEDBACK_ATTACHMENT_ACCEPT,
25
+ FEEDBACK_PICKABLE_CATEGORIES,
26
+ FEEDBACK_REWORKABLE_STATUSES,
27
+ FEEDBACK_QUEUE_STATUSES,
28
+ FEEDBACK_AUTHOR_EDITABLE_STATUSES,
29
+ FEEDBACK_AWAITING_STATUSES,
30
+ FEEDBACK_DECIDED_STATUSES,
31
+ FEEDBACK_COMMENT_MAX,
32
+ FEEDBACK_REPLY_MAX,
33
+ appendRework,
34
+ reworkCount,
35
+ feedbackReworkCount,
36
+ splitBodyAttachments,
37
+ splitDescription,
38
+ replaceDescription,
39
+ isImageAttachment,
40
+ attachmentName,
41
+ type FeedbackEnvironment,
42
+ type FeedbackContext,
43
+ type FeedbackRecord,
44
+ } from "./feedback/feedback-record";
13
45
  export * from "./feedback/feedback-labels";
14
- export * from "./feedback/feedback-status-undo";
15
- export * from "./feedback/feedback-swipe";
46
+ export {
47
+ useFeedbackStatusUndo,
48
+ type FeedbackStatusPatch,
49
+ type FeedbackStatusMutateAsync,
50
+ type FeedbackStatusRow,
51
+ type FeedbackStatusChange,
52
+ type FeedbackStatusUndoOptions,
53
+ } from "./feedback/feedback-status-undo";
54
+ export {
55
+ DEFAULT_FEEDBACK_SWIPE,
56
+ feedbackSwipePlan,
57
+ feedbackSwipeOmitShown,
58
+ type FeedbackSwipeAction,
59
+ type FeedbackSwipeBinding,
60
+ type FeedbackSwipeOptions,
61
+ } from "./feedback/feedback-swipe";
16
62
  export * from "./feedback/feedback-menu";
17
63
  export * from "./feedback/feedback-context";
18
64
  export * from "./feedback/feedback-capture";
19
65
  export * from "./feedback/feedback-submit";
20
- export * from "./feedback/feedback-table";
21
- export * from "./feedback/feedback-row-detail";
66
+ export {
67
+ DEFAULT_FEEDBACK_PAGE_LABELS,
68
+ useFeedbackPageLabels,
69
+ isFeedbackAwaiting,
70
+ useFeedbackRenderDate,
71
+ FeedbackSubject,
72
+ useFeedbackColumns,
73
+ feedbackMobileGroupBy,
74
+ FeedbackMobileCard,
75
+ FeedbackAwaitingToggle,
76
+ FeedbackEmptyState,
77
+ type FeedbackPageLabels,
78
+ type FeedbackTableRow,
79
+ type FeedbackRenderDate,
80
+ type FeedbackSubjectProps,
81
+ type FeedbackColumnsOptions,
82
+ type UseFeedbackColumnsOptions,
83
+ type FeedbackMobileCardProps,
84
+ type FeedbackAwaitingToggleProps,
85
+ type FeedbackEmptyStateProps,
86
+ } from "./feedback/feedback-table";
87
+ export {
88
+ DEFAULT_FEEDBACK_DETAIL_LABELS,
89
+ FeedbackReworkSection,
90
+ FeedbackRowDetail,
91
+ type FeedbackDetailLabels,
92
+ type FeedbackRowAccess,
93
+ type FeedbackDetailPatch,
94
+ type FeedbackDetailUpdateAsync,
95
+ type FeedbackUpload,
96
+ type FeedbackReworkSend,
97
+ type FeedbackReworkSectionProps,
98
+ type FeedbackRowDetailProps,
99
+ } from "./feedback/feedback-row-detail";
22
100
  export * from "./feedback/feedback-crash";
23
101
  // 0.38.0: the public pages (§9.15) — the "Visible to others" switch, the list every user
24
102
  // reads and one report opened.
25
- export * from "./feedback/feedback-public-switch";
103
+ export {
104
+ FeedbackPublicSwitch,
105
+ type FeedbackPublicSwitchRow,
106
+ type FeedbackPublicSwitchViewer,
107
+ type FeedbackPublicSwitchProps,
108
+ } from "./feedback/feedback-public-switch";
26
109
  export * from "./feedback/feedback-public-list";
27
110
  // 0.38.0: public feedback (docs/feedback-harmonization.md §9) — the shapes, the vote, the
28
111
  // comment thread, the replies' timeline and composer.
@@ -31,45 +114,3 @@ export * from "./feedback/feedback-vote-button";
31
114
  export * from "./feedback/feedback-comment-thread";
32
115
  export * from "./feedback/feedback-replies";
33
116
  export * from "./feedback/feedback-entry-file";
34
- // 0.52: the slice's share of the 55 names no app reads (refactor audit 2026-10-30, API-4,
35
- // decision 4), tagged on their specifiers as the barrel's are — the modules keep them.
36
- export {
37
- /** @deprecated 0.52 — `appendRework`, which writes the line (API-4); removed in 0.53 */
38
- feedbackAttachmentLine,
39
- } from "./feedback/feedback-record";
40
- export {
41
- /** @deprecated 0.52 — `useFeedbackStatusUndo`, which keeps its Undo that long (API-4); removed in 0.53 */
42
- FEEDBACK_UNDO_DURATION,
43
- } from "./feedback/feedback-status-undo";
44
- export {
45
- /** @deprecated 0.52 — `DEFAULT_FEEDBACK_SWIPE` and `feedbackSwipePlan`, which name the actions (API-4); removed in 0.53 */
46
- FEEDBACK_SWIPE_ACTIONS,
47
- } from "./feedback/feedback-swipe";
48
- export {
49
- /** @deprecated 0.52 — `useFeedbackColumns`, the same columns in the provider's words (API-4); removed in 0.53 */
50
- feedbackColumns,
51
- /** @deprecated 0.52 — `useFeedbackColumns`, whose submitter cell reads it (API-4); removed in 0.53 */
52
- feedbackSubmitter,
53
- /** @deprecated 0.52 — `useFeedbackColumns`, whose submitter cell reads it (API-4); removed in 0.53 */
54
- feedbackSubmitterEmail,
55
- /** @deprecated 0.52 — `useFeedbackColumns`, whose environment cell reads it (API-4); removed in 0.53 */
56
- feedbackEnvironment,
57
- } from "./feedback/feedback-table";
58
- export {
59
- /** @deprecated 0.52 — `FeedbackRowDetail`, which links the page itself (API-4); removed in 0.53 */
60
- feedbackPageUrl,
61
- /** @deprecated 0.52 — `FeedbackRowDetail` and the table's URL cell, which link only a page's path and keep one-shot pages as text (the 0.52 code review's guard, which an app has no helper for); removed in 0.53 */
62
- feedbackPageHref,
63
- /** @deprecated 0.52 — `FeedbackRowDetail` and the table's URL cell, which show the page themselves; removed in 0.53 */
64
- feedbackPagePath,
65
- /** @deprecated 0.52 — `FeedbackRowDetail`, which lists the attachments itself (API-4); removed in 0.53 */
66
- feedbackAttachmentUrls,
67
- /** @deprecated 0.52 — `FeedbackRowDetail`, which decides who may edit what (API-4); removed in 0.53 */
68
- feedbackRowAccess,
69
- /** @deprecated 0.52 — `FeedbackRowDetail`, which resolves its words itself (API-4); removed in 0.53 */
70
- useFeedbackDetailLabels,
71
- } from "./feedback/feedback-row-detail";
72
- export {
73
- /** @deprecated 0.52 — `FeedbackPublicSwitch`, which asks it (API-4); removed in 0.53 */
74
- feedbackPublicSwitchAllowed,
75
- } from "./feedback/feedback-public-switch";
@@ -119,10 +119,33 @@ export function matchesHotkey(e: KeyboardEvent, combo: ParsedHotkey): boolean {
119
119
  return symbol && !combo.shift ? true : e.shiftKey === combo.shift;
120
120
  }
121
121
 
122
+ /**
123
+ * Whether `el` is editable content — `isContentEditable`, read from the attributes where
124
+ * the engine has no such property (keksdose audit follow-up, 2026-11-01). jsdom is one:
125
+ * there a hotkey fired while typing in a contenteditable, so a test could not show the
126
+ * editor keeping its letters, and an engine without the property would do the same.
127
+ *
128
+ * The nearest element with a `contenteditable` that names a state decides: `""`,
129
+ * `"true"` and `"plaintext-only"` edit, `"false"` does not — a `false` island inside an
130
+ * editor is not typed in. Any other value is the attribute's invalid-value default,
131
+ * which inherits, so the search goes on to the next one up. Keywords are
132
+ * case-insensitive. None at all: editable only in a `designMode` document.
133
+ */
134
+ function isEditableContent(el: HTMLElement): boolean {
135
+ const native = (el as { isContentEditable?: boolean }).isContentEditable;
136
+ if (native !== undefined) return native;
137
+ for (let at = el.closest("[contenteditable]"); at; at = at.parentElement?.closest("[contenteditable]") ?? null) {
138
+ const state = (at.getAttribute("contenteditable") ?? "").toLowerCase();
139
+ if (state === "" || state === "true" || state === "plaintext-only") return true;
140
+ if (state === "false") return false;
141
+ }
142
+ return el.ownerDocument.designMode === "on";
143
+ }
144
+
122
145
  /** Is the focus somewhere that takes typed characters? */
123
146
  function isTypingTarget(target: EventTarget | null): boolean {
124
147
  if (!(target instanceof HTMLElement)) return false;
125
- if (target.isContentEditable) return true;
148
+ if (isEditableContent(target)) return true;
126
149
  if (target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement) return true;
127
150
  if (target instanceof HTMLInputElement) {
128
151
  return !["button", "checkbox", "radio", "submit", "reset", "range", "color", "file", "image"].includes(target.type);
@@ -5,7 +5,6 @@ import { DEFAULT_MONTH_PICKER_LABELS } from "../components/month-picker-labels";
5
5
  import { DEFAULT_PAGE_CONTENTS_LABELS } from "../components/page-contents-labels";
6
6
  import { DEFAULT_POPOVER_LABELS } from "../components/popover-labels";
7
7
  import { DEFAULT_CHIP_INPUT_LABELS } from "../components/chip-labels";
8
- import { DEFAULT_FIELD_SYNC_LABELS } from "../components/field-sync-labels";
9
8
  import { DEFAULT_CHARACTER_COUNT_LABELS, DEFAULT_PASSWORD_REVEAL_LABELS } from "../components/field-base-labels";
10
9
  import { DEFAULT_TABS_LABELS } from "../components/tabs-labels";
11
10
  import { DEFAULT_WIZARD_LABELS } from "../wizard/wizard-labels";
@@ -109,7 +108,6 @@ import { DEFAULT_COUNTRY_SELECT_LABELS } from "../components/country-select-labe
109
108
  import { DEFAULT_INLINE_EDIT_LABELS } from "../components/inline-edit-field-labels";
110
109
  import { DEFAULT_IBAN_INPUT_LABELS } from "../components/iban-input-labels";
111
110
  import { DEFAULT_PHONE_INPUT_LABELS } from "../components/phone-input-labels";
112
- import { DEFAULT_SIGN_CHIP_LABELS } from "../components/sign-chip-labels";
113
111
  import { DEFAULT_COLUMN_MAPPER_LABELS } from "../components/column-mapper-labels";
114
112
  import { DEFAULT_NOTIFICATIONS_LABELS } from "../notifications/notifications-labels";
115
113
  import {
@@ -157,7 +155,6 @@ export const DEFAULT_UI_KIT_LABELS: UiKitLabels = {
157
155
  calculator: DEFAULT_CALCULATOR_LABELS,
158
156
  currency: DEFAULT_CURRENCY_LABELS,
159
157
  chipInput: DEFAULT_CHIP_INPUT_LABELS,
160
- fieldSync: DEFAULT_FIELD_SYNC_LABELS,
161
158
  passwordReveal: DEFAULT_PASSWORD_REVEAL_LABELS,
162
159
  tabs: DEFAULT_TABS_LABELS,
163
160
  appShell: DEFAULT_APP_SHELL_LABELS,
@@ -259,7 +256,6 @@ export const DEFAULT_UI_KIT_LABELS: UiKitLabels = {
259
256
  inlineEdit: DEFAULT_INLINE_EDIT_LABELS,
260
257
  ibanInput: DEFAULT_IBAN_INPUT_LABELS,
261
258
  phoneInput: DEFAULT_PHONE_INPUT_LABELS,
262
- signChip: DEFAULT_SIGN_CHIP_LABELS,
263
259
  columnMapper: DEFAULT_COLUMN_MAPPER_LABELS,
264
260
  notifications: DEFAULT_NOTIFICATIONS_LABELS,
265
261
  adminArea: DEFAULT_ADMIN_AREA_LABELS,
@@ -158,6 +158,7 @@ export function germanLabels(numberLocale: string): UiKitLabels {
158
158
  feedbackContext: {
159
159
  user: "Nutzer",
160
160
  attachUrl: "Aktuelle Seiten-URL anhängen",
161
+ diagnostics: "Mitgesendete Diagnose",
161
162
  },
162
163
  feedbackPage: {
163
164
  title: "Feedback-Eingang",
@@ -190,15 +191,13 @@ export function germanLabels(numberLocale: string): UiKitLabels {
190
191
  cancel: "Abbrechen",
191
192
  url: "URL",
192
193
  copyUrl: "URL kopieren",
194
+ diagnostics: "Diagnose",
193
195
  attachment: "Anhang",
194
196
  download: (name) => `${name} herunterladen`,
195
197
  downloadFailed: "Der Anhang konnte nicht heruntergeladen werden.",
196
198
  outcome: "Ergebnis",
197
199
  replies: "Antworten",
198
200
  resolvedAt: (date) => `Erledigt am: ${date}`,
199
- outcomeAdd: "Ergebnis hinzufügen",
200
- outcomeUpdate: "Aktualisieren",
201
- outcomePlaceholder: "Was wurde umgesetzt, entschieden oder warum nicht.",
202
201
  rework: "Nacharbeit",
203
202
  reworkTitle: "Zur Nacharbeit senden",
204
203
  reworkSend: "Nacharbeit senden",
@@ -513,13 +512,6 @@ export function germanLabels(numberLocale: string): UiKitLabels {
513
512
  noResults: "Keine passenden Symbole",
514
513
  resultCount: (count) => `${n(count)} ${count === 1 ? "Symbol" : "Symbole"}`,
515
514
  },
516
- fieldSync: {
517
- synced: "Gespeichert",
518
- edited: "Nicht gespeicherte Änderungen",
519
- pending: "Wird gespeichert…",
520
- error: "Speichern fehlgeschlagen",
521
- retry: "Erneut versuchen",
522
- },
523
515
  passwordReveal: {
524
516
  show: "Passwort anzeigen",
525
517
  hide: "Passwort verbergen",
@@ -553,7 +545,6 @@ export function germanLabels(numberLocale: string): UiKitLabels {
553
545
  palette: "Darstellungsvorlage",
554
546
  language: "Sprache",
555
547
  languageCurrent: (name) => `Sprache wählen, aktuell: ${name}`,
556
- switchRole: "Rolle wechseln",
557
548
  role: (value) => `Rolle: ${value}`,
558
549
  },
559
550
  pickerSheet: {
@@ -755,8 +746,8 @@ export function germanLabels(numberLocale: string): UiKitLabels {
755
746
  legend: "Kategorien",
756
747
  },
757
748
  treemap: {
758
- tile: (name, value, share) => `${name}: ${value} (${share})`,
759
- group: (name, value, share) => `${name}, Gruppe: ${value} (${share})`,
749
+ tile: (name, value, share) => `${name}: ${value}${share ? ` (${share})` : ""}`,
750
+ group: (name, value, share) => `${name}, Gruppe: ${value}${share ? ` (${share})` : ""}`,
760
751
  inGroup: (name, group) => `${name}, in ${group}`,
761
752
  },
762
753
  confirmDialog: {
@@ -1569,12 +1560,6 @@ export function germanLabels(numberLocale: string): UiKitLabels {
1569
1560
  countryCode: "Ländervorwahl",
1570
1561
  other: "Andere",
1571
1562
  },
1572
- signChip: {
1573
- outflow: "Ausgabe",
1574
- inflow: "Einnahme",
1575
- direction: (current, next) => `Richtung: ${current} – zu ${next} wechseln`,
1576
- switchTo: (next) => `Zu ${next} wechseln`,
1577
- },
1578
1563
  columnMapper: {
1579
1564
  paste: "Tabelle einfügen",
1580
1565
  pasteHint: