@eifi1/ui-kit 0.21.0 → 0.23.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 (320) hide show
  1. package/README.md +42 -25
  2. package/dist/chart.d.ts +19 -14
  3. package/dist/components/account-chips.d.ts +10 -3
  4. package/dist/components/account-chips.js +5 -2
  5. package/dist/components/account-chips.js.map +1 -1
  6. package/dist/components/account-settings.d.ts +33 -2
  7. package/dist/components/account-settings.js +43 -21
  8. package/dist/components/account-settings.js.map +1 -1
  9. package/dist/components/amount-input.d.ts +53 -14
  10. package/dist/components/amount-input.js +17 -28
  11. package/dist/components/amount-input.js.map +1 -1
  12. package/dist/components/autocomplete.d.ts +29 -0
  13. package/dist/components/autocomplete.js +134 -104
  14. package/dist/components/autocomplete.js.map +1 -1
  15. package/dist/components/button-group.d.ts +19 -14
  16. package/dist/components/calculator.d.ts +19 -14
  17. package/dist/components/checkbox-group.d.ts +104 -0
  18. package/dist/components/checkbox-group.js +111 -0
  19. package/dist/components/checkbox-group.js.map +1 -0
  20. package/dist/components/checkbox.d.ts +19 -0
  21. package/dist/components/checkbox.js +30 -7
  22. package/dist/components/checkbox.js.map +1 -1
  23. package/dist/components/chip.d.ts +18 -0
  24. package/dist/components/chip.js +47 -10
  25. package/dist/components/chip.js.map +1 -1
  26. package/dist/components/column-mapper.d.ts +182 -0
  27. package/dist/components/column-mapper.js +375 -0
  28. package/dist/components/column-mapper.js.map +1 -0
  29. package/dist/components/combobox-core.d.ts +39 -2
  30. package/dist/components/combobox-core.js +29 -6
  31. package/dist/components/combobox-core.js.map +1 -1
  32. package/dist/components/combobox.d.ts +91 -2
  33. package/dist/components/combobox.js +454 -308
  34. package/dist/components/combobox.js.map +1 -1
  35. package/dist/components/confirm-dialog.d.ts +69 -161
  36. package/dist/components/confirm-dialog.js +7 -8
  37. package/dist/components/confirm-dialog.js.map +1 -1
  38. package/dist/components/copy-button.d.ts +16 -11
  39. package/dist/components/country-select.d.ts +167 -0
  40. package/dist/components/country-select.js +293 -0
  41. package/dist/components/country-select.js.map +1 -0
  42. package/dist/components/currency-select.d.ts +17 -1
  43. package/dist/components/currency-select.js +56 -23
  44. package/dist/components/currency-select.js.map +1 -1
  45. package/dist/components/danger-confirm.d.ts +69 -166
  46. package/dist/components/danger-confirm.js +144 -50
  47. package/dist/components/danger-confirm.js.map +1 -1
  48. package/dist/components/data-table-cells.d.ts +1 -2
  49. package/dist/components/data-table-filter-popover.d.ts +1 -2
  50. package/dist/components/data-table-filters.d.ts +1 -2
  51. package/dist/components/data-table-labels.d.ts +4 -97
  52. package/dist/components/data-table-labels.js +9 -1
  53. package/dist/components/data-table-labels.js.map +1 -1
  54. package/dist/components/data-table-pagination.d.ts +3 -1
  55. package/dist/components/data-table.d.ts +1 -2
  56. package/dist/components/data-table.js +98 -3
  57. package/dist/components/data-table.js.map +1 -1
  58. package/dist/components/date-picker.d.ts +66 -5
  59. package/dist/components/date-picker.js +378 -66
  60. package/dist/components/date-picker.js.map +1 -1
  61. package/dist/components/entity-combobox.d.ts +42 -1
  62. package/dist/components/entity-combobox.js +154 -113
  63. package/dist/components/entity-combobox.js.map +1 -1
  64. package/dist/components/facing-pair.d.ts +19 -14
  65. package/dist/components/field-parts.d.ts +224 -0
  66. package/dist/components/field-parts.js +156 -0
  67. package/dist/components/field-parts.js.map +1 -0
  68. package/dist/components/field-strip.d.ts +105 -0
  69. package/dist/components/field-strip.js +46 -0
  70. package/dist/components/field-strip.js.map +1 -0
  71. package/dist/components/file-button.d.ts +19 -14
  72. package/dist/components/file-button.js +13 -3
  73. package/dist/components/file-button.js.map +1 -1
  74. package/dist/components/file-dropzone.d.ts +41 -15
  75. package/dist/components/file-dropzone.js +57 -34
  76. package/dist/components/file-dropzone.js.map +1 -1
  77. package/dist/components/form-actions.d.ts +18 -13
  78. package/dist/components/form-actions.js +69 -5
  79. package/dist/components/form-actions.js.map +1 -1
  80. package/dist/components/iban-input.d.ts +69 -0
  81. package/dist/components/iban-input.js +125 -0
  82. package/dist/components/iban-input.js.map +1 -0
  83. package/dist/components/icon-picker.d.ts +21 -2
  84. package/dist/components/icon-picker.js +19 -4
  85. package/dist/components/icon-picker.js.map +1 -1
  86. package/dist/components/inline-edit-field.d.ts +167 -0
  87. package/dist/components/inline-edit-field.js +293 -0
  88. package/dist/components/inline-edit-field.js.map +1 -0
  89. package/dist/components/language-select.d.ts +130 -0
  90. package/dist/components/language-select.js +18 -0
  91. package/dist/components/language-select.js.map +1 -0
  92. package/dist/components/line-items.d.ts +25 -3
  93. package/dist/components/line-items.js +55 -46
  94. package/dist/components/line-items.js.map +1 -1
  95. package/dist/components/list.d.ts +25 -0
  96. package/dist/components/list.js +16 -5
  97. package/dist/components/list.js.map +1 -1
  98. package/dist/components/money-field.d.ts +32 -14
  99. package/dist/components/money-field.js.map +1 -1
  100. package/dist/components/month-picker.d.ts +52 -4
  101. package/dist/components/month-picker.js +291 -86
  102. package/dist/components/month-picker.js.map +1 -1
  103. package/dist/components/multi-entity-combobox.d.ts +26 -1
  104. package/dist/components/multi-entity-combobox.js +143 -102
  105. package/dist/components/multi-entity-combobox.js.map +1 -1
  106. package/dist/components/multi-select.d.ts +8 -1
  107. package/dist/components/multi-select.js +9 -4
  108. package/dist/components/multi-select.js.map +1 -1
  109. package/dist/components/number-field.d.ts +34 -19
  110. package/dist/components/number-field.js +6 -20
  111. package/dist/components/number-field.js.map +1 -1
  112. package/dist/components/number-input.d.ts +79 -19
  113. package/dist/components/number-input.js +90 -38
  114. package/dist/components/number-input.js.map +1 -1
  115. package/dist/components/numpad-sheet.d.ts +19 -14
  116. package/dist/components/one-time-code-input.d.ts +100 -0
  117. package/dist/components/one-time-code-input.js +137 -0
  118. package/dist/components/one-time-code-input.js.map +1 -0
  119. package/dist/components/phone-input.d.ts +69 -0
  120. package/dist/components/phone-input.js +171 -0
  121. package/dist/components/phone-input.js.map +1 -0
  122. package/dist/components/reauth-dialog.d.ts +2 -2
  123. package/dist/components/reauth-dialog.js +6 -8
  124. package/dist/components/reauth-dialog.js.map +1 -1
  125. package/dist/components/series-chart.d.ts +19 -14
  126. package/dist/components/settings-fields.d.ts +19 -14
  127. package/dist/components/share-card.d.ts +16 -11
  128. package/dist/components/sign-chip.d.ts +66 -0
  129. package/dist/components/sign-chip.js +39 -0
  130. package/dist/components/sign-chip.js.map +1 -0
  131. package/dist/components/swatch-picker.d.ts +43 -2
  132. package/dist/components/swatch-picker.js +80 -32
  133. package/dist/components/swatch-picker.js.map +1 -1
  134. package/dist/components/switch.d.ts +19 -0
  135. package/dist/components/switch.js +24 -6
  136. package/dist/components/switch.js.map +1 -1
  137. package/dist/components/text-link.d.ts +18 -13
  138. package/dist/components/tile-radio.d.ts +88 -13
  139. package/dist/components/tile-radio.js +28 -11
  140. package/dist/components/tile-radio.js.map +1 -1
  141. package/dist/components/time-input.d.ts +24 -15
  142. package/dist/components/time-input.js.map +1 -1
  143. package/dist/components/toggle-group.d.ts +47 -1
  144. package/dist/components/toggle-group.js +110 -69
  145. package/dist/components/toggle-group.js.map +1 -1
  146. package/dist/components/trigger-aria.d.ts +3 -0
  147. package/dist/components/trigger-aria.js +3 -1
  148. package/dist/components/trigger-aria.js.map +1 -1
  149. package/dist/components/ui.d.ts +16 -11
  150. package/dist/components/ui.js +284 -88
  151. package/dist/components/ui.js.map +1 -1
  152. package/dist/components/use-table-state.d.ts +1 -2
  153. package/dist/{data-table-3mi2R3so.d.ts → data-table-labels-B7OdnM0S.d.ts} +140 -3
  154. package/dist/data-table.d.ts +1 -2
  155. package/dist/data-table.js +2 -1
  156. package/dist/data-table.js.map +1 -1
  157. package/dist/feedback/feedback-attachment.d.ts +1 -1
  158. package/dist/feedback/feedback-attachment.js +348 -41
  159. package/dist/feedback/feedback-attachment.js.map +1 -1
  160. package/dist/feedback/feedback-dialog.d.ts +1 -1
  161. package/dist/feedback/feedback-dialog.js.map +1 -1
  162. package/dist/feedback/feedback-inbox.d.ts +3 -2
  163. package/dist/feedback/feedback-inbox.js.map +1 -1
  164. package/dist/feedback/feedback-thread.d.ts +68 -253
  165. package/dist/feedback/feedback-thread.js +46 -10
  166. package/dist/feedback/feedback-thread.js.map +1 -1
  167. package/dist/{kit-labels-D1J2_jyD.d.ts → feedback-BxeQVzwq.d.ts} +1206 -20
  168. package/dist/{feedback-attachment-WFiXJ8We.d.ts → feedback-attachment-fGAzZPf0.d.ts} +178 -11
  169. package/dist/feedback.d.ts +66 -2
  170. package/dist/hooks/use-file-drop.d.ts +19 -14
  171. package/dist/i18n/defaults.d.ts +19 -14
  172. package/dist/i18n/defaults.js +19 -2
  173. package/dist/i18n/defaults.js.map +1 -1
  174. package/dist/i18n/german.d.ts +19 -14
  175. package/dist/i18n/german.js +84 -5
  176. package/dist/i18n/german.js.map +1 -1
  177. package/dist/i18n/kit-labels.d.ts +15 -10
  178. package/dist/i18n/kit-labels.js +8 -2
  179. package/dist/i18n/kit-labels.js.map +1 -1
  180. package/dist/i18n/languages.d.ts +19 -14
  181. package/dist/i18n/locales/de-CH.d.ts +19 -14
  182. package/dist/i18n/locales/en.d.ts +19 -14
  183. package/dist/i18n/locales/en.js +16 -0
  184. package/dist/i18n/locales/en.js.map +1 -1
  185. package/dist/i18n/locales/es.d.ts +19 -14
  186. package/dist/i18n/locales/es.js +83 -5
  187. package/dist/i18n/locales/es.js.map +1 -1
  188. package/dist/i18n/locales/fr.d.ts +19 -14
  189. package/dist/i18n/locales/fr.js +82 -5
  190. package/dist/i18n/locales/fr.js.map +1 -1
  191. package/dist/i18n/locales/hu.d.ts +19 -14
  192. package/dist/i18n/locales/hu.js +85 -5
  193. package/dist/i18n/locales/hu.js.map +1 -1
  194. package/dist/i18n/locales/it.d.ts +19 -14
  195. package/dist/i18n/locales/it.js +84 -5
  196. package/dist/i18n/locales/it.js.map +1 -1
  197. package/dist/i18n/locales/zh.d.ts +19 -14
  198. package/dist/i18n/locales/zh.js +80 -5
  199. package/dist/i18n/locales/zh.js.map +1 -1
  200. package/dist/i18n/review.d.ts +19 -14
  201. package/dist/i18n/review.js +27 -1
  202. package/dist/i18n/review.js.map +1 -1
  203. package/dist/index.d.ts +21 -10
  204. package/dist/index.js +73 -2
  205. package/dist/index.js.map +1 -1
  206. package/dist/lib/column-mapping.d.ts +81 -0
  207. package/dist/lib/column-mapping.js +108 -0
  208. package/dist/lib/column-mapping.js.map +1 -0
  209. package/dist/lib/countries.d.ts +43 -0
  210. package/dist/lib/countries.js +39 -0
  211. package/dist/lib/countries.js.map +1 -0
  212. package/dist/lib/decimal-marks.d.ts +46 -0
  213. package/dist/lib/decimal-marks.js +40 -0
  214. package/dist/lib/decimal-marks.js.map +1 -0
  215. package/dist/lib/iban.d.ts +98 -0
  216. package/dist/lib/iban.js +154 -0
  217. package/dist/lib/iban.js.map +1 -0
  218. package/dist/lib/isin.d.ts +30 -0
  219. package/dist/lib/isin.js +36 -0
  220. package/dist/lib/isin.js.map +1 -0
  221. package/dist/lib/phone.d.ts +69 -0
  222. package/dist/lib/phone.js +121 -0
  223. package/dist/lib/phone.js.map +1 -0
  224. package/dist/lib/table-text.d.ts +109 -1
  225. package/dist/lib/table-text.js +122 -1
  226. package/dist/lib/table-text.js.map +1 -1
  227. package/dist/rhf/fields.d.ts +233 -18
  228. package/dist/rhf/fields.js +456 -3
  229. package/dist/rhf/fields.js.map +1 -1
  230. package/dist/rhf/form.d.ts +19 -14
  231. package/dist/rhf.d.ts +22 -15
  232. package/dist/rhf.js.map +1 -1
  233. package/dist/shell/app-shell.d.ts +18 -13
  234. package/dist/shell/top-bar-brand.d.ts +19 -14
  235. package/dist/shell/topbar-action-menu.d.ts +36 -3
  236. package/dist/shell/topbar-action-menu.js +74 -33
  237. package/dist/shell/topbar-action-menu.js.map +1 -1
  238. package/dist/shell.d.ts +18 -13
  239. package/dist/table-text.d.ts +1 -1
  240. package/dist/tour/tour.js +20 -24
  241. package/dist/tour/tour.js.map +1 -1
  242. package/dist/wizard/stepper-nav.d.ts +49 -16
  243. package/dist/wizard/stepper-nav.js +4 -0
  244. package/dist/wizard/stepper-nav.js.map +1 -1
  245. package/dist/wizard.d.ts +19 -14
  246. package/package.json +1 -1
  247. package/src/components/account-chips.tsx +17 -3
  248. package/src/components/account-settings.tsx +92 -26
  249. package/src/components/amount-input.tsx +68 -56
  250. package/src/components/autocomplete.tsx +198 -114
  251. package/src/components/checkbox-group.tsx +229 -0
  252. package/src/components/checkbox.tsx +72 -8
  253. package/src/components/chip.tsx +80 -10
  254. package/src/components/column-mapper.tsx +666 -0
  255. package/src/components/combobox-core.tsx +82 -9
  256. package/src/components/combobox.tsx +661 -340
  257. package/src/components/confirm-dialog.tsx +12 -8
  258. package/src/components/country-select.tsx +556 -0
  259. package/src/components/currency-select.tsx +109 -33
  260. package/src/components/danger-confirm.tsx +429 -82
  261. package/src/components/data-table-labels.ts +16 -1
  262. package/src/components/data-table.tsx +175 -6
  263. package/src/components/date-picker.tsx +595 -71
  264. package/src/components/entity-combobox.tsx +235 -124
  265. package/src/components/field-parts.tsx +403 -0
  266. package/src/components/field-strip.tsx +149 -0
  267. package/src/components/file-button.tsx +36 -3
  268. package/src/components/file-dropzone.tsx +106 -38
  269. package/src/components/form-actions.tsx +147 -6
  270. package/src/components/iban-input.tsx +231 -0
  271. package/src/components/icon-picker.tsx +47 -6
  272. package/src/components/inline-edit-field.tsx +533 -0
  273. package/src/components/language-select.tsx +78 -0
  274. package/src/components/line-items.tsx +35 -2
  275. package/src/components/list.tsx +55 -6
  276. package/src/components/money-field.tsx +13 -0
  277. package/src/components/month-picker.tsx +400 -63
  278. package/src/components/multi-entity-combobox.tsx +207 -120
  279. package/src/components/multi-select.tsx +80 -58
  280. package/src/components/number-field.tsx +28 -46
  281. package/src/components/number-input.tsx +210 -43
  282. package/src/components/one-time-code-input.tsx +288 -0
  283. package/src/components/phone-input.tsx +299 -0
  284. package/src/components/reauth-dialog.tsx +17 -18
  285. package/src/components/sign-chip.tsx +103 -0
  286. package/src/components/swatch-picker.tsx +143 -31
  287. package/src/components/switch.tsx +58 -7
  288. package/src/components/tile-radio.tsx +145 -29
  289. package/src/components/time-input.tsx +8 -1
  290. package/src/components/toggle-group.tsx +206 -73
  291. package/src/components/trigger-aria.ts +5 -0
  292. package/src/components/ui.tsx +479 -138
  293. package/src/data-table.ts +2 -1
  294. package/src/feedback/feedback-attachment.tsx +597 -46
  295. package/src/feedback/feedback-dialog.tsx +9 -3
  296. package/src/feedback/feedback-inbox.tsx +3 -2
  297. package/src/feedback/feedback-thread.tsx +113 -9
  298. package/src/i18n/defaults.ts +18 -1
  299. package/src/i18n/german.ts +89 -0
  300. package/src/i18n/kit-labels.tsx +82 -2
  301. package/src/i18n/locales/en.ts +36 -4
  302. package/src/i18n/locales/es.ts +87 -0
  303. package/src/i18n/locales/fr.ts +87 -0
  304. package/src/i18n/locales/hu.ts +83 -0
  305. package/src/i18n/locales/it.ts +88 -0
  306. package/src/i18n/locales/zh.ts +76 -0
  307. package/src/i18n/review.ts +26 -0
  308. package/src/index.ts +71 -3
  309. package/src/lib/column-mapping.ts +234 -0
  310. package/src/lib/countries.ts +91 -0
  311. package/src/lib/decimal-marks.ts +99 -0
  312. package/src/lib/iban.ts +171 -0
  313. package/src/lib/isin.ts +62 -0
  314. package/src/lib/phone.ts +211 -0
  315. package/src/lib/table-text.ts +271 -0
  316. package/src/rhf/fields.tsx +860 -9
  317. package/src/rhf.ts +3 -1
  318. package/src/shell/topbar-action-menu.tsx +134 -38
  319. package/src/tour/tour.tsx +66 -28
  320. package/src/wizard/stepper-nav.tsx +35 -1
