@eifi1/ui-kit 0.29.0 → 0.31.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 (307) hide show
  1. package/README.md +65 -6
  2. package/dist/account/account-parts.d.ts +21 -0
  3. package/dist/account/account-parts.js +40 -0
  4. package/dist/account/account-parts.js.map +1 -0
  5. package/dist/account/data-export-setting.d.ts +73 -0
  6. package/dist/account/data-export-setting.js +114 -0
  7. package/dist/account/data-export-setting.js.map +1 -0
  8. package/dist/account/delete-account-setting.d.ts +95 -0
  9. package/dist/account/delete-account-setting.js +200 -0
  10. package/dist/account/delete-account-setting.js.map +1 -0
  11. package/dist/account/email-change-setting.d.ts +136 -0
  12. package/dist/account/email-change-setting.js +278 -0
  13. package/dist/account/email-change-setting.js.map +1 -0
  14. package/dist/account/sessions-setting.d.ts +110 -0
  15. package/dist/account/sessions-setting.js +147 -0
  16. package/dist/account/sessions-setting.js.map +1 -0
  17. package/dist/admin/admin-action-confirm.d.ts +95 -0
  18. package/dist/admin/admin-action-confirm.js +276 -0
  19. package/dist/admin/admin-action-confirm.js.map +1 -0
  20. package/dist/admin/admin-action-log.d.ts +105 -0
  21. package/dist/admin/admin-action-log.js +153 -0
  22. package/dist/admin/admin-action-log.js.map +1 -0
  23. package/dist/admin/admin-parts.d.ts +40 -0
  24. package/dist/admin/admin-parts.js +45 -0
  25. package/dist/admin/admin-parts.js.map +1 -0
  26. package/dist/admin/invitations-panel.d.ts +95 -0
  27. package/dist/admin/invitations-panel.js +290 -0
  28. package/dist/admin/invitations-panel.js.map +1 -0
  29. package/dist/admin/reviewer-scope-editor.d.ts +95 -0
  30. package/dist/admin/reviewer-scope-editor.js +134 -0
  31. package/dist/admin/reviewer-scope-editor.js.map +1 -0
  32. package/dist/admin/role-select.d.ts +95 -0
  33. package/dist/admin/role-select.js +128 -0
  34. package/dist/admin/role-select.js.map +1 -0
  35. package/dist/admin/transfer-ownership-dialog.d.ts +95 -0
  36. package/dist/admin/transfer-ownership-dialog.js +83 -0
  37. package/dist/admin/transfer-ownership-dialog.js.map +1 -0
  38. package/dist/admin/user-roster.d.ts +95 -0
  39. package/dist/admin/user-roster.js +285 -0
  40. package/dist/admin/user-roster.js.map +1 -0
  41. package/dist/auth/auth-errors.d.ts +103 -6
  42. package/dist/auth/auth-errors.js +68 -2
  43. package/dist/auth/auth-errors.js.map +1 -1
  44. package/dist/auth/forgot-password-form.d.ts +10 -3
  45. package/dist/auth/forgot-password-form.js +6 -3
  46. package/dist/auth/forgot-password-form.js.map +1 -1
  47. package/dist/auth/register-form.d.ts +21 -12
  48. package/dist/auth/register-form.js +6 -4
  49. package/dist/auth/register-form.js.map +1 -1
  50. package/dist/auth/reset-password-form.d.ts +10 -3
  51. package/dist/auth/reset-password-form.js +6 -3
  52. package/dist/auth/reset-password-form.js.map +1 -1
  53. package/dist/auth/sign-in-form.d.ts +75 -9
  54. package/dist/auth/sign-in-form.js +105 -15
  55. package/dist/auth/sign-in-form.js.map +1 -1
  56. package/dist/auth/verify-email.d.ts +7 -2
  57. package/dist/auth/verify-email.js +44 -8
  58. package/dist/auth/verify-email.js.map +1 -1
  59. package/dist/chart.d.ts +20 -11
  60. package/dist/components/account-chips.d.ts +47 -7
  61. package/dist/components/account-chips.js +19 -3
  62. package/dist/components/account-chips.js.map +1 -1
  63. package/dist/components/account-settings-labels.d.ts +24 -1
  64. package/dist/components/account-settings-labels.js +6 -2
  65. package/dist/components/account-settings-labels.js.map +1 -1
  66. package/dist/components/account-settings.d.ts +69 -8
  67. package/dist/components/account-settings.js +133 -25
  68. package/dist/components/account-settings.js.map +1 -1
  69. package/dist/components/amount-input.d.ts +21 -12
  70. package/dist/components/button-group.d.ts +21 -12
  71. package/dist/components/calculator.d.ts +21 -12
  72. package/dist/components/confirm-dialog.d.ts +21 -12
  73. package/dist/components/copy-button.d.ts +18 -9
  74. package/dist/components/danger-confirm.d.ts +21 -12
  75. package/dist/components/data-table.js +8 -1
  76. package/dist/components/data-table.js.map +1 -1
  77. package/dist/components/date-picker.js +9 -4
  78. package/dist/components/date-picker.js.map +1 -1
  79. package/dist/components/facing-pair.d.ts +21 -12
  80. package/dist/components/file-button.d.ts +21 -12
  81. package/dist/components/file-dropzone.d.ts +21 -12
  82. package/dist/components/form-actions.d.ts +21 -12
  83. package/dist/components/iban-input.d.ts +21 -12
  84. package/dist/components/language-select.d.ts +21 -12
  85. package/dist/components/legal-page.d.ts +21 -12
  86. package/dist/components/legal.d.ts +21 -12
  87. package/dist/components/money-field.d.ts +21 -12
  88. package/dist/components/number-field.d.ts +21 -12
  89. package/dist/components/number-input.d.ts +21 -12
  90. package/dist/components/numpad-sheet.d.ts +21 -12
  91. package/dist/components/passkeys-setting.js +2 -1
  92. package/dist/components/passkeys-setting.js.map +1 -1
  93. package/dist/components/phone-input.d.ts +21 -12
  94. package/dist/components/series-chart.d.ts +21 -12
  95. package/dist/components/settings-fields.d.ts +55 -13
  96. package/dist/components/settings-fields.js +20 -1
  97. package/dist/components/settings-fields.js.map +1 -1
  98. package/dist/components/share-card.d.ts +20 -11
  99. package/dist/components/text-link.d.ts +21 -12
  100. package/dist/components/time-input.d.ts +21 -12
  101. package/dist/components/ui.d.ts +17 -8
  102. package/dist/{register-form-V1OeNlMr.d.ts → delete-account-setting-DCFS5Vof.d.ts} +6612 -5612
  103. package/dist/demo/demo-banner.d.ts +51 -0
  104. package/dist/demo/demo-banner.js +97 -0
  105. package/dist/demo/demo-banner.js.map +1 -0
  106. package/dist/demo/demo-countdown.d.ts +58 -0
  107. package/dist/demo/demo-countdown.js +79 -0
  108. package/dist/demo/demo-countdown.js.map +1 -0
  109. package/dist/demo/demo-ended.d.ts +45 -0
  110. package/dist/demo/demo-ended.js +42 -0
  111. package/dist/demo/demo-ended.js.map +1 -0
  112. package/dist/demo/demo-labels.d.ts +53 -0
  113. package/dist/demo/demo-labels.js +29 -0
  114. package/dist/demo/demo-labels.js.map +1 -0
  115. package/dist/demo/demo-session.d.ts +30 -0
  116. package/dist/demo/demo-session.js +8 -0
  117. package/dist/demo/demo-session.js.map +1 -0
  118. package/dist/demo/demo-start.d.ts +54 -0
  119. package/dist/demo/demo-start.js +68 -0
  120. package/dist/demo/demo-start.js.map +1 -0
  121. package/dist/feedback/feedback-attachment.d.ts +21 -12
  122. package/dist/feedback/feedback-context.d.ts +21 -12
  123. package/dist/feedback/feedback-crash.d.ts +21 -12
  124. package/dist/feedback/feedback-dialog.d.ts +21 -12
  125. package/dist/feedback/feedback-inbox.d.ts +21 -12
  126. package/dist/feedback/feedback-inbox.js +12 -2
  127. package/dist/feedback/feedback-inbox.js.map +1 -1
  128. package/dist/feedback/feedback-labels.d.ts +21 -12
  129. package/dist/feedback/feedback-labels.js +1 -0
  130. package/dist/feedback/feedback-labels.js.map +1 -1
  131. package/dist/feedback/feedback-menu.d.ts +21 -12
  132. package/dist/feedback/feedback-record.d.ts +21 -12
  133. package/dist/feedback/feedback-record.js +2 -0
  134. package/dist/feedback/feedback-record.js.map +1 -1
  135. package/dist/feedback/feedback-row-detail.d.ts +21 -12
  136. package/dist/feedback/feedback-row-detail.js +7 -0
  137. package/dist/feedback/feedback-row-detail.js.map +1 -1
  138. package/dist/feedback/feedback-status-undo.d.ts +21 -12
  139. package/dist/feedback/feedback-submit.d.ts +21 -12
  140. package/dist/feedback/feedback-swipe.d.ts +22 -13
  141. package/dist/feedback/feedback-swipe.js.map +1 -1
  142. package/dist/feedback/feedback-table.d.ts +18 -9
  143. package/dist/feedback/feedback-thread.d.ts +21 -12
  144. package/dist/feedback.d.ts +21 -12
  145. package/dist/hooks/use-anchored-panel.d.ts +6 -2
  146. package/dist/hooks/use-anchored-panel.js +2 -1
  147. package/dist/hooks/use-anchored-panel.js.map +1 -1
  148. package/dist/hooks/use-file-drop.d.ts +21 -12
  149. package/dist/i18n/defaults.d.ts +21 -12
  150. package/dist/i18n/defaults.js +28 -0
  151. package/dist/i18n/defaults.js.map +1 -1
  152. package/dist/i18n/german.d.ts +21 -12
  153. package/dist/i18n/german.js +298 -12
  154. package/dist/i18n/german.js.map +1 -1
  155. package/dist/i18n/kit-labels.d.ts +14 -5
  156. package/dist/i18n/kit-labels.js.map +1 -1
  157. package/dist/i18n/languages.d.ts +15 -6
  158. package/dist/i18n/locales/de-CH.d.ts +21 -12
  159. package/dist/i18n/locales/en.d.ts +21 -12
  160. package/dist/i18n/locales/es.d.ts +21 -12
  161. package/dist/i18n/locales/es.js +287 -10
  162. package/dist/i18n/locales/es.js.map +1 -1
  163. package/dist/i18n/locales/fr.d.ts +21 -12
  164. package/dist/i18n/locales/fr.js +290 -7
  165. package/dist/i18n/locales/fr.js.map +1 -1
  166. package/dist/i18n/locales/hu.d.ts +21 -12
  167. package/dist/i18n/locales/hu.js +288 -12
  168. package/dist/i18n/locales/hu.js.map +1 -1
  169. package/dist/i18n/locales/it.d.ts +21 -12
  170. package/dist/i18n/locales/it.js +289 -7
  171. package/dist/i18n/locales/it.js.map +1 -1
  172. package/dist/i18n/locales/zh.d.ts +21 -12
  173. package/dist/i18n/locales/zh.js +279 -7
  174. package/dist/i18n/locales/zh.js.map +1 -1
  175. package/dist/i18n/review.d.ts +21 -12
  176. package/dist/i18n/review.js +50 -1
  177. package/dist/i18n/review.js.map +1 -1
  178. package/dist/index.d.ts +31 -4
  179. package/dist/index.js +148 -0
  180. package/dist/index.js.map +1 -1
  181. package/dist/landing/access.d.ts +48 -0
  182. package/dist/landing/access.js +38 -0
  183. package/dist/landing/access.js.map +1 -0
  184. package/dist/landing/landing-actions.d.ts +138 -0
  185. package/dist/landing/landing-actions.js +39 -0
  186. package/dist/landing/landing-actions.js.map +1 -0
  187. package/dist/landing/landing-labels.d.ts +43 -0
  188. package/dist/landing/landing-labels.js +23 -0
  189. package/dist/landing/landing-labels.js.map +1 -0
  190. package/dist/landing/landing-sections.d.ts +218 -0
  191. package/dist/landing/landing-sections.js +167 -0
  192. package/dist/landing/landing-sections.js.map +1 -0
  193. package/dist/landing/page-seo.d.ts +99 -0
  194. package/dist/landing/page-seo.js +121 -0
  195. package/dist/landing/page-seo.js.map +1 -0
  196. package/dist/landing/public-header.d.ts +148 -0
  197. package/dist/landing/public-header.js +49 -0
  198. package/dist/landing/public-header.js.map +1 -0
  199. package/dist/landing/routing.d.ts +218 -0
  200. package/dist/landing/routing.js +81 -0
  201. package/dist/landing/routing.js.map +1 -0
  202. package/dist/rhf/fields.d.ts +21 -12
  203. package/dist/rhf/form.d.ts +21 -12
  204. package/dist/rhf.d.ts +21 -12
  205. package/dist/settings/settings-catalogue.d.ts +84 -0
  206. package/dist/settings/settings-catalogue.js +47 -0
  207. package/dist/settings/settings-catalogue.js.map +1 -0
  208. package/dist/settings/settings-context.d.ts +31 -0
  209. package/dist/settings/settings-context.js +11 -0
  210. package/dist/settings/settings-context.js.map +1 -0
  211. package/dist/settings/settings-heading.d.ts +50 -0
  212. package/dist/settings/settings-heading.js +27 -0
  213. package/dist/settings/settings-heading.js.map +1 -0
  214. package/dist/settings/settings-labels.d.ts +41 -0
  215. package/dist/settings/settings-labels.js +38 -0
  216. package/dist/settings/settings-labels.js.map +1 -0
  217. package/dist/settings/settings-layout.d.ts +77 -0
  218. package/dist/settings/settings-layout.js +242 -0
  219. package/dist/settings/settings-layout.js.map +1 -0
  220. package/dist/settings/settings-section.d.ts +133 -0
  221. package/dist/settings/settings-section.js +63 -0
  222. package/dist/settings/settings-section.js.map +1 -0
  223. package/dist/settings/use-account-language.d.ts +83 -0
  224. package/dist/settings/use-account-language.js +62 -0
  225. package/dist/settings/use-account-language.js.map +1 -0
  226. package/dist/settings/use-settings-focus.d.ts +34 -0
  227. package/dist/settings/use-settings-focus.js +77 -0
  228. package/dist/settings/use-settings-focus.js.map +1 -0
  229. package/dist/settings/use-settings-route.d.ts +118 -0
  230. package/dist/settings/use-settings-route.js +120 -0
  231. package/dist/settings/use-settings-route.js.map +1 -0
  232. package/dist/shell/app-shell.d.ts +27 -12
  233. package/dist/shell/app-shell.js +3 -2
  234. package/dist/shell/app-shell.js.map +1 -1
  235. package/dist/shell/top-bar-brand.d.ts +21 -12
  236. package/dist/shell.d.ts +25 -6
  237. package/dist/shell.js +56 -0
  238. package/dist/shell.js.map +1 -1
  239. package/dist/wizard/stepper-nav.d.ts +21 -12
  240. package/dist/wizard.d.ts +21 -12
  241. package/package.json +2 -1
  242. package/src/account/account-parts.ts +67 -0
  243. package/src/account/data-export-setting.tsx +219 -0
  244. package/src/account/delete-account-setting.tsx +363 -0
  245. package/src/account/email-change-setting.tsx +454 -0
  246. package/src/account/sessions-setting.tsx +284 -0
  247. package/src/admin/admin-action-confirm.tsx +495 -0
  248. package/src/admin/admin-action-log.tsx +297 -0
  249. package/src/admin/admin-parts.ts +82 -0
  250. package/src/admin/invitations-panel.tsx +523 -0
  251. package/src/admin/reviewer-scope-editor.tsx +234 -0
  252. package/src/admin/role-select.tsx +286 -0
  253. package/src/admin/transfer-ownership-dialog.tsx +172 -0
  254. package/src/admin/user-roster.tsx +573 -0
  255. package/src/auth/auth-errors.ts +196 -8
  256. package/src/auth/forgot-password-form.tsx +21 -5
  257. package/src/auth/register-form.tsx +24 -6
  258. package/src/auth/reset-password-form.tsx +19 -5
  259. package/src/auth/sign-in-form.tsx +241 -38
  260. package/src/auth/verify-email.tsx +59 -8
  261. package/src/components/account-chips.tsx +64 -7
  262. package/src/components/account-settings-labels.ts +28 -1
  263. package/src/components/account-settings.tsx +231 -34
  264. package/src/components/data-table.tsx +8 -0
  265. package/src/components/date-picker.tsx +9 -4
  266. package/src/components/passkeys-setting.tsx +2 -1
  267. package/src/components/settings-fields.tsx +50 -1
  268. package/src/demo/demo-banner.tsx +159 -0
  269. package/src/demo/demo-countdown.ts +141 -0
  270. package/src/demo/demo-ended.tsx +89 -0
  271. package/src/demo/demo-labels.ts +78 -0
  272. package/src/demo/demo-session.ts +32 -0
  273. package/src/demo/demo-start.tsx +150 -0
  274. package/src/feedback/feedback-inbox.tsx +21 -8
  275. package/src/feedback/feedback-labels.ts +2 -1
  276. package/src/feedback/feedback-record.ts +10 -7
  277. package/src/feedback/feedback-row-detail.tsx +28 -4
  278. package/src/feedback/feedback-swipe.tsx +1 -1
  279. package/src/hooks/use-anchored-panel.ts +14 -3
  280. package/src/i18n/defaults.ts +28 -0
  281. package/src/i18n/german.ts +327 -5
  282. package/src/i18n/kit-labels.tsx +42 -0
  283. package/src/i18n/locales/es.ts +313 -3
  284. package/src/i18n/locales/fr.ts +316 -0
  285. package/src/i18n/locales/hu.ts +308 -5
  286. package/src/i18n/locales/it.ts +313 -0
  287. package/src/i18n/locales/zh.ts +286 -0
  288. package/src/i18n/review.ts +49 -0
  289. package/src/index.ts +184 -0
  290. package/src/landing/access.ts +97 -0
  291. package/src/landing/landing-actions.tsx +92 -0
  292. package/src/landing/landing-labels.ts +59 -0
  293. package/src/landing/landing-sections.tsx +337 -0
  294. package/src/landing/page-seo.ts +251 -0
  295. package/src/landing/public-header.tsx +120 -0
  296. package/src/landing/routing.tsx +209 -0
  297. package/src/settings/settings-catalogue.ts +132 -0
  298. package/src/settings/settings-context.ts +33 -0
  299. package/src/settings/settings-heading.tsx +65 -0
  300. package/src/settings/settings-labels.ts +75 -0
  301. package/src/settings/settings-layout.tsx +379 -0
  302. package/src/settings/settings-section.tsx +108 -0
  303. package/src/settings/use-account-language.ts +146 -0
  304. package/src/settings/use-settings-focus.ts +120 -0
  305. package/src/settings/use-settings-route.ts +258 -0
  306. package/src/shell/app-shell.tsx +10 -2
  307. package/src/shell.ts +45 -0
package/README.md CHANGED
@@ -382,16 +382,16 @@ columns, strings and permissions (see the note at the top of `src/feedback/feedb
382
382
 
383
383
  <!-- BEGIN GENERATED: exports — node scripts/gen-export-inventory.mjs -->
384
384
 
385
- **1478 names from 219 modules** — 692 values and 786 types. _Italic_ is a type-only export.
385
+ **1688 names from 253 modules** — 778 values and 910 types. _Italic_ is a type-only export.
386
386
 
387
387
  Generated from `dist/index.d.ts` by `node scripts/gen-export-inventory.mjs`; the count
388
388
  is pinned by `src/__tests__/public-surface.test.ts`. Do not edit between the markers.
389
389
 
390
390
  | Entry point | Names |
391
391
  |---|---|
392
- | `@eifi1/ui-kit` | 1478 |
392
+ | `@eifi1/ui-kit` | 1688 |
393
393
  | `@eifi1/ui-kit/chart` | 104 |
394
- | `@eifi1/ui-kit/shell` | 24 |
394
+ | `@eifi1/ui-kit/shell` | 71 |
395
395
  | `@eifi1/ui-kit/data-table` | 51 |
396
396
  | `@eifi1/ui-kit/wizard` | 25 |
397
397
  | `@eifi1/ui-kit/tour` | 7 |
@@ -458,6 +458,19 @@ re-slicing of it, never a second API.
458
458
  | `theme/theme-store` | `applyPersistedTheme`, `createThemeStore`, _`ThemeMode`_, _`ThemePreference`_, _`ThemeState`_, _`ThemeStore`_ |
459
459
  | `theme/palette-store` | `applyPersistedPalette`, `createPaletteStore`, _`PaletteStore`_ |
460
460
 
461
+ ### admin
462
+
463
+ | Module | Exports |
464
+ |---|---|
465
+ | `admin/admin-action-confirm` | `AdminActionConfirm`, `DEFAULT_ADMIN_ACTION_LABELS`, _`AdminActionConfirmProps`_, _`AdminActionConfirmValues`_, _`AdminActionLabels`_, _`AdminActionTarget`_, _`AdminConfirmLevel`_ |
466
+ | `admin/user-roster` | `adminUserStates`, `DEFAULT_USER_ROSTER_LABELS`, `USER_ROSTER_SORT_KEYS`, `UserIdentityCell`, `userRosterColumns`, `userRosterSort`, `UserRowActions`, `useUserRosterColumns`, _`AdminUserStateFields`_, _`RoleEditing`_, _`RosterState`_, _`UserIdentityCellProps`_, _`UserRosterColumnsOptions`_, _`UserRosterLabels`_, _`UserRosterRow`_, _`UserRosterSortKey`_, _`UserRowAction`_, _`UserRowActionList`_, _`UserRowActionsProps`_ |
467
+ | `admin/invitations-panel` | `DEFAULT_INVITATIONS_LABELS`, `InvitationsPanel`, _`InvitationDraft`_, _`InvitationRow`_, _`InvitationScope`_, _`InvitationSentAnswer`_, _`InvitationsLabels`_, _`InvitationsPanelProps`_, _`InvitationStatus`_ |
468
+ | `admin/reviewer-scope-editor` | `DEFAULT_REVIEWER_SCOPE_LABELS`, `ReviewerScopeEditor`, _`ReviewerScope`_, _`ReviewerScopeArea`_, _`ReviewerScopeEditorProps`_, _`ReviewerScopeLabels`_, _`ReviewerScopeLanguage`_ |
469
+ | `admin/role-select` | `DEFAULT_ROLE_SELECT_LABELS`, `RolesEditor`, `RoleSelect`, _`RoleLock`_, _`RoleLockCode`_, _`RolesEditorProps`_, _`RoleSelectLabels`_, _`RoleSelectProps`_ |
470
+ | `admin/transfer-ownership-dialog` | `DEFAULT_TRANSFER_OWNERSHIP_LABELS`, `TransferOwnershipDialog`, _`TransferCandidate`_, _`TransferOwnershipDialogProps`_, _`TransferOwnershipLabels`_, _`TransferUnavailable`_, _`TransferValues`_ |
471
+ | `admin/admin-action-log` | `ADMIN_ACTION_KINDS`, `AdminActionLog`, `DEFAULT_ADMIN_ACTION_LOG_LABELS`, _`AdminActionKind`_, _`AdminActionLogEntry`_, _`AdminActionLogLabels`_, _`AdminActionLogPaging`_, _`AdminActionLogProps`_ |
472
+ | `admin/admin-parts` | _`AdminPerson`_ |
473
+
461
474
  ### i18n
462
475
 
463
476
  | Module | Exports |
@@ -500,7 +513,7 @@ re-slicing of it, never a second API.
500
513
  | `components/multi-select` | `MultiSelect`, _`MultiSelectOption`_, _`MultiSelectProps`_ |
501
514
  | `components/tooltip` | `placeTooltip`, `Tooltip`, _`TooltipPlacement`_, _`TooltipProps`_, _`TooltipSide`_, _`TooltipSize`_, _`TooltipTap`_, _`TooltipViewport`_ |
502
515
  | `components/user-avatar` | `avatarInitials`, `UserAvatar`, _`UserAvatarBadge`_, _`UserAvatarProps`_ |
503
- | `components/settings-fields` | `LanguageSetting`, `ThemeSetting`, _`LanguageSettingProps`_, _`ThemeSettingProps`_ |
516
+ | `components/settings-fields` | `LanguageSetting`, `ThemeSetting`, _`LanguageSettingProps`_, _`ThemeSettingProps`_, _`ThemeSettingToggleProps`_ |
504
517
  | `components/field-sync` | `DEFAULT_FIELD_SYNC_LABELS`, `FIELD_SYNC_FRAME`, `FIELD_SYNC_SAVED_MS`, `FieldSyncIndicator`, `FieldSyncRow`, `resolveFieldSyncLabels`, `useFieldSync`, _`FieldSyncIndicatorProps`_, _`FieldSyncLabels`_, _`FieldSyncRowProps`_, _`FieldSyncState`_, _`UseFieldSyncOptions`_, _`UseFieldSyncReturn`_ |
505
518
  | `components/month-picker` | `DEFAULT_MONTH_PICKER_LABELS`, `MonthPicker`, _`MonthPickerLabels`_, _`MonthPickerProps`_ |
506
519
  | `components/checkbox` | `Checkbox`, _`CheckboxProps`_ |
@@ -531,7 +544,7 @@ re-slicing of it, never a second API.
531
544
  | `components/series-chart-labels` | `DEFAULT_SERIES_CHART_LABELS`, _`SeriesChartLabels`_ |
532
545
  | `components/pie-chart` | `PieChart`, _`PieChartProps`_, _`PieChartSlice`_ |
533
546
  | `components/pie-chart-labels` | `DEFAULT_PIE_CHART_LABELS`, _`PieChartLabels`_ |
534
- | `components/account-settings` | `PasswordSetting`, `ProfileSetting`, `TwoFactorSetting`, _`PasswordSettingStrength`_, _`TwoFactorSetupData`_ |
547
+ | `components/account-settings` | `PasswordSetting`, `ProfileSetting`, `TwoFactorSetting`, _`PasswordSettingStrength`_, _`ProfileNameValues`_, _`ProfileSettingDisplayNameProps`_, _`ProfileSettingNamesProps`_, _`ProfileSettingProps`_, _`TwoFactorSetupData`_ |
535
548
  | `components/passkeys-setting` | `PasskeysSetting`, _`PasskeyDataAttributes`_, _`PasskeyId`_, _`PasskeyItem`_, _`PasskeysSettingProps`_ |
536
549
  | `components/qr-code` | `QrCode`, _`QrCodeProps`_ |
537
550
  | `components/alert-banner` | `AlertBanner`, `alertFrameClass`, `toneFrameClass`, _`AlertBannerProps`_, _`AlertSize`_, _`AlertTone`_ |
@@ -622,6 +635,15 @@ re-slicing of it, never a second API.
622
635
  | `feedback/feedback-submit` | `useFeedbackSubmit`, _`FeedbackCreatePayload`_, _`FeedbackSubmit`_, _`UseFeedbackSubmitOptions`_ |
623
636
  | `feedback/feedback-crash` | `createCrashReporter`, _`CrashFiling`_, _`CrashReportCreate`_, _`CrashReporter`_, _`CrashReporterOptions`_, _`CrashReportResponse`_ |
624
637
 
638
+ ### account
639
+
640
+ | Module | Exports |
641
+ |---|---|
642
+ | `account/delete-account-setting` | `DEFAULT_DELETE_ACCOUNT_LABELS`, `DeleteAccountSetting`, _`DeleteAccountConsequence`_, _`DeleteAccountLabels`_, _`DeleteAccountSettingProps`_, _`DeleteAccountValues`_, _`DeletionMode`_ |
643
+ | `account/email-change-setting` | `DEFAULT_EMAIL_CHANGE_LABELS`, `EmailChangeSetting`, _`EmailChangeAction`_, _`EmailChangeLabels`_, _`EmailChangeSettingProps`_, _`EmailChangeValues`_ |
644
+ | `account/sessions-setting` | `DEFAULT_SESSIONS_LABELS`, `SessionsSetting`, _`SessionId`_, _`SessionItem`_, _`SessionsAction`_, _`SessionsLabels`_, _`SessionsSettingProps`_ |
645
+ | `account/data-export-setting` | `DataExportSetting`, `DEFAULT_DATA_EXPORT_LABELS`, _`DataExportFile`_, _`DataExportLabels`_, _`DataExportSettingProps`_ |
646
+
625
647
  ### auth
626
648
 
627
649
  | Module | Exports |
@@ -630,7 +652,7 @@ re-slicing of it, never a second API.
630
652
  | `auth/sign-in-form` | `DEFAULT_SIGN_IN_LABELS`, `SignInForm`, _`SignInAction`_, _`SignInAnswer`_, _`SignInCodeValues`_, _`SignInCredentials`_, _`SignInFormProps`_, _`SignInLabels`_, _`SignInNewPasswordValues`_, _`SignInStep`_ |
631
653
  | `auth/complete-name-dialog` | `CompleteNameDialog`, `DEFAULT_COMPLETE_NAME_LABELS`, _`CompleteNameDialogProps`_, _`CompleteNameLabels`_, _`CompleteNameValues`_ |
632
654
  | `auth/email-tag` | `taggedEmail` |
633
- | `auth/auth-errors` | `authErrorCode`, `isAuthError`, _`AuthErrorCode`_ |
655
+ | `auth/auth-errors` | `authErrorCode`, `isAuthError`, `isRateLimited`, `retryAfterSeconds`, _`AccountErrorCode`_, _`AuthErrorCode`_, _`DemoErrorCode`_, _`KitErrorCode`_ |
634
656
  | `auth/forgot-password-form` | `DEFAULT_FORGOT_PASSWORD_LABELS`, `ForgotPasswordForm`, _`ForgotPasswordFormProps`_, _`ForgotPasswordLabels`_ |
635
657
  | `auth/reset-password-form` | `DEFAULT_RESET_PASSWORD_LABELS`, `ResetPasswordForm`, _`ResetPasswordCheck`_, _`ResetPasswordFormProps`_, _`ResetPasswordLabels`_, _`ResetPasswordResult`_, _`ResetPasswordValues`_ |
636
658
  | `auth/verify-email` | `DEFAULT_VERIFY_EMAIL_LABELS`, `EmailVerificationBanner`, `VerifyEmailStatus`, _`EmailVerificationBannerProps`_, _`VerifyEmailFailure`_, _`VerifyEmailLabels`_, _`VerifyEmailStatusProps`_ |
@@ -678,6 +700,43 @@ re-slicing of it, never a second API.
678
700
  | `search/search-index` | `createSearchIndex`, `matchEntries`, `normalizeSearchText`, `SEARCH_TIER_POINTS`, _`SearchEntry`_, _`SearchHit`_, _`SearchIndex`_, _`SearchIndexOptions`_, _`SearchMatchField`_ |
679
701
  | `search/global-search` | `DEFAULT_GLOBAL_SEARCH_LABELS`, `GlobalSearch`, _`GlobalSearchLabels`_, _`GlobalSearchProps`_, _`GlobalSearchSource`_, _`GlobalSearchSourceGroup`_, _`GlobalSearchSuggestion`_, _`GlobalSearchTriggerProps`_ |
680
702
 
703
+ ### settings
704
+
705
+ | Module | Exports |
706
+ |---|---|
707
+ | `settings/settings-layout` | `SETTINGS_SEARCH_THRESHOLD`, `SettingsLayout`, _`SettingsLayoutProps`_, _`SettingsLayoutWidth`_ |
708
+ | `settings/use-settings-route` | `resolveSettingsLocation`, `SETTINGS_FROM_LIST_STATE`, `settingsFromListState`, `useSettingsRoute`, _`SettingsLayoutMode`_, _`SettingsLocation`_, _`SettingsLocationResult`_, _`SettingsLocationRules`_, _`SettingsRoute`_, _`UseSettingsRouteOptions`_ |
709
+ | `settings/use-settings-focus` | `SETTINGS_FOCUS_MS`, `SETTINGS_FOCUS_RING`, `useSettingsFocus` |
710
+ | `settings/settings-section` | `SettingsSection`, _`SettingsSectionProps`_ |
711
+ | `settings/settings-context` | `useSettingsLayout`, _`SettingsLayoutContextValue`_ |
712
+ | `settings/settings-heading` | `SettingsHeadingLevel`, `useSettingsHeadingLevel`, _`SettingsHeadingLevelProps`_, _`SettingsHeadingTag`_ |
713
+ | `settings/settings-catalogue` | `settingsHref`, `settingsSearchEntries`, `visibleSettingsEntries`, `visibleSettingsGroups`, _`SettingsEntry`_, _`SettingsGroup`_, _`SettingsSearchEntriesOptions`_ |
714
+ | `settings/settings-labels` | `DEFAULT_SETTINGS_LABELS`, _`SettingsCoreGroup`_, _`SettingsGroupLabels`_, _`SettingsLabels`_ |
715
+ | `settings/use-account-language` | `matchOfferedLanguage`, `resolveAccountLanguage`, `useAccountLanguage`, _`AccountLanguage`_, _`AccountLanguageSource`_, _`ResolveAccountLanguageInput`_, _`ResolvedAccountLanguage`_, _`UseAccountLanguageOptions`_ |
716
+
717
+ ### landing
718
+
719
+ | Module | Exports |
720
+ |---|---|
721
+ | `landing/landing-labels` | `DEFAULT_LANDING_LABELS`, `useLandingLabels`, _`LandingLabels`_ |
722
+ | `landing/access` | `accessAction`, `useAccessAction`, _`AccessChoice`_, _`AccessLabels`_, _`AccessLink`_ |
723
+ | `landing/landing-actions` | `LandingActions`, _`LandingActionsProps`_, _`LandingSession`_ |
724
+ | `landing/landing-sections` | `CtaBand`, `FeatureRow`, `FeatureRows`, `Hero`, `PublicFooter`, `TrustStrip`, _`CtaBandProps`_, _`FeatureRowProps`_, _`FeatureRowsProps`_, _`HeroProps`_, _`PublicFooterProps`_, _`TrustItem`_, _`TrustStripProps`_ |
725
+ | `landing/page-seo` | `metaContent`, `seoCopyProblems`, `usePageSeo`, _`SeoCopy`_, _`SeoCopyLimits`_, _`SeoCopyProblem`_, _`SeoCopyProblemCode`_ |
726
+ | `landing/routing` | `clearLastVisitedPage`, `DEFAULT_LAST_VISITED_EXCLUDES`, `NEXT_PARAM`, `readLastVisitedPage`, `RedirectIfAuthed`, `RootEntry`, `safeNextPath`, `useLastVisitedPage`, _`LastVisitedPageOptions`_, _`PathPattern`_, _`RedirectIfAuthedProps`_, _`RootEntryProps`_ |
727
+ | `landing/public-header` | `PublicHeader`, _`PublicHeaderBrand`_, _`PublicHeaderProps`_ |
728
+
729
+ ### demo
730
+
731
+ | Module | Exports |
732
+ |---|---|
733
+ | `demo/demo-labels` | `DEFAULT_DEMO_LABELS`, `useDemoLabels`, _`DemoLabels`_ |
734
+ | `demo/demo-session` | `isDemoSession`, _`DemoModel`_, _`DemoSessionUser`_ |
735
+ | `demo/demo-countdown` | `DEMO_MINUTES_ONLY`, `DEMO_WARNING_MINUTES`, `demoCountdown`, `useDemoCountdown`, _`DemoCountdown`_, _`DemoCountdownOptions`_, _`DemoExpiry`_ |
736
+ | `demo/demo-start` | `DemoStart`, _`DemoStartProps`_ |
737
+ | `demo/demo-banner` | `DemoBanner`, _`DemoBannerProps`_ |
738
+ | `demo/demo-ended` | `DemoEnded`, _`DemoEndedProps`_ |
739
+
681
740
  <!-- END GENERATED: exports -->
682
741
 
683
742
  ## Forms / refs
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The companies a `last_admin` refusal names — kastlan checks the last admin per company
3
+ * and answers `409 {detail, code: "last_admin", companies: ["Example AG"]}` (§6.4,
4
+ * server-kit's `AccountError(…, extra={"companies": …})`). Read where `authErrorCode`
5
+ * reads the code: axios' `response.data`, ofetch's `data`, a generated client's `body`,
6
+ * a body thrown as it came. `undefined` when there is no such list.
7
+ */
8
+ declare function refusalCompanies(err: unknown): string[] | undefined;
9
+ /** Whether the component is still mounted — a late answer after the app navigated away
10
+ * (the deletion signs out) must not set state. */
11
+ declare function useMounted(): {
12
+ readonly current: boolean;
13
+ };
14
+ /** Call `call` and hand back a promise, a throw included — a callback may return
15
+ * nothing (done at once), a promise, or throw before it returns one. */
16
+ declare function settle(call: () => unknown): Promise<unknown>;
17
+ /** The settings cards' type scale, PasskeysSetting's: a small title and a muted line. */
18
+ declare const CARD_TITLE_CLASS = "text-sm font-medium";
19
+ declare const CARD_DESCRIPTION_CLASS = "text-xs text-[var(--text-muted)]";
20
+
21
+ export { CARD_DESCRIPTION_CLASS, CARD_TITLE_CLASS, refusalCompanies, settle, useMounted };
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ const isBag = (value) => typeof value === "object" && value !== null;
4
+ function companiesOfBody(body) {
5
+ if (!isBag(body)) return void 0;
6
+ const pick = (value) => Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === "string") ? value : void 0;
7
+ return pick(body.companies) ?? (isBag(body.detail) ? pick(body.detail.companies) : void 0);
8
+ }
9
+ function refusalCompanies(err) {
10
+ if (!isBag(err)) return void 0;
11
+ const response = err.response;
12
+ return (isBag(response) ? companiesOfBody(response.data) : void 0) ?? companiesOfBody(err.data) ?? companiesOfBody(err.body) ?? companiesOfBody(err);
13
+ }
14
+ function useMounted() {
15
+ const mounted = useRef(true);
16
+ useEffect(() => {
17
+ mounted.current = true;
18
+ return () => {
19
+ mounted.current = false;
20
+ };
21
+ }, []);
22
+ return mounted;
23
+ }
24
+ function settle(call) {
25
+ try {
26
+ return Promise.resolve(call());
27
+ } catch (error) {
28
+ return Promise.reject(error);
29
+ }
30
+ }
31
+ const CARD_TITLE_CLASS = "text-sm font-medium";
32
+ const CARD_DESCRIPTION_CLASS = "text-xs text-[var(--text-muted)]";
33
+ export {
34
+ CARD_DESCRIPTION_CLASS,
35
+ CARD_TITLE_CLASS,
36
+ refusalCompanies,
37
+ settle,
38
+ useMounted
39
+ };
40
+ //# sourceMappingURL=account-parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/account/account-parts.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/**\n * What the account's own settings parts share (docs/user-admin-harmonization.md §6):\n * the companies a refusal names, a mounted guard, and the card's type.\n *\n * @internal Not part of the barrel; the parts are.\n */\n\ntype Bag = Record<string, unknown>;\n\nconst isBag = (value: unknown): value is Bag => typeof value === \"object\" && value !== null;\n\n/** `companies` on a parsed body, or under FastAPI's nested `detail`: a list of names. */\nfunction companiesOfBody(body: unknown): string[] | undefined {\n if (!isBag(body)) return undefined;\n const pick = (value: unknown) =>\n Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === \"string\")\n ? (value as string[])\n : undefined;\n return pick(body.companies) ?? (isBag(body.detail) ? pick(body.detail.companies) : undefined);\n}\n\n/**\n * The companies a `last_admin` refusal names — kastlan checks the last admin per company\n * and answers `409 {detail, code: \"last_admin\", companies: [\"Example AG\"]}` (§6.4,\n * server-kit's `AccountError(…, extra={\"companies\": …})`). Read where `authErrorCode`\n * reads the code: axios' `response.data`, ofetch's `data`, a generated client's `body`,\n * a body thrown as it came. `undefined` when there is no such list.\n */\nexport function refusalCompanies(err: unknown): string[] | undefined {\n if (!isBag(err)) return undefined;\n const response = err.response;\n return (\n (isBag(response) ? companiesOfBody(response.data) : undefined) ??\n companiesOfBody(err.data) ??\n companiesOfBody(err.body) ??\n companiesOfBody(err)\n );\n}\n\n/** Whether the component is still mounted — a late answer after the app navigated away\n * (the deletion signs out) must not set state. */\nexport function useMounted(): { readonly current: boolean } {\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n return mounted;\n}\n\n/** Call `call` and hand back a promise, a throw included — a callback may return\n * nothing (done at once), a promise, or throw before it returns one. */\nexport function settle(call: () => unknown): Promise<unknown> {\n try {\n return Promise.resolve(call());\n } catch (error) {\n return Promise.reject(error);\n }\n}\n\n/** The settings cards' type scale, PasskeysSetting's: a small title and a muted line. */\nexport const CARD_TITLE_CLASS = \"text-sm font-medium\";\nexport const CARD_DESCRIPTION_CLASS = \"text-xs text-[var(--text-muted)]\";\n"],"mappings":";AAAA,SAAS,WAAW,cAAc;AAWlC,MAAM,QAAQ,CAAC,UAAiC,OAAO,UAAU,YAAY,UAAU;AAGvF,SAAS,gBAAgB,MAAqC;AAC5D,MAAI,CAAC,MAAM,IAAI,EAAG,QAAO;AACzB,QAAM,OAAO,CAAC,UACZ,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,IACrF,QACD;AACN,SAAO,KAAK,KAAK,SAAS,MAAM,MAAM,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,SAAS,IAAI;AACrF;AASO,SAAS,iBAAiB,KAAoC;AACnE,MAAI,CAAC,MAAM,GAAG,EAAG,QAAO;AACxB,QAAM,WAAW,IAAI;AACrB,UACG,MAAM,QAAQ,IAAI,gBAAgB,SAAS,IAAI,IAAI,WACpD,gBAAgB,IAAI,IAAI,KACxB,gBAAgB,IAAI,IAAI,KACxB,gBAAgB,GAAG;AAEvB;AAIO,SAAS,aAA4C;AAC1D,QAAM,UAAU,OAAO,IAAI;AAC3B,YAAU,MAAM;AACd,YAAQ,UAAU;AAClB,WAAO,MAAM;AACX,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAIO,SAAS,OAAO,MAAuC;AAC5D,MAAI;AACF,WAAO,QAAQ,QAAQ,KAAK,CAAC;AAAA,EAC/B,SAAS,OAAO;AACd,WAAO,QAAQ,OAAO,KAAK;AAAA,EAC7B;AACF;AAGO,MAAM,mBAAmB;AACzB,MAAM,yBAAyB;","names":[]}
@@ -0,0 +1,73 @@
1
+ import * as react from 'react';
2
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
3
+
4
+ /** Every string {@link DataExportSetting} renders — the `dataExport` namespace of
5
+ * `<UiKitProvider labels>`, overridable per instance through `labels`. */
6
+ interface DataExportLabels {
7
+ /** The card's title. */
8
+ title: string;
9
+ /** What the download is. The app's own sentence (`description`) follows it. */
10
+ description: string;
11
+ /** The button. */
12
+ download: string;
13
+ /** Said once the file was handed to the browser. */
14
+ started: string;
15
+ /** The link under it that saves the same file again, for a browser that held the
16
+ * download back. */
17
+ saveAgain: string;
18
+ /** The export was throttled — HTTP 429 (§6.5: once a minute) — given its
19
+ * `Retry-After` wait in seconds, or `undefined` without one. */
20
+ rateLimited: (seconds?: number) => string;
21
+ /** Any other failure. */
22
+ failed: string;
23
+ }
24
+ declare const DEFAULT_DATA_EXPORT_LABELS: DataExportLabels;
25
+ /**
26
+ * What {@link DataExportSettingProps.onExport} resolves with: the file itself — a `Blob`
27
+ * (axios' `responseType: "blob"`, `await res.blob()`) — or a URL the browser fetches
28
+ * itself (a signed link), with the file name to save it under.
29
+ */
30
+ type DataExportFile = Blob | {
31
+ url: string;
32
+ filename?: string;
33
+ };
34
+ interface DataExportSettingProps extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
35
+ /**
36
+ * Fetch the export (`GET /auth/me/export`, §6.5). Resolve with the file — the card
37
+ * saves it under `filename` — or reject with the client's error: a 429 (the export is
38
+ * throttled to once a minute) says `rateLimited`, anything else (a demo account's 403)
39
+ * goes through `describeError`, else `failed`.
40
+ */
41
+ onExport: () => Promise<DataExportFile>;
42
+ /**
43
+ * The app's sentence under the kit's — what the export holds and what it doesn't.
44
+ * kastlan's: "Your account; your company's records are your company's, ask them."
45
+ */
46
+ description?: ReactNode;
47
+ /** The name the file is saved under. Default `account-export-YYYY-MM-DD.json` (the
48
+ * local day); a `{ url, filename }` answer's own name wins. */
49
+ filename?: string;
50
+ /** The app's own words for a failure, or `undefined` for the kit's. Asked first. */
51
+ describeError?: (error: unknown) => ReactNode | undefined;
52
+ labels?: Partial<DataExportLabels>;
53
+ }
54
+ /**
55
+ * The account's data as a download (docs/user-admin-harmonization.md §6.5, §2.2): what it
56
+ * is, the app's sentence on what it holds, and one button.
57
+ *
58
+ * **The kit saves the file.** `onExport` fetches it — the request is the app's, with its
59
+ * auth (auth §8) — and resolves with a `Blob` or a `{ url }`; the card hands it to the
60
+ * browser through a link with a `download` name, so it lands as `account-export-….json`
61
+ * rather than opening as a page of JSON. A `Blob` becomes an object URL, revoked when
62
+ * the next export replaces it or the card unmounts.
63
+ *
64
+ * The click comes after an `await`, which some browsers count as no longer the
65
+ * person's: "Didn't start? Save the file" stays under the confirmation, a real link to
66
+ * the same file that the person clicks themselves.
67
+ *
68
+ * **The throttle** (once a minute, §6.5) is a 429, said as such; the app's
69
+ * `describeError` comes first (keksdose's demo account answers 403).
70
+ */
71
+ declare function DataExportSetting({ onExport, description, filename, describeError, labels: labelsProp, className, ...rest }: DataExportSettingProps): react.JSX.Element;
72
+
73
+ export { DEFAULT_DATA_EXPORT_LABELS, type DataExportFile, type DataExportLabels, DataExportSetting, type DataExportSettingProps };
@@ -0,0 +1,114 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { Download } from "lucide-react";
5
+ import { useKitLabels } from "../i18n/kit-labels.js";
6
+ import { cn } from "../lib/cn.js";
7
+ import { AlertBanner } from "../components/alert-banner.js";
8
+ import { hasMessage } from "../components/choice-parts.js";
9
+ import { TextLink } from "../components/text-link.js";
10
+ import { Button, Card } from "../components/ui.js";
11
+ import { englishWait, isRateLimited, retryAfterSeconds } from "../auth/auth-errors.js";
12
+ import { CARD_DESCRIPTION_CLASS, settle, useMounted } from "./account-parts.js";
13
+ import { SettingsCardTitle } from "../settings/settings-heading.js";
14
+ const DEFAULT_DATA_EXPORT_LABELS = {
15
+ title: "Export your data",
16
+ description: "Download a copy of your account\u2019s data as a JSON file.",
17
+ download: "Download my data",
18
+ started: "Your download has started.",
19
+ saveAgain: "Didn\u2019t start? Save the file",
20
+ rateLimited: (seconds) => seconds && seconds > 0 ? `You exported your data a moment ago. Try again in ${englishWait(seconds)}.` : "You exported your data a moment ago. Please try again in a minute.",
21
+ failed: "The export failed. Please try again."
22
+ };
23
+ function defaultFilename(now = /* @__PURE__ */ new Date()) {
24
+ const pad = (n) => String(n).padStart(2, "0");
25
+ return `account-export-${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}.json`;
26
+ }
27
+ function isUrlAnswer(value) {
28
+ return typeof value === "object" && value !== null && typeof value.url === "string";
29
+ }
30
+ function startDownload(href, filename) {
31
+ const link = document.createElement("a");
32
+ link.href = href;
33
+ link.download = filename;
34
+ link.rel = "noopener";
35
+ link.hidden = true;
36
+ document.body.appendChild(link);
37
+ link.click();
38
+ link.remove();
39
+ }
40
+ function DataExportSetting({
41
+ onExport,
42
+ description,
43
+ filename,
44
+ describeError,
45
+ labels: labelsProp,
46
+ className,
47
+ ...rest
48
+ }) {
49
+ const labels = useKitLabels("dataExport", DEFAULT_DATA_EXPORT_LABELS, labelsProp);
50
+ const [busy, setBusy] = useState(false);
51
+ const [saved, setSaved] = useState(null);
52
+ const [failure, setFailure] = useState(null);
53
+ const mounted = useMounted();
54
+ useEffect(() => {
55
+ if (!saved?.owned) return;
56
+ const href = saved.href;
57
+ return () => URL.revokeObjectURL(href);
58
+ }, [saved]);
59
+ const run = () => {
60
+ if (busy) return;
61
+ setBusy(true);
62
+ setFailure(null);
63
+ setSaved(null);
64
+ settle(onExport).then(
65
+ (answer) => {
66
+ if (!mounted.current) return;
67
+ setBusy(false);
68
+ let next;
69
+ if (answer instanceof Blob) {
70
+ next = { href: URL.createObjectURL(answer), filename: filename ?? defaultFilename(), owned: true };
71
+ } else if (isUrlAnswer(answer)) {
72
+ next = { href: answer.url, filename: answer.filename ?? filename ?? defaultFilename(), owned: false };
73
+ } else {
74
+ setFailure(labels.failed);
75
+ return;
76
+ }
77
+ setSaved(next);
78
+ startDownload(next.href, next.filename);
79
+ },
80
+ (error) => {
81
+ if (!mounted.current) return;
82
+ setBusy(false);
83
+ const own = describeError?.(error);
84
+ setFailure(
85
+ hasMessage(own) ? own : isRateLimited(error) ? labels.rateLimited(retryAfterSeconds(error)) : labels.failed
86
+ );
87
+ }
88
+ );
89
+ };
90
+ return /* @__PURE__ */ jsxs(Card, { ...rest, className: cn("p-4 space-y-3", className), children: [
91
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
92
+ /* @__PURE__ */ jsx(SettingsCardTitle, { children: labels.title }),
93
+ /* @__PURE__ */ jsx("div", { className: CARD_DESCRIPTION_CLASS, children: labels.description }),
94
+ hasMessage(description) && /* @__PURE__ */ jsx("div", { className: CARD_DESCRIPTION_CLASS, children: description })
95
+ ] }),
96
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2", children: [
97
+ /* @__PURE__ */ jsxs(Button, { type: "button", variant: "secondary", pending: busy, onClick: run, children: [
98
+ /* @__PURE__ */ jsx(Download, { "aria-hidden": true, className: "size-4" }),
99
+ labels.download
100
+ ] }),
101
+ /* @__PURE__ */ jsx("span", { role: "status", className: "text-xs text-[var(--text-secondary)]", children: saved && /* @__PURE__ */ jsxs(Fragment, { children: [
102
+ labels.started,
103
+ " ",
104
+ /* @__PURE__ */ jsx(TextLink, { href: saved.href, download: saved.filename, reloadDocument: true, tone: "secondary", children: labels.saveAgain })
105
+ ] }) })
106
+ ] }),
107
+ hasMessage(failure) && /* @__PURE__ */ jsx(AlertBanner, { tone: "danger", size: "sm", role: "alert", children: failure })
108
+ ] });
109
+ }
110
+ export {
111
+ DEFAULT_DATA_EXPORT_LABELS,
112
+ DataExportSetting
113
+ };
114
+ //# sourceMappingURL=data-export-setting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/account/data-export-setting.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { Download } from \"lucide-react\";\n\nimport { useKitLabels } from \"../i18n/kit-labels\";\nimport { cn } from \"../lib/cn\";\nimport { AlertBanner } from \"../components/alert-banner\";\nimport { hasMessage } from \"../components/choice-parts\";\nimport { TextLink } from \"../components/text-link\";\nimport { Button, Card } from \"../components/ui\";\nimport { englishWait, isRateLimited, retryAfterSeconds } from \"../auth/auth-errors\";\nimport { CARD_DESCRIPTION_CLASS, settle, useMounted } from \"./account-parts\";\nimport { SettingsCardTitle } from \"../settings/settings-heading\";\n\n/* ── Labels ──────────────────────────────────────────────────────────────── */\n\n/** Every string {@link DataExportSetting} renders — the `dataExport` namespace of\n * `<UiKitProvider labels>`, overridable per instance through `labels`. */\nexport interface DataExportLabels {\n /** The card's title. */\n title: string;\n /** What the download is. The app's own sentence (`description`) follows it. */\n description: string;\n /** The button. */\n download: string;\n /** Said once the file was handed to the browser. */\n started: string;\n /** The link under it that saves the same file again, for a browser that held the\n * download back. */\n saveAgain: string;\n /** The export was throttled — HTTP 429 (§6.5: once a minute) — given its\n * `Retry-After` wait in seconds, or `undefined` without one. */\n rateLimited: (seconds?: number) => string;\n /** Any other failure. */\n failed: string;\n}\n\nexport const DEFAULT_DATA_EXPORT_LABELS: DataExportLabels = {\n title: \"Export your data\",\n description: \"Download a copy of your account’s data as a JSON file.\",\n download: \"Download my data\",\n started: \"Your download has started.\",\n saveAgain: \"Didn’t start? Save the file\",\n rateLimited: (seconds) =>\n seconds && seconds > 0\n ? `You exported your data a moment ago. Try again in ${englishWait(seconds)}.`\n : \"You exported your data a moment ago. Please try again in a minute.\",\n failed: \"The export failed. Please try again.\",\n};\n\n/* ── Props ───────────────────────────────────────────────────────────────── */\n\n/**\n * What {@link DataExportSettingProps.onExport} resolves with: the file itself — a `Blob`\n * (axios' `responseType: \"blob\"`, `await res.blob()`) — or a URL the browser fetches\n * itself (a signed link), with the file name to save it under.\n */\nexport type DataExportFile = Blob | { url: string; filename?: string };\n\nexport interface DataExportSettingProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /**\n * Fetch the export (`GET /auth/me/export`, §6.5). Resolve with the file — the card\n * saves it under `filename` — or reject with the client's error: a 429 (the export is\n * throttled to once a minute) says `rateLimited`, anything else (a demo account's 403)\n * goes through `describeError`, else `failed`.\n */\n onExport: () => Promise<DataExportFile>;\n /**\n * The app's sentence under the kit's — what the export holds and what it doesn't.\n * kastlan's: \"Your account; your company's records are your company's, ask them.\"\n */\n description?: ReactNode;\n /** The name the file is saved under. Default `account-export-YYYY-MM-DD.json` (the\n * local day); a `{ url, filename }` answer's own name wins. */\n filename?: string;\n /** The app's own words for a failure, or `undefined` for the kit's. Asked first. */\n describeError?: (error: unknown) => ReactNode | undefined;\n labels?: Partial<DataExportLabels>;\n}\n\ninterface Saved {\n href: string;\n filename: string;\n /** An object URL of ours, revoked when it is replaced or the card goes. */\n owned: boolean;\n}\n\n/** `account-export-2026-10-07.json`, the local day — the one a person looks for. */\nfunction defaultFilename(now = new Date()): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `account-export-${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}.json`;\n}\n\n/** A `{ url }` answer, as opposed to a Blob or anything else. */\nfunction isUrlAnswer(value: unknown): value is { url: string; filename?: string } {\n return typeof value === \"object\" && value !== null && typeof (value as { url?: unknown }).url === \"string\";\n}\n\n/** Hand `href` to the browser as a download named `filename`: a link with `download`,\n * clicked once and taken out again — the one way a page saves a file without a new\n * tab that would show the JSON instead. */\nfunction startDownload(href: string, filename: string) {\n const link = document.createElement(\"a\");\n link.href = href;\n link.download = filename;\n link.rel = \"noopener\";\n link.hidden = true;\n document.body.appendChild(link);\n link.click();\n link.remove();\n}\n\n/**\n * The account's data as a download (docs/user-admin-harmonization.md §6.5, §2.2): what it\n * is, the app's sentence on what it holds, and one button.\n *\n * **The kit saves the file.** `onExport` fetches it — the request is the app's, with its\n * auth (auth §8) — and resolves with a `Blob` or a `{ url }`; the card hands it to the\n * browser through a link with a `download` name, so it lands as `account-export-….json`\n * rather than opening as a page of JSON. A `Blob` becomes an object URL, revoked when\n * the next export replaces it or the card unmounts.\n *\n * The click comes after an `await`, which some browsers count as no longer the\n * person's: \"Didn't start? Save the file\" stays under the confirmation, a real link to\n * the same file that the person clicks themselves.\n *\n * **The throttle** (once a minute, §6.5) is a 429, said as such; the app's\n * `describeError` comes first (keksdose's demo account answers 403).\n */\nexport function DataExportSetting({\n onExport,\n description,\n filename,\n describeError,\n labels: labelsProp,\n className,\n ...rest\n}: DataExportSettingProps) {\n const labels = useKitLabels(\"dataExport\", DEFAULT_DATA_EXPORT_LABELS, labelsProp);\n const [busy, setBusy] = useState(false);\n const [saved, setSaved] = useState<Saved | null>(null);\n const [failure, setFailure] = useState<ReactNode>(null);\n const mounted = useMounted();\n\n // Our object URL lives as long as the \"Save the file\" link that points at it.\n useEffect(() => {\n if (!saved?.owned) return;\n const href = saved.href;\n return () => URL.revokeObjectURL(href);\n }, [saved]);\n\n const run = () => {\n if (busy) return;\n setBusy(true);\n setFailure(null);\n // The last file's link goes (and its object URL with it): it would sit beside this\n // export's answer as if it were it.\n setSaved(null);\n settle(onExport).then(\n (answer) => {\n if (!mounted.current) return;\n setBusy(false);\n let next: Saved;\n if (answer instanceof Blob) {\n next = { href: URL.createObjectURL(answer), filename: filename ?? defaultFilename(), owned: true };\n } else if (isUrlAnswer(answer)) {\n next = { href: answer.url, filename: answer.filename ?? filename ?? defaultFilename(), owned: false };\n } else {\n // Nothing to save: an app that resolved with its response object, say.\n setFailure(labels.failed);\n return;\n }\n setSaved(next);\n startDownload(next.href, next.filename);\n },\n (error: unknown) => {\n if (!mounted.current) return;\n setBusy(false);\n const own = describeError?.(error);\n setFailure(\n hasMessage(own) ? own : isRateLimited(error) ? labels.rateLimited(retryAfterSeconds(error)) : labels.failed,\n );\n },\n );\n };\n\n return (\n <Card {...rest} className={cn(\"p-4 space-y-3\", className)}>\n <div className=\"space-y-1\">\n <SettingsCardTitle>{labels.title}</SettingsCardTitle>\n <div className={CARD_DESCRIPTION_CLASS}>{labels.description}</div>\n {hasMessage(description) && <div className={CARD_DESCRIPTION_CLASS}>{description}</div>}\n </div>\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">\n <Button type=\"button\" variant=\"secondary\" pending={busy} onClick={run}>\n <Download aria-hidden className=\"size-4\" />\n {labels.download}\n </Button>\n {/* Always in the tree, so the confirmation that appears in it is announced; in\n the button's row, so an empty one takes no line of its own. */}\n <span role=\"status\" className=\"text-xs text-[var(--text-secondary)]\">\n {saved && (\n <>\n {labels.started}{\" \"}\n <TextLink href={saved.href} download={saved.filename} reloadDocument tone=\"secondary\">\n {labels.saveAgain}\n </TextLink>\n </>\n )}\n </span>\n </div>\n {hasMessage(failure) && (\n <AlertBanner tone=\"danger\" size=\"sm\" role=\"alert\">\n {failure}\n </AlertBanner>\n )}\n </Card>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,95 @@
1
+ import 'react';
2
+ export { cq as DEFAULT_DELETE_ACCOUNT_LABELS, cQ as DeleteAccountConsequence, cR as DeleteAccountLabels, cS as DeleteAccountSetting, cT as DeleteAccountSettingProps, cU as DeleteAccountValues, cV as DeletionMode } from '../delete-account-setting-DCFS5Vof.js';
3
+ import '../components/tooltip.js';
4
+ import '../hooks/use-anchored-rect.js';
5
+ import '../lib/clipping.js';
6
+ import '../data-table-labels-DUELeXpa.js';
7
+ import '../components/data-table-sort.js';
8
+ import '../components/swipeable-row.js';
9
+ import '../components/mini-calendar.js';
10
+ import '../components/calendar-heatmap.js';
11
+ import '../components/popover.js';
12
+ import '../components/chip.js';
13
+ import 'lucide-react';
14
+ import '../components/field-sync.js';
15
+ import '../wizard/types.js';
16
+ import '../tour/tour.js';
17
+ import '../search/command-palette.js';
18
+ import '../search/global-search.js';
19
+ import '../search/search-index.js';
20
+ import '../components/month-picker.js';
21
+ import '../components/page-contents.js';
22
+ import '../components/series-chart-labels.js';
23
+ import '../components/pie-chart-labels.js';
24
+ import '../components/sparkline.js';
25
+ import '../components/stat-tile.js';
26
+ import '../components/signature-pad.js';
27
+ import '../components/password-strength.js';
28
+ import '../components/swatch-picker.js';
29
+ import '../components/tile-radio.js';
30
+ import '../components/icon-picker.js';
31
+ import '../components/dialog-frame.js';
32
+ import '../components/modal.js';
33
+ import '../hooks/use-search-param-state.js';
34
+ import '../components/measured-grid.js';
35
+ import '../components/user-avatar.js';
36
+ import '../lib/person-name.js';
37
+ import '../components/status-dot.js';
38
+ import '../components/progress-bar.js';
39
+ import '../components/signed-amount.js';
40
+ import '../shell/topbar-action-menu.js';
41
+ import '../components/menu-item.js';
42
+ import '../components/floating-panel.js';
43
+ import '../hooks/use-authed-src.js';
44
+ import '../components/account-settings-labels.js';
45
+ import '../components/bulk-action-bar.js';
46
+ import '../components/list.js';
47
+ import '../components/breadcrumbs.js';
48
+ import '../components/toast.js';
49
+ import '../components/description-list.js';
50
+ import '../components/line-items.js';
51
+ import '../components/error-boundary.js';
52
+ import '../components/authed-image.js';
53
+ import '../components/image-grid.js';
54
+ import '../components/lightbox.js';
55
+ import '../components/write-lock.js';
56
+ import '../auth/sign-in-form.js';
57
+ import '../landing/access.js';
58
+ import '../landing/landing-labels.js';
59
+ import '../shell/topbar-controls.js';
60
+ import '../theme/palette-presets.js';
61
+ import '../theme/chart-palette.js';
62
+ import '../theme/theme-store.js';
63
+ import 'zustand/middleware';
64
+ import 'zustand';
65
+ import '../auth/complete-name-dialog.js';
66
+ import '../auth/forgot-password-form.js';
67
+ import '../auth/status-parts.js';
68
+ import '../auth/reset-password-form.js';
69
+ import '../auth/verify-email.js';
70
+ import '../auth/not-found-page.js';
71
+ import '../auth/accept-invitation.js';
72
+ import '../shell/company-switcher.js';
73
+ import './email-change-setting.js';
74
+ import './sessions-setting.js';
75
+ import '../lib/format.js';
76
+ import './data-export-setting.js';
77
+ import '../components/account-chips.js';
78
+ import '../admin/admin-parts.js';
79
+ import '../admin/admin-action-log.js';
80
+ import '../settings/settings-labels.js';
81
+ import '../demo/demo-labels.js';
82
+ import '../components/reauth-dialog.js';
83
+ import '../components/server-wake.js';
84
+ import '../lib/server-wake.js';
85
+ import '../components/translation-review-labels.js';
86
+ import '../lib/translation-review.js';
87
+ import '../components/country-select.js';
88
+ import '../components/inline-edit-field.js';
89
+ import '../lib/iban.js';
90
+ import '../lib/phone.js';
91
+ import '../components/sign-chip.js';
92
+ import '../components/column-mapper.js';
93
+ import '../lib/column-mapping.js';
94
+ import '../lib/table-text.js';
95
+ import '../components/field-parts.js';