@@ -1,254 +1,69 @@
1
- import { j as FeedbackAttachmentLabels } from '../feedback-attachment-WFiXJ8We.js';
2
- import { FeedbackNoteAttachment } from './feedback-inbox.js';
3
- import * as react from 'react';
4
- import { ReactNode, Ref } from 'react';
1
+ import 'react';
2
+ export { z as ChatComposer, D as ChatComposerHandle, E as ChatComposerLabels, F as ChatComposerProps, a3 as DEFAULT_FEEDBACK_COMPOSER_LABELS, a4 as DEFAULT_FEEDBACK_THREAD_LABELS, ax as FeedbackComposer, ay as FeedbackComposerAttachment, az as FeedbackComposerHandle, aA as FeedbackComposerLabels, aB as FeedbackComposerProps, aC as FeedbackThread, aD as FeedbackThreadAttachment, aE as FeedbackThreadEvent, aF as FeedbackThreadItem, aG as FeedbackThreadLabels, aH as FeedbackThreadMessage, aI as FeedbackThreadProps } from '../feedback-BxeQVzwq.js';
3
+ import '../feedback-attachment-fGAzZPf0.js';
4
+ import './feedback-inbox.js';
5
+ import '../components/tooltip.js';
6
+ import '../hooks/use-anchored-rect.js';
7
+ import '../lib/clipping.js';
8
+ import '../data-table-labels-B7OdnM0S.js';
9
+ import '../components/data-table-sort.js';
10
+ import '../components/swipeable-row.js';
11
+ import '../components/mini-calendar.js';
12
+ import '../components/calendar-heatmap.js';
13
+ import '../components/popover.js';
14
+ import '../components/chip.js';
5
15
  import 'lucide-react';
6
-
7
- /**
8
- * The conversation under a report: who said what, when, with what attached — and the
9
- * box to answer in.
10
- *
11
- * Both apps had written it by hand. kastlan's feedback page grew a comment list of
12
- * bordered boxes with `slate-*` literals (feedback-page.tsx, "keksdose left this
13
- * unbuilt"), and keksdose built the same thing a second time for support
14
- * (support-thread.tsx) with sides, bubbles and a composer that clears only what it
15
- * sent. This is that second one, generalised: the kit owns the look and the
16
- * behaviour, the app owns the data, the upload and every word it does not share.
17
- *
18
- * **Own vs other** is the caller's per message (`own`), not a comparison the kit makes
19
- * against a user id: whose message sits at the END side depends on who is reading,
20
- * and only the app knows that (keksdose's support thread labelled a member's question
21
- * "Du" in the admin panel the first time round, by reading the wrong field).
22
- *
23
- * **Redaction.** A thread is somebody's words about their own data — exactly what a
24
- * host's demo / screen-share mode blurs. Bodies, authors and attachments carry
25
- * `data-private` (the attribute `Tooltip redact` and `StatTile sensitive` use) unless
26
- * `redact={false}`.
27
- *
28
- * **RTL.** Sides are logical — `justify-end` is the reading end, and the bubble's
29
- * tucked corner is `rounded-ee` / `rounded-es` — and each body is `dir="auto"`, so a
30
- * Hebrew reply in an English thread (or the reverse) lays out as its own language.
31
- *
32
- * **A chat, too** (keksdose G4/G5). keksdose's support chat is the same conversation
33
- * read the chat way: status lines between the messages ("Closed automatically",
34
- * "Reopened"), a day line where the date changes, clock times under it, Enter to send
35
- * and several files uploaded ahead of the send. Each of those is an opt-in here
36
- * (`kind: "event"`, `daySeparators`, `timeFormat="clock"`, `sendOn="enter"`,
37
- * `attachmentSlot` + `canSend`), so the feedback thread's defaults stay as they were.
38
- */
39
- /** The `feedbackThread` namespace of `<UiKitProvider labels>`. */
40
- interface FeedbackThreadLabels {
41
- /** Accessible name of the message list. */
42
- thread: string;
43
- empty: string;
44
- loading: string;
45
- /** Author line of an `own` message that has no `author` of its own. */
46
- you: string;
47
- /** The badge beside a `staff` author. */
48
- staff: string;
49
- /** Accessible name of a message's attachment list. */
50
- attachments: string;
51
- }
52
- declare const DEFAULT_FEEDBACK_THREAD_LABELS: FeedbackThreadLabels;
53
- /** The `feedbackComposer` namespace of `<UiKitProvider labels>`. The attach buttons'
54
- * words are `feedbackAttachment`'s, shared with the dialog and the note editor. */
55
- interface FeedbackComposerLabels {
56
- /** Accessible name of the text box. */
57
- field: string;
58
- placeholder: string;
59
- send: string;
60
- /** The shortcut line, given the platform's modifier ("Ctrl" or "⌘"). */
61
- sendHint: (modifier: string) => string;
62
- /** The shortcut line under `sendOn="enter"` (keksdose G5): Enter sends, so say how a
63
- * new line is made. */
64
- sendHintEnter: string;
65
- }
66
- declare const DEFAULT_FEEDBACK_COMPOSER_LABELS: FeedbackComposerLabels;
67
- interface FeedbackThreadAttachment {
68
- id?: string | number;
69
- name: string;
70
- /** Where to open it. Left out, the attachment is listed by name only. */
71
- url?: string;
72
- /** MIME type; an `image/*` with a `url` is shown as a thumbnail. */
73
- type?: string;
74
- /** Bytes, shown beside a non-image. */
75
- size?: number;
76
- }
77
- interface FeedbackThreadMessage {
78
- /** Leave out, or `"message"`. `"event"` is a {@link FeedbackThreadEvent}. */
79
- kind?: "message";
80
- id: string | number;
81
- /** Who wrote it. Left out on an `own` message, it reads "You". */
82
- author?: ReactNode;
83
- /** A `Date`, an ISO string or epoch ms. */
84
- createdAt: Date | string | number;
85
- body: string;
86
- attachments?: readonly FeedbackThreadAttachment[];
87
- /** Written by whoever is reading: sits at the end side, in the brand tint. */
88
- own?: boolean;
89
- /** Written by the team rather than a user: gets the "Staff" badge. */
90
- staff?: boolean;
91
- }
92
- /**
93
- * A line in the thread that nobody wrote — "Closed automatically", "Marked as
94
- * resolved", "Reopened" — drawn centred and muted with its time, no author, no side,
95
- * no bubble.
96
- *
97
- * keksdose G4: its support chat interleaves these with the messages, and as a message
98
- * they came out as a bubble from nobody at the start side, which reads as the member
99
- * having said "resolved". Word it for the READER, as with `own`: the app knows whether
100
- * "you reopened it" or "Anna reopened it" is true for the person looking.
101
- *
102
- * The text is the app's, not somebody's words about their data, so it is NOT tagged
103
- * `data-private`; one that names a person can wrap the name in its own
104
- * `<span data-private>` (`body` is a node for that reason).
105
- */
106
- interface FeedbackThreadEvent {
107
- kind: "event";
108
- id: string | number;
109
- /** A `Date`, an ISO string or epoch ms. */
110
- createdAt: Date | string | number;
111
- body: ReactNode;
112
- }
113
- /** One row of a {@link FeedbackThread}: a message, or an event line between them. */
114
- type FeedbackThreadItem = FeedbackThreadMessage | FeedbackThreadEvent;
115
- interface FeedbackThreadProps {
116
- /** Oldest first. Event lines ({@link FeedbackThreadEvent}) sit among the messages. */
117
- messages: readonly FeedbackThreadItem[];
118
- loading?: boolean;
119
- /** Replaces the default "No comments yet". */
120
- empty?: ReactNode;
121
- /**
122
- * Draw one attachment yourself — for files behind auth, which a plain `<img src>`
123
- * cannot fetch (kastlan's `AuthedImage`), or a lightbox. The default is a thumbnail
124
- * link for an image with a `url`, a file link otherwise.
125
- */
126
- renderAttachment?: (attachment: FeedbackThreadAttachment, message: FeedbackThreadMessage) => ReactNode;
127
- /** Tag bodies, authors and attachments `data-private`. Default true. */
128
- redact?: boolean;
129
- /**
130
- * How a row's time reads. `"relative"` (default): "5 minutes ago", a date past six
131
- * days — right for a report's comments, read days apart. `"clock"`: the time of day
132
- * in the locale ("14:05", "2:05 PM") — the chat look, keksdose G4; pair it with
133
- * `daySeparators`, which say which day that clock time is on. Either way the full
134
- * date and time is in the Tooltip.
135
- */
136
- timeFormat?: "relative" | "clock";
137
- /**
138
- * A centred day line before the first row and wherever the next row is on another
139
- * calendar day (the device's zone): "Today", "Yesterday", else the date — keksdose
140
- * G4. "Today" / "Yesterday" are `Intl.RelativeTimeFormat`'s own words in the kit
141
- * locale, so there is no label to translate. Default false.
142
- */
143
- daySeparators?: boolean;
144
- /** "Now" for the relative times and the day lines — pin it in tests and stories.
145
- * Default: the clock. */
146
- now?: Date | number;
147
- /** Overrides the provider's locale for the times. */
148
- locale?: string;
149
- labels?: Partial<FeedbackThreadLabels>;
150
- className?: string;
151
- }
152
- declare function FeedbackThread({ messages, loading, empty, renderAttachment, redact, now, locale: localeProp, timeFormat, daySeparators, labels: labelsProp, className, }: FeedbackThreadProps): react.JSX.Element;
153
- /** What the composer's attach control takes — {@link FeedbackNoteAttachment} with the
154
- * labels optional, since the field reads `feedbackAttachment` from the provider. */
155
- type FeedbackComposerAttachment = Omit<FeedbackNoteAttachment, "labels"> & {
156
- labels?: Partial<FeedbackAttachmentLabels>;
157
- };
158
- interface FeedbackComposerProps {
159
- /**
160
- * Send the comment. Return the promise: the box clears when it RESOLVES, and only of
161
- * what was sent — text typed while it was in flight stays. A rejection keeps
162
- * everything for a retry (surface the error yourself; the composer stays quiet).
163
- *
164
- * `attachment` is the built-in field's one picture. Files the host uploaded ahead
165
- * (`attachmentSlot`) are the host's state, read by the host here — and `body` may be
166
- * `""` when `canSend` let an attachments-only message go.
167
- */
168
- onSend: (body: string, attachment: File | null) => void | Promise<unknown>;
169
- /** The send is in flight: a spinner on the button and no second send. */
170
- pending?: boolean;
171
- /** Offer one picture with the comment (file, paste or `onCaptureScreenshot`).
172
- * `true` for the defaults. Left out, the composer is text only. */
173
- attachment?: boolean | FeedbackComposerAttachment;
174
- /**
175
- * The host's own attach control, in the row with Send where the built-in field sits
176
- * (after it, if both are on) — keksdose G5: its support chat uploads up to N files
177
- * AHEAD of the send and sends their refs, which one `File` in `onSend` cannot carry.
178
- * The slot is the host's picker plus the chips of what is uploaded; the upload, the
179
- * refs and clearing them once `onSend` resolves stay with the host. Pair it with
180
- * `canSend`.
181
- */
182
- attachmentSlot?: ReactNode;
183
- /**
184
- * Whether Send is enabled, over the composer's own rule (some text in the box) —
185
- * for state the composer cannot see, i.e. `attachmentSlot`'s (keksdose G5): `true`
186
- * with files ready makes an empty draft sendable (`onSend("", null)`), `false` while
187
- * an upload is still running holds even a written reply back. Left out, the text
188
- * decides. `pending` blocks a send either way.
189
- */
190
- canSend?: boolean;
191
- /**
192
- * Which key sends. `"mod-enter"` (default): Ctrl/⌘+Enter, the report dialog's and
193
- * note editor's shortcut, with plain Enter a new line — feedback is written in
194
- * paragraphs. `"enter"`: the chat way (keksdose G5) — Enter sends, Shift+Enter is a
195
- * new line, Ctrl/⌘+Enter still sends; an Enter that confirms an IME composition
196
- * (Japanese, Chinese input) is the IME's, never a send.
197
- */
198
- sendOn?: "mod-enter" | "enter";
199
- /** Rendered INSTEAD of the composer — the thread is closed, or read-only for this
200
- * reader. */
201
- disabledReason?: ReactNode;
202
- rows?: number;
203
- /**
204
- * The box's hint, over the `placeholder` label — keksdose F9: an admin answering a
205
- * support ticket is asked something else ("Reply to Anna…") than a member adding to
206
- * their own report, and one provider-wide label cannot say both.
207
- */
208
- placeholder?: string;
209
- /**
210
- * The draft, controlled — for a host that keeps it itself (saves it per ticket,
211
- * prefills a template). Left out, the composer keeps its own. Either way a send
212
- * that resolves clears only what was sent: controlled, that is an
213
- * `onValueChange("")` the host receives like any keystroke, and only if the draft
214
- * is still the one that went out.
215
- */
216
- value?: string;
217
- /** Every change to the draft — typing, {@link FeedbackComposerHandle.insertText}, the
218
- * clear after a send. Required to change a controlled `value`. */
219
- onValueChange?: (value: string) => void;
220
- /** {@link FeedbackComposerHandle}: put text into the draft from outside (canned-reply
221
- * chips) or focus the box. */
222
- ref?: Ref<FeedbackComposerHandle>;
223
- labels?: Partial<FeedbackComposerLabels>;
224
- className?: string;
225
- }
226
- /**
227
- * What a {@link FeedbackComposer} `ref` holds.
228
- *
229
- * keksdose F9: the support admin answers the same five questions all day and wants
230
- * chips above the box ("Thanks, fixed in the next release") that drop their text in
231
- * where the caret is. A controlled `value` alone cannot do that well — the host sees
232
- * the string, not the caret, so it could only append — so the composer, which owns
233
- * the textarea, does the splice.
234
- */
235
- interface FeedbackComposerHandle {
236
- /**
237
- * Insert `text` at the caret, replacing any selection (the caret the box last had:
238
- * a click on a chip blurs it, and the selection survives the blur), then focus the
239
- * box with the caret after the inserted text so the reply can go on. Nothing is
240
- * added around it — put a space or a newline in `text` if the reply needs one. A
241
- * no-op while `disabledReason` replaces the box.
242
- */
243
- insertText: (text: string) => void;
244
- focus: () => void;
245
- }
246
- /**
247
- * The answer box under a {@link FeedbackThread}: a textarea, an optional picture,
248
- * and Send — Ctrl/⌘+Enter sends, the shortcut the report dialog and the note editor
249
- * use, so the habit carries across the feature. Plain Enter is a new line: feedback is
250
- * written in paragraphs, unlike a chat — which `sendOn="enter"` is for (keksdose G5).
251
- */
252
- declare function FeedbackComposer({ onSend, pending, attachment, attachmentSlot, canSend: canSendProp, sendOn, disabledReason, rows, placeholder, value, onValueChange, ref, labels: labelsProp, className, }: FeedbackComposerProps): react.JSX.Element;
253
-
254
- export { DEFAULT_FEEDBACK_COMPOSER_LABELS, DEFAULT_FEEDBACK_THREAD_LABELS, FeedbackComposer, type FeedbackComposerAttachment, type FeedbackComposerHandle, type FeedbackComposerLabels, type FeedbackComposerProps, FeedbackThread, type FeedbackThreadAttachment, type FeedbackThreadEvent, type FeedbackThreadItem, type FeedbackThreadLabels, type FeedbackThreadMessage, type FeedbackThreadProps };
16
+ import '../components/field-sync.js';
17
+ import '../wizard/types.js';
18
+ import '../tour/tour.js';
19
+ import '../search/command-palette.js';
20
+ import '../search/global-search.js';
21
+ import '../search/search-index.js';
22
+ import '../components/month-picker.js';
23
+ import '../components/page-contents.js';
24
+ import '../components/series-chart-labels.js';
25
+ import '../components/pie-chart-labels.js';
26
+ import '../components/sparkline.js';
27
+ import '../components/stat-tile.js';
28
+ import '../components/signature-pad.js';
29
+ import '../components/password-strength.js';
30
+ import '../components/swatch-picker.js';
31
+ import '../components/tile-radio.js';
32
+ import '../components/icon-picker.js';
33
+ import '../components/dialog-frame.js';
34
+ import '../components/modal.js';
35
+ import '../hooks/use-search-param-state.js';
36
+ import '../components/measured-grid.js';
37
+ import '../components/account-settings-labels.js';
38
+ import '../components/floating-panel.js';
39
+ import '../components/bulk-action-bar.js';
40
+ import '../components/list.js';
41
+ import '../components/signed-amount.js';
42
+ import '../components/breadcrumbs.js';
43
+ import '../components/toast.js';
44
+ import '../components/description-list.js';
45
+ import '../components/line-items.js';
46
+ import '../components/progress-bar.js';
47
+ import '../components/error-boundary.js';
48
+ import '../components/authed-image.js';
49
+ import '../hooks/use-authed-src.js';
50
+ import '../components/image-grid.js';
51
+ import '../components/lightbox.js';
52
+ import '../components/write-lock.js';
53
+ import '../components/legal.js';
54
+ import '../components/account-chips.js';
55
+ import '../lib/format.js';
56
+ import '../components/reauth-dialog.js';
57
+ import '../components/server-wake.js';
58
+ import '../lib/server-wake.js';
59
+ import '../components/translation-review-labels.js';
60
+ import '../lib/translation-review.js';
61
+ import '../components/country-select.js';
62
+ import '../components/inline-edit-field.js';
63
+ import '../lib/iban.js';
64
+ import '../lib/phone.js';
65
+ import '../components/sign-chip.js';
66
+ import '../components/column-mapper.js';
67
+ import '../lib/column-mapping.js';
68
+ import '../lib/table-text.js';
69
+ import '../components/field-parts.js';
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useEffect, useImperativeHandle, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
3
+ import { useEffect, useId, useImperativeHandle, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { ImageIcon, ImageOff, Paperclip, Send } from "lucide-react";
5
5
  import { cn } from "../lib/cn.js";
6
6
  import { formatDate, formatRelativeTime } from "../lib/format.js";
@@ -237,14 +237,22 @@ function FeedbackComposer({
237
237
  sendOn = "mod-enter",
238
238
  disabledReason,
239
239
  rows = 3,
240
+ maxLength,
241
+ showCount,
242
+ countLabels,
240
243
  placeholder,
241
244
  value,
242
245
  onValueChange,
243
246
  ref,
244
247
  labels: labelsProp,
245
- className
248
+ className,
249
+ id,
250
+ size = "md",
251
+ ...rest
246
252
  }) {
247
253
  const labels = useKitLabels("feedbackComposer", DEFAULT_FEEDBACK_COMPOSER_LABELS, labelsProp);
254
+ const rootAttributes = { id, ...dataAttributes(rest) };
255
+ const hintId = useId();
248
256
  const [ownDraft, setOwnDraft] = useState("");
249
257
  const controlled = value !== void 0;
250
258
  const draft = controlled ? value : ownDraft;
@@ -287,9 +295,10 @@ function FeedbackComposer({
287
295
  () => "Ctrl"
288
296
  );
289
297
  if (disabledReason != null && disabledReason !== false) {
290
- return /* @__PURE__ */ jsx("p", { className: cn("text-xs text-[var(--text-muted)]", className), children: disabledReason });
298
+ return /* @__PURE__ */ jsx("p", { ...rootAttributes, className: cn("text-xs text-[var(--text-muted)]", className), children: disabledReason });
291
299
  }
292
- const canSend = (canSendProp ?? draft.trim().length > 0) && !pending;
300
+ const tooLong = maxLength !== void 0 && draft.length > maxLength;
301
+ const canSend = (canSendProp ?? draft.trim().length > 0) && !pending && !tooLong;
293
302
  const send = () => {
294
303
  if (!canSend) return;
295
304
  const sentDraft = draft;
@@ -301,13 +310,17 @@ function FeedbackComposer({
301
310
  });
302
311
  };
303
312
  const config = attachment === true ? {} : attachment || null;
304
- return /* @__PURE__ */ jsxs("div", { ref: root, className: cn("space-y-2", className), children: [
313
+ return /* @__PURE__ */ jsxs("div", { ...rootAttributes, ref: root, className: cn("space-y-2", className), children: [
305
314
  /* @__PURE__ */ jsx(
306
315
  Textarea,
307
316
  {
308
317
  rows,
309
318
  dir: "auto",
310
319
  "aria-label": labels.field,
320
+ "aria-describedby": size === "sm" ? hintId : void 0,
321
+ maxLength,
322
+ ...showCount !== void 0 ? { showCount } : null,
323
+ countLabels,
311
324
  ref: box,
312
325
  placeholder: placeholder ?? labels.placeholder,
313
326
  value: draft,
@@ -341,16 +354,39 @@ function FeedbackComposer({
341
354
  attachmentSlot
342
355
  ] }) : /* @__PURE__ */ jsx("span", {}),
343
356
  /* @__PURE__ */ jsxs("div", { className: "ms-auto flex items-center gap-2", children: [
344
- /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--text-placeholder)]", children: sendOn === "enter" ? labels.sendHintEnter : labels.sendHint(modifier) }),
345
- /* @__PURE__ */ jsxs(Button, { onClick: send, disabled: !canSend, "aria-busy": pending || void 0, children: [
346
- pending ? /* @__PURE__ */ jsx(Spinner, { label: null, className: "size-4" }) : /* @__PURE__ */ jsx(Send, { className: "size-4 rtl:-scale-x-100", "aria-hidden": true }),
347
- labels.send
348
- ] })
357
+ /* @__PURE__ */ jsx(
358
+ "span",
359
+ {
360
+ id: hintId,
361
+ className: size === "sm" ? "sr-only" : "text-xs text-[var(--text-placeholder)]",
362
+ children: sendOn === "enter" ? labels.sendHintEnter : labels.sendHint(modifier)
363
+ }
364
+ ),
365
+ /* @__PURE__ */ jsxs(
366
+ Button,
367
+ {
368
+ onClick: send,
369
+ disabled: !canSend,
370
+ "aria-busy": pending || void 0,
371
+ size: size === "sm" ? "sm" : void 0,
372
+ children: [
373
+ pending ? /* @__PURE__ */ jsx(Spinner, { label: null, className: "size-4" }) : /* @__PURE__ */ jsx(Send, { className: "size-4 rtl:-scale-x-100", "aria-hidden": true }),
374
+ labels.send
375
+ ]
376
+ }
377
+ )
349
378
  ] })
350
379
  ] })
351
380
  ] });
352
381
  }
382
+ function dataAttributes(props) {
383
+ const out = {};
384
+ for (const [key, value] of Object.entries(props)) if (key.startsWith("data-")) out[key] = value;
385
+ return out;
386
+ }
387
+ const ChatComposer = FeedbackComposer;
353
388
  export {
389
+ ChatComposer,
354
390
  DEFAULT_FEEDBACK_COMPOSER_LABELS,
355
391
  DEFAULT_FEEDBACK_THREAD_LABELS,
356
392
  FeedbackComposer,