@eifi1/ui-kit 0.16.1 → 0.18.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 (186) hide show
  1. package/README.md +34 -9
  2. package/dist/chart.d.ts +10 -1
  3. package/dist/components/account-chips.d.ts +153 -0
  4. package/dist/components/account-chips.js +135 -0
  5. package/dist/components/account-chips.js.map +1 -0
  6. package/dist/components/account-settings-labels.d.ts +10 -2
  7. package/dist/components/account-settings-labels.js +3 -0
  8. package/dist/components/account-settings-labels.js.map +1 -1
  9. package/dist/components/amount-input.d.ts +18 -1
  10. package/dist/components/amount-input.js.map +1 -1
  11. package/dist/components/button-group.d.ts +10 -1
  12. package/dist/components/calculator.d.ts +10 -1
  13. package/dist/components/chip.d.ts +25 -1
  14. package/dist/components/chip.js +143 -6
  15. package/dist/components/chip.js.map +1 -1
  16. package/dist/components/confirm-dialog.d.ts +42 -1
  17. package/dist/components/confirm-dialog.js +36 -5
  18. package/dist/components/confirm-dialog.js.map +1 -1
  19. package/dist/components/copy-button.d.ts +10 -1
  20. package/dist/components/danger-confirm.d.ts +55 -4
  21. package/dist/components/danger-confirm.js +67 -30
  22. package/dist/components/danger-confirm.js.map +1 -1
  23. package/dist/components/data-table-cells.d.ts +1 -1
  24. package/dist/components/data-table-filter-popover.d.ts +1 -1
  25. package/dist/components/data-table-filters.d.ts +1 -1
  26. package/dist/components/data-table.d.ts +1 -1
  27. package/dist/components/data-table.js +93 -3
  28. package/dist/components/data-table.js.map +1 -1
  29. package/dist/components/facing-pair.d.ts +10 -1
  30. package/dist/components/file-button.d.ts +10 -1
  31. package/dist/components/file-dropzone.d.ts +10 -1
  32. package/dist/components/form-actions.d.ts +10 -1
  33. package/dist/components/form-actions.js +35 -1
  34. package/dist/components/form-actions.js.map +1 -1
  35. package/dist/components/line-items.d.ts +30 -6
  36. package/dist/components/line-items.js +77 -33
  37. package/dist/components/line-items.js.map +1 -1
  38. package/dist/components/list.d.ts +13 -1
  39. package/dist/components/list.js.map +1 -1
  40. package/dist/components/money-field.d.ts +10 -1
  41. package/dist/components/number-field.d.ts +11 -2
  42. package/dist/components/number-field.js +23 -22
  43. package/dist/components/number-field.js.map +1 -1
  44. package/dist/components/number-input.d.ts +10 -1
  45. package/dist/components/numpad-sheet.d.ts +10 -1
  46. package/dist/components/passkeys-setting.d.ts +27 -1
  47. package/dist/components/passkeys-setting.js +31 -5
  48. package/dist/components/passkeys-setting.js.map +1 -1
  49. package/dist/components/progress-bar.d.ts +25 -1
  50. package/dist/components/progress-bar.js +21 -4
  51. package/dist/components/progress-bar.js.map +1 -1
  52. package/dist/components/reauth-dialog.d.ts +90 -0
  53. package/dist/components/reauth-dialog.js +158 -0
  54. package/dist/components/reauth-dialog.js.map +1 -0
  55. package/dist/components/series-chart.d.ts +10 -1
  56. package/dist/components/server-wake.d.ts +58 -0
  57. package/dist/components/server-wake.js +58 -0
  58. package/dist/components/server-wake.js.map +1 -0
  59. package/dist/components/settings-fields.d.ts +10 -1
  60. package/dist/components/share-card.d.ts +61 -0
  61. package/dist/components/share-card.js +350 -0
  62. package/dist/components/share-card.js.map +1 -0
  63. package/dist/components/signed-amount.d.ts +12 -3
  64. package/dist/components/signed-amount.js +6 -4
  65. package/dist/components/signed-amount.js.map +1 -1
  66. package/dist/components/status-dot.d.ts +2 -0
  67. package/dist/components/text-link.d.ts +10 -1
  68. package/dist/components/time-input.d.ts +10 -1
  69. package/dist/components/toast.d.ts +10 -1
  70. package/dist/components/toast.js +42 -2
  71. package/dist/components/toast.js.map +1 -1
  72. package/dist/components/toggle-group.js +5 -2
  73. package/dist/components/toggle-group.js.map +1 -1
  74. package/dist/components/ui.d.ts +10 -1
  75. package/dist/components/ui.js +67 -30
  76. package/dist/components/ui.js.map +1 -1
  77. package/dist/components/use-table-state.d.ts +1 -1
  78. package/dist/components/user-avatar.d.ts +2 -0
  79. package/dist/components/write-lock.d.ts +68 -0
  80. package/dist/components/write-lock.js +33 -0
  81. package/dist/components/write-lock.js.map +1 -0
  82. package/dist/{data-table-CfVXtCeG.d.ts → data-table-3mi2R3so.d.ts} +59 -1
  83. package/dist/data-table.d.ts +1 -1
  84. package/dist/hooks/use-file-drop.d.ts +10 -1
  85. package/dist/hooks/use-overlay-history.js +16 -0
  86. package/dist/hooks/use-overlay-history.js.map +1 -1
  87. package/dist/i18n/defaults.d.ts +10 -1
  88. package/dist/i18n/defaults.js +11 -1
  89. package/dist/i18n/defaults.js.map +1 -1
  90. package/dist/i18n/german.d.ts +78 -0
  91. package/dist/i18n/{locales/de.js → german.js} +59 -9
  92. package/dist/i18n/german.js.map +1 -0
  93. package/dist/i18n/kit-labels.d.ts +10 -1
  94. package/dist/i18n/kit-labels.js +5 -0
  95. package/dist/i18n/kit-labels.js.map +1 -1
  96. package/dist/i18n/locales/de-CH.d.ts +23 -8
  97. package/dist/i18n/locales/de-CH.js +7 -3
  98. package/dist/i18n/locales/de-CH.js.map +1 -1
  99. package/dist/i18n/locales/{de.d.ts → en.d.ts} +24 -10
  100. package/dist/i18n/locales/en.js +95 -0
  101. package/dist/i18n/locales/en.js.map +1 -0
  102. package/dist/i18n/locales/es.d.ts +10 -1
  103. package/dist/i18n/locales/es.js +51 -1
  104. package/dist/i18n/locales/es.js.map +1 -1
  105. package/dist/i18n/locales/fr.d.ts +10 -1
  106. package/dist/i18n/locales/fr.js +51 -1
  107. package/dist/i18n/locales/fr.js.map +1 -1
  108. package/dist/i18n/locales/hu.d.ts +10 -1
  109. package/dist/i18n/locales/hu.js +54 -1
  110. package/dist/i18n/locales/hu.js.map +1 -1
  111. package/dist/i18n/locales/it.d.ts +10 -1
  112. package/dist/i18n/locales/it.js +51 -1
  113. package/dist/i18n/locales/it.js.map +1 -1
  114. package/dist/i18n/locales/zh.d.ts +10 -1
  115. package/dist/i18n/locales/zh.js +50 -1
  116. package/dist/i18n/locales/zh.js.map +1 -1
  117. package/dist/i18n/swiss.d.ts +3 -3
  118. package/dist/i18n/swiss.js.map +1 -1
  119. package/dist/index.d.ts +11 -6
  120. package/dist/index.js +33 -1
  121. package/dist/index.js.map +1 -1
  122. package/dist/{kit-labels-DE--LmCk.d.ts → kit-labels-CPbsjlXr.d.ts} +282 -10
  123. package/dist/lib/server-wake.d.ts +130 -0
  124. package/dist/lib/server-wake.js +121 -0
  125. package/dist/lib/server-wake.js.map +1 -0
  126. package/dist/rhf/fields.d.ts +10 -1
  127. package/dist/rhf/form.d.ts +10 -1
  128. package/dist/rhf/line-items.js.map +1 -1
  129. package/dist/rhf.d.ts +10 -1
  130. package/dist/search/global-search.d.ts +24 -4
  131. package/dist/search/global-search.js +31 -3
  132. package/dist/search/global-search.js.map +1 -1
  133. package/dist/search.d.ts +1 -1
  134. package/dist/shell/app-shell.d.ts +10 -1
  135. package/dist/shell/top-bar-brand.d.ts +10 -1
  136. package/dist/shell/topbar-action-menu.d.ts +2 -0
  137. package/dist/shell.d.ts +10 -1
  138. package/dist/wizard/stepper-nav.d.ts +10 -1
  139. package/dist/wizard.d.ts +10 -1
  140. package/package.json +1 -1
  141. package/src/components/account-chips.tsx +302 -0
  142. package/src/components/account-settings-labels.ts +16 -2
  143. package/src/components/amount-input.tsx +8 -0
  144. package/src/components/chip.tsx +239 -6
  145. package/src/components/confirm-dialog.tsx +82 -7
  146. package/src/components/danger-confirm.tsx +118 -33
  147. package/src/components/data-table.tsx +185 -3
  148. package/src/components/form-actions.tsx +93 -4
  149. package/src/components/line-items.tsx +116 -40
  150. package/src/components/list.tsx +13 -1
  151. package/src/components/number-field.tsx +32 -26
  152. package/src/components/passkeys-setting.tsx +68 -7
  153. package/src/components/progress-bar.tsx +40 -4
  154. package/src/components/reauth-dialog.tsx +273 -0
  155. package/src/components/server-wake.tsx +124 -0
  156. package/src/components/share-card.tsx +615 -0
  157. package/src/components/signed-amount.tsx +16 -5
  158. package/src/components/toast.tsx +72 -2
  159. package/src/components/toggle-group.tsx +5 -2
  160. package/src/components/ui.tsx +145 -34
  161. package/src/components/write-lock.tsx +96 -0
  162. package/src/hooks/use-overlay-history.ts +51 -0
  163. package/src/i18n/defaults.ts +10 -0
  164. package/src/i18n/{locales/de.ts → german.ts} +68 -13
  165. package/src/i18n/kit-labels.tsx +22 -2
  166. package/src/i18n/locales/de-CH.ts +17 -8
  167. package/src/i18n/locales/en.ts +116 -0
  168. package/src/i18n/locales/es.ts +51 -0
  169. package/src/i18n/locales/fr.ts +52 -0
  170. package/src/i18n/locales/hu.ts +55 -0
  171. package/src/i18n/locales/it.ts +51 -0
  172. package/src/i18n/locales/zh.ts +50 -0
  173. package/src/i18n/swiss.ts +3 -3
  174. package/src/index.ts +23 -1
  175. package/src/lib/server-wake.ts +270 -0
  176. package/src/rhf/line-items.tsx +2 -1
  177. package/src/search/global-search.tsx +59 -6
  178. package/dist/i18n/locales/de-CH-informal.d.ts +0 -61
  179. package/dist/i18n/locales/de-CH-informal.js +0 -8
  180. package/dist/i18n/locales/de-CH-informal.js.map +0 -1
  181. package/dist/i18n/locales/de-informal.d.ts +0 -82
  182. package/dist/i18n/locales/de-informal.js +0 -37
  183. package/dist/i18n/locales/de-informal.js.map +0 -1
  184. package/dist/i18n/locales/de.js.map +0 -1
  185. package/src/i18n/locales/de-CH-informal.ts +0 -10
  186. package/src/i18n/locales/de-informal.ts +0 -61
package/README.md CHANGED
@@ -382,21 +382,21 @@ 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
- **1039 names from 161 modules** — 483 values and 556 types. _Italic_ is a type-only export.
385
+ **1101 names from 167 modules** — 508 values and 593 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` | 1039 |
392
+ | `@eifi1/ui-kit` | 1101 |
393
393
  | `@eifi1/ui-kit/chart` | 104 |
394
394
  | `@eifi1/ui-kit/shell` | 24 |
395
395
  | `@eifi1/ui-kit/data-table` | 49 |
396
396
  | `@eifi1/ui-kit/wizard` | 25 |
397
397
  | `@eifi1/ui-kit/tour` | 7 |
398
398
  | `@eifi1/ui-kit/feedback` | 54 |
399
- | `@eifi1/ui-kit/search` | 22 |
399
+ | `@eifi1/ui-kit/search` | 23 |
400
400
  | `@eifi1/ui-kit/dates` | 22 |
401
401
  | `@eifi1/ui-kit/table-text` | 8 |
402
402
  | `@eifi1/ui-kit/rhf` | 44 |
@@ -414,6 +414,7 @@ re-slicing of it, never a second API.
414
414
  | `lib/format` | `currencyMinorDigits`, `EMPTY_FORMATTED_VALUE`, `formatDate`, `formatMoney`, `formatNumber`, `formatPercent`, `formatRelativeTime`, `roundToCurrency`, `toDate`, `useKitFormat`, _`DateInput`_, _`FormatDateOptions`_, _`FormatDateStyle`_, _`FormatDigits`_, _`FormatMoneyOptions`_, _`FormatNumberBaseOptions`_, _`FormatNumberOptions`_, _`FormatPercentOptions`_, _`FormatRelativeTimeOptions`_, _`KitFormat`_, _`RoundToCurrencyOptions`_ |
415
415
  | `lib/safe-storage` | `readStored`, `writeStored` |
416
416
  | `lib/qr-encode` | `encodeQr`, _`QrEncodeOptions`_, _`QrErrorCorrection`_, _`QrMatrix`_ |
417
+ | `lib/server-wake` | `attachServerWake`, `createServerWake`, `serverWake`, `watchReadsAnd`, `wrapFetch`, _`AxiosLikeInstance`_, _`ServerWakeAxiosConfig`_, _`ServerWakeFilter`_, _`ServerWakeOptions`_, _`ServerWakeRequest`_, _`ServerWakeStage`_, _`ServerWakeWatcher`_ |
417
418
  | `lib/clipping` | `CLIPS_ATTRIBUTE` |
418
419
 
419
420
  ### hooks
@@ -460,10 +461,11 @@ re-slicing of it, never a second API.
460
461
 
461
462
  | Module | Exports |
462
463
  |---|---|
463
- | `components/ui` | `Button`, `buttonClasses`, `Card`, `CardAction`, `CardContent`, `CardDescription`, `CardFooter`, `CardHeader`, `CardTitle`, `DEFAULT_PASSWORD_REVEAL_LABELS`, `DEFAULT_TABS_LABELS`, `EmptyState`, `FIELD_BASE`, `FIELD_DISPLAY`, `FIELD_FLOATING_PAD`, `FIELD_INVALID`, `FIELD_TRIGGER`, `FIELD_WRITABLE_LOOK`, `FieldChevron`, `FieldHint`, `FieldLabel`, `FLOATING_INPUT_CLASS`, `FLOATING_LABEL_CLASS`, `FLOATING_LABEL_STATIC`, `FloatingField`, `IconButton`, `Input`, `Label`, `PHONE_QUERY`, `resolvePasswordRevealLabels`, `Select`, `Spinner`, `Tabs`, `Textarea`, _`ButtonClassesOptions`_, _`ButtonLinkProps`_, _`ButtonProps`_, _`ButtonSize`_, _`ButtonTone`_, _`ButtonVariant`_, _`CardActionProps`_, _`CardContentProps`_, _`CardDescriptionProps`_, _`CardFooterProps`_, _`CardHeaderProps`_, _`CardProps`_, _`CardTitleLevel`_, _`CardTitleProps`_, _`CardTone`_, _`EmptyStateProps`_, _`FieldChevronProps`_, _`FieldHintProps`_, _`FieldLabelProps`_, _`FloatingFieldProps`_, _`IconButtonGlyphSize`_, _`IconButtonLinkProps`_, _`IconButtonProps`_, _`IconButtonSize`_, _`IconButtonTone`_, _`IconButtonToneColor`_, _`IconButtonVariant`_, _`InputProps`_, _`LabelProps`_, _`PasswordRevealLabels`_, _`SelectProps`_, _`SpinnerProps`_, _`TabItem`_, _`TabsLabels`_, _`TabsProps`_, _`TextareaProps`_ |
464
+ | `components/ui` | `Button`, `buttonClasses`, `Card`, `CardAction`, `CardContent`, `CardDescription`, `CardFooter`, `CardHeader`, `CardTitle`, `DEFAULT_PASSWORD_REVEAL_LABELS`, `DEFAULT_TABS_LABELS`, `EmptyState`, `FIELD_BASE`, `FIELD_DISPLAY`, `FIELD_FLOATING_PAD`, `FIELD_INVALID`, `FIELD_TRIGGER`, `FIELD_WRITABLE_LOOK`, `FieldChevron`, `FieldHint`, `FieldLabel`, `FLOATING_INPUT_CLASS`, `FLOATING_LABEL_CLASS`, `FLOATING_LABEL_STATIC`, `FloatingField`, `IconButton`, `Input`, `Label`, `PHONE_QUERY`, `resolvePasswordRevealLabels`, `Select`, `Spinner`, `Tabs`, `Textarea`, _`ButtonClassesOptions`_, _`ButtonLinkProps`_, _`ButtonProps`_, _`ButtonSize`_, _`ButtonTone`_, _`ButtonVariant`_, _`CardActionProps`_, _`CardContentProps`_, _`CardDensity`_, _`CardDescriptionProps`_, _`CardFooterProps`_, _`CardHeaderProps`_, _`CardProps`_, _`CardTitleLevel`_, _`CardTitleProps`_, _`CardTone`_, _`EmptyStateProps`_, _`FieldChevronProps`_, _`FieldHintProps`_, _`FieldLabelProps`_, _`FloatingFieldProps`_, _`IconButtonGlyphSize`_, _`IconButtonLinkProps`_, _`IconButtonProps`_, _`IconButtonSize`_, _`IconButtonTone`_, _`IconButtonToneColor`_, _`IconButtonVariant`_, _`InputProps`_, _`LabelProps`_, _`PasswordRevealLabels`_, _`SelectProps`_, _`SpinnerProps`_, _`TabItem`_, _`TabsLabels`_, _`TabsProps`_, _`TextareaProps`_ |
464
465
  | `components/copy-button` | `CopyButton`, `DEFAULT_COPY_BUTTON_LABELS`, _`CopyButtonLabels`_, _`CopyButtonProps`_ |
465
466
  | `components/file-button` | `DEFAULT_FILE_PICKER_LABELS`, `FileButton`, `matchesAccept`, `useFilePicker`, _`FileButtonProps`_, _`FilePickerLabels`_, _`FileRejection`_, _`FileRejectionReason`_, _`FileScreenOptions`_, _`UseFilePickerOptions`_, _`UseFilePickerReturn`_ |
466
- | `components/form-actions` | `DEFAULT_FORM_ACTIONS_LABELS`, `FormActions`, _`FormActionsAlign`_, _`FormActionsDestructive`_, _`FormActionsLabels`_, _`FormActionsPlacement`_, _`FormActionsProps`_, _`FormActionsStickyWithin`_, _`FormActionsSubmitProps`_ |
467
+ | `components/form-actions` | `DEFAULT_FORM_ACTIONS_LABELS`, `FormActions`, _`FormActionsAlign`_, _`FormActionsDestructive`_, _`FormActionsLabels`_, _`FormActionsPlacement`_, _`FormActionsProps`_, _`FormActionsStickyWithin`_, _`FormActionsSubmitProps`_, _`ResponsiveFormActionsPlacement`_ |
468
+ | `components/share-card` | `DEFAULT_SHARE_CARD_LABELS`, `ShareCard`, `ShareDialog`, `SharePanel`, _`ShareAddRequest`_, _`ShareCandidate`_, _`ShareCardLabels`_, _`ShareCardProps`_, _`ShareDialogProps`_, _`ShareGrantee`_, _`SharePanelProps`_, _`SharePendingGrant`_, _`ShareRole`_ |
467
469
  | `components/field` | `Field`, _`FieldControlProps`_, _`FieldLabelVisibility`_, _`FieldProps`_, _`FieldRenderMeta`_ |
468
470
  | `components/search-field` | `SearchField`, _`SearchFieldProps`_ |
469
471
  | `components/dropdown` | `DropdownPanel`, `DropdownSearchHeader`, `useDropdown`, `useDropdownSearch`, _`DropdownPanelProps`_, _`DropdownSearchHeaderProps`_ |
@@ -497,7 +499,8 @@ re-slicing of it, never a second API.
497
499
  | `components/page-contents` | `DEFAULT_PAGE_CONTENTS_LABELS`, `PageContents`, `PageContentsLayout`, `useScrollSpy`, _`PageContentsItem`_, _`PageContentsLabels`_, _`PageContentsLayoutProps`_, _`PageContentsProps`_, _`UseScrollSpyOptions`_ |
498
500
  | `components/disclosure` | `Collapse`, `Disclosure`, _`CollapseProps`_, _`DisclosureProps`_, _`DisclosureTriggerProps`_ |
499
501
  | `components/dialog-frame` | `DEFAULT_DIALOG_FRAME_LABELS`, `DialogFrame`, _`DialogFrameLabels`_, _`DialogFrameProps`_ |
500
- | `components/danger-confirm` | `DangerConfirm`, `DEFAULT_DANGER_CONFIRM_LABELS`, _`DangerConfirmLabels`_, _`DangerConfirmProps`_ |
502
+ | `components/danger-confirm` | `DangerConfirm`, `DEFAULT_DANGER_CONFIRM_LABELS`, `typedMatches`, _`DangerConfirmLabels`_, _`DangerConfirmProps`_, _`TypedMatch`_ |
503
+ | `components/reauth-dialog` | `DEFAULT_REAUTH_DIALOG_LABELS`, `ReauthDialog`, _`ReauthDialogLabels`_, _`ReauthDialogProps`_ |
501
504
  | `components/confirm-dialog` | `ConfirmProvider`, `DEFAULT_CONFIRM_DIALOG_LABELS`, `useConfirm`, _`ConfirmDialogLabels`_, _`ConfirmFn`_, _`ConfirmOptions`_, _`ConfirmProviderProps`_, _`ConfirmTone`_ |
502
505
  | `components/floating-panel` | `DEFAULT_FLOATING_PANEL_LABELS`, `FloatingAction`, `FloatingActionButton`, `FloatingActionGroup`, `FloatingPanel`, _`FloatingActionButtonProps`_, _`FloatingActionGroupProps`_, _`FloatingActionLinkProps`_, _`FloatingActionProps`_, _`FloatingCorner`_, _`FloatingPanelLabels`_, _`FloatingPanelProps`_ |
503
506
  | `components/bulk-action-bar` | `BulkActionBar`, `DEFAULT_BULK_ACTION_BAR_LABELS`, _`BulkActionBarLabels`_, _`BulkActionBarProps`_, _`BulkActionBarVariant`_, _`ResponsiveBulkActionBarVariant`_ |
@@ -520,7 +523,7 @@ re-slicing of it, never a second API.
520
523
  | `components/alert-banner` | `AlertBanner`, `alertFrameClass`, `toneFrameClass`, _`AlertBannerProps`_, _`AlertSize`_, _`AlertTone`_ |
521
524
  | `components/toggle-group` | `ToggleGroup`, _`ToggleGroupBaseProps`_, _`ToggleGroupClearableProps`_, _`ToggleGroupProps`_, _`ToggleGroupRequiredProps`_, _`ToggleOption`_ |
522
525
  | `components/nav-pills` | `NavPills`, _`NavPillItem`_, _`NavPillLinkProps`_, _`NavPillsCurrent`_, _`NavPillsProps`_ |
523
- | `components/chip` | `Chip`, `ChipInput`, `DEFAULT_CHIP_INPUT_LABELS`, `resolveChipInputLabels`, _`ChipHue`_, _`ChipInputLabels`_, _`ChipInputProps`_, _`ChipLinkProps`_, _`ChipProps`_, _`ChipShape`_, _`ChipSize`_, _`ChipTone`_, _`ChipVariant`_ |
526
+ | `components/chip` | `Chip`, `ChipInput`, `DEFAULT_CHIP_INPUT_LABELS`, `refreshChipEdges`, `resolveChipInputLabels`, _`ChipHue`_, _`ChipInputLabels`_, _`ChipInputProps`_, _`ChipLinkProps`_, _`ChipProps`_, _`ChipShape`_, _`ChipSize`_, _`ChipTone`_, _`ChipVariant`_ |
524
527
  | `components/wizard-stepper` | `WizardStepper` |
525
528
  | `components/hover-menu` | `HoverMenu`, _`HoverMenuProps`_ |
526
529
  | `components/modal` | `Modal`, `ModalCloseContext`, `useBackdropClose`, _`ModalProps`_ |
@@ -533,7 +536,10 @@ re-slicing of it, never a second API.
533
536
  | `components/tree-view` | `TreeRow`, `TreeView`, _`TreeItemState`_, _`TreeNode`_, _`TreeRowProps`_, _`TreeViewProps`_ |
534
537
  | `components/chart` | `ChartContainer`, `ChartLegend`, `ChartLegendContent`, `ChartTooltip`, `ChartTooltipContent`, `useChart`, _`ChartConfig`_, _`ChartSeriesConfig`_ |
535
538
  | `components/description-list` | `DEFAULT_DESCRIPTION_LIST_LABELS`, `DescriptionItem`, `DescriptionList`, _`DescriptionItemProps`_, _`DescriptionListColumns`_, _`DescriptionListDensity`_, _`DescriptionListLabels`_, _`DescriptionListLayout`_, _`DescriptionListProps`_ |
536
- | `components/line-items` | `DEFAULT_LINE_ITEMS_LABELS`, `LineItems`, _`LineItemCellContext`_, _`LineItemsColumn`_, _`LineItemsFieldLabels`_, _`LineItemsLabels`_, _`LineItemsProps`_, _`LineItemsSummary`_, _`LineItemsSummaryTone`_ |
539
+ | `components/write-lock` | `DEFAULT_WRITE_LOCK_LABELS`, `useWriteLock`, `WriteLockProvider`, _`WriteLock`_, _`WriteLockLabels`_, _`WriteLockProviderProps`_ |
540
+ | `components/account-chips` | `ACCOUNT_STATE_TONES`, `AccountStateChip`, `dateColumn`, `DateMark`, `DEFAULT_ACCOUNT_STATE_LABELS`, `RoleChip`, _`AccountState`_, _`AccountStateChipProps`_, _`AccountStateLabels`_, _`DateColumnOptions`_, _`DateMarkProps`_, _`RoleChipProps`_, _`RoleDefinition`_, _`RoleVocabulary`_ |
541
+ | `components/server-wake` | `DEFAULT_SERVER_WAKE_LABELS`, `ServerWakeNotice`, `useServerWakeStage`, _`ServerWakeLabels`_, _`ServerWakeNoticeProps`_ |
542
+ | `components/line-items` | `DEFAULT_LINE_ITEMS_LABELS`, `LineItems`, _`LineItemCellContext`_, _`LineItemsColumn`_, _`LineItemsFieldLabels`_, _`LineItemsLabels`_, _`LineItemsProps`_, _`LineItemsRemoveAlign`_, _`LineItemsRemovePlacement`_, _`LineItemsSummary`_, _`LineItemsSummaryTone`_ |
537
543
  | `components/progress-bar` | `DEFAULT_PROGRESS_BAR_LABELS`, `ProgressBar`, _`ProgressBarLabels`_, _`ProgressBarProps`_, _`ProgressBarSegment`_, _`ProgressBarSize`_, _`ProgressBarTone`_ |
538
544
  | `components/skeleton` | `Skeleton`, _`SkeletonProps`_, _`SkeletonShape`_ |
539
545
  | `components/loading-state` | `LoadingState`, _`LoadingStateLabelVisibility`_, _`LoadingStateProps`_, _`LoadingStateSize`_ |
@@ -613,7 +619,7 @@ re-slicing of it, never a second API.
613
619
  |---|---|
614
620
  | `search/command-palette` | `CommandPalette`, `DEFAULT_COMMAND_PALETTE_LABELS`, `useCommandKey`, _`CommandItem`_, _`CommandPaletteDensity`_, _`CommandPaletteLabels`_ |
615
621
  | `search/search-index` | `createSearchIndex`, `matchEntries`, `normalizeSearchText`, `SEARCH_TIER_POINTS`, _`SearchEntry`_, _`SearchHit`_, _`SearchIndex`_, _`SearchIndexOptions`_, _`SearchMatchField`_ |
616
- | `search/global-search` | `DEFAULT_GLOBAL_SEARCH_LABELS`, `GlobalSearch`, _`GlobalSearchLabels`_, _`GlobalSearchProps`_, _`GlobalSearchSource`_, _`GlobalSearchSuggestion`_, _`GlobalSearchTriggerProps`_ |
622
+ | `search/global-search` | `DEFAULT_GLOBAL_SEARCH_LABELS`, `GlobalSearch`, _`GlobalSearchLabels`_, _`GlobalSearchProps`_, _`GlobalSearchSource`_, _`GlobalSearchSourceGroup`_, _`GlobalSearchSuggestion`_, _`GlobalSearchTriggerProps`_ |
617
623
 
618
624
  <!-- END GENERATED: exports -->
619
625
 
@@ -724,6 +730,25 @@ pageChanged: (page: number, totalPages: number) => string;
724
730
  fieldValue: (field: string, value: string) => string;
725
731
  ```
726
732
 
733
+ ### Shipped catalogues
734
+
735
+ The kit's own words come translated, one standalone subpath per language, so an app
736
+ bundles only the language it imports: `@eifi1/ui-kit/i18n/<code>` exports
737
+ `UI_KIT_LABELS_<CODE>` and a factory `uiKitLabels<Code>(numberLocale)` that keeps the words
738
+ and changes only how counts and file sizes are written. Codes: `de-CH`, `fr`, `it`, `es`,
739
+ `hu`, `zh`, and `en` (factory only — the constant is `DEFAULT_UI_KIT_LABELS`).
740
+
741
+ There is ONE German: `de-CH`, Swiss Standard German, formal ("Sie"), with "ss" for every
742
+ "ß" — `uiKitLabelsDeCh("de-DE")` keeps that text and writes German digits. An app that
743
+ addresses its users with "du" overrides the few sentences that address the reader in its
744
+ own provider; the kit does not ship a second register.
745
+
746
+ ```tsx
747
+ import { UI_KIT_LABELS_DE_CH } from "@eifi1/ui-kit/i18n/de-CH";
748
+
749
+ <UiKitProvider labels={UI_KIT_LABELS_DE_CH} locale="de-CH">…</UiKitProvider>
750
+ ```
751
+
727
752
  ### The worked example
728
753
 
729
754
  `showcase/src/i18n/` runs the whole showcase in seven locales — English, German, French,
package/dist/chart.d.ts CHANGED
@@ -13,7 +13,7 @@ export { TimeTickUnit } from './components/series-chart-ticks.js';
13
13
  import 'recharts';
14
14
  import 'react';
15
15
  import './lib/direction.js';
16
- import './kit-labels-DE--LmCk.js';
16
+ import './kit-labels-CPbsjlXr.js';
17
17
  import './components/data-table-labels.js';
18
18
  import './components/mini-calendar.js';
19
19
  import './components/calendar-heatmap.js';
@@ -62,3 +62,12 @@ import './components/authed-image.js';
62
62
  import './hooks/use-authed-src.js';
63
63
  import './components/image-grid.js';
64
64
  import './components/lightbox.js';
65
+ import './components/write-lock.js';
66
+ import './components/account-chips.js';
67
+ import './lib/format.js';
68
+ import './data-table-3mi2R3so.js';
69
+ import './components/data-table-sort.js';
70
+ import './components/swipeable-row.js';
71
+ import './components/reauth-dialog.js';
72
+ import './components/server-wake.js';
73
+ import './lib/server-wake.js';
@@ -0,0 +1,153 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ import { LucideIcon } from 'lucide-react';
4
+ import { DateInput, FormatDateStyle, FormatRelativeTimeOptions } from '../lib/format.js';
5
+ import { ChipTone, ChipSize, ChipVariant, ChipShape } from './chip.js';
6
+ import { b as DataTableColumn } from '../data-table-3mi2R3so.js';
7
+ import './data-table-sort.js';
8
+ import './swipeable-row.js';
9
+ import './data-table-labels.js';
10
+
11
+ /**
12
+ * The parts an admin roster repeats (0.18.0) — and only those.
13
+ *
14
+ * Kurvenschmiede (features/admin/users-panel.tsx, allowlist-panel.tsx) and keksdose
15
+ * (features/admin/users-panel.tsx, the allowlist card in admin-page.tsx) each built the
16
+ * same table: name over email, a role, whether the account is active, created, last
17
+ * login, a row of actions, and an allowlist with a note. What they share is not the
18
+ * table — the columns around it (keksdose's plan and privacy mode, Kurvenschmiede's
19
+ * owned-work counts and its role SELECT), the actions and every rule about who may do
20
+ * what are each app's own. What they share is the vocabulary: both spelled the same
21
+ * square, uppercase status chip by hand (keksdose's `Badge` with its own tone map,
22
+ * Kurvenschmiede's inline `<Chip size="xs" shape="square" caps>`), and both formatted
23
+ * their two date columns by hand (`toLocaleDateString` in one, a "3 days ago" helper
24
+ * in the other). So: {@link RoleChip}, {@link AccountStateChip} and
25
+ * {@link dateColumn}, and the roster stays the app's `DataTable`.
26
+ */
27
+ /** The chip look both rosters use: a square, uppercase status tag. Each can be changed. */
28
+ interface AccountChipLook {
29
+ /** Default `sm` — keksdose's roster; Kurvenschmiede's denser lists pass `xs`. */
30
+ size?: ChipSize;
31
+ /** Default `soft`. `dot` for a column of them that should not outshout the names. */
32
+ variant?: ChipVariant;
33
+ /** Default `square`: a chip in a table cell, beside square controls. */
34
+ shape?: ChipShape;
35
+ /** Default true — the status-badge type. */
36
+ caps?: boolean;
37
+ className?: string;
38
+ [key: `data-${string}`]: string | number | boolean | undefined;
39
+ }
40
+ /** How one role is drawn. `label` is the app's, translated. */
41
+ interface RoleDefinition {
42
+ label: string;
43
+ tone?: ChipTone;
44
+ /** A lucide component or an element — Kurvenschmiede marks its admins with a shield. */
45
+ icon?: LucideIcon | ReactElement;
46
+ }
47
+ /**
48
+ * Every role an app has, keyed by the value its API sends. Annotate the app's table
49
+ * with it (`const ROLES: RoleVocabulary<UserRole> = {…}`) and TypeScript asks for a
50
+ * label when a role is added.
51
+ */
52
+ type RoleVocabulary<R extends string = string> = Readonly<Record<R, RoleDefinition>>;
53
+ interface RoleChipProps<R extends string = string> extends AccountChipLook {
54
+ /**
55
+ * The role key as the API sends it. `null` / `undefined` renders nothing. Named
56
+ * `value`, not `role`, because `role` on a JSX element is the ARIA role — the lint
57
+ * rule and every reader would take it for one.
58
+ */
59
+ value: R | null | undefined;
60
+ /** What each key is called and how it is toned. A key missing here is shown as the
61
+ * key itself, in `neutral`: an unknown role is still a fact the admin should see. */
62
+ roles: Readonly<Partial<Record<R, RoleDefinition>>>;
63
+ }
64
+ /**
65
+ * A role as a chip: the API's key looked up in the app's {@link RoleVocabulary}.
66
+ *
67
+ * The vocabulary is a prop and not kit English, because the roles are the app's —
68
+ * Kurvenschmiede has admin, member and customer, keksdose admin and user, kastlan its
69
+ * own — and so are their names. Carries `data-role` with the key, for a test or a
70
+ * style hook.
71
+ */
72
+ declare function RoleChip<R extends string = string>({ value: role, roles, size, variant, shape, caps, className, ...rest }: RoleChipProps<R>): react.JSX.Element | null;
73
+ /**
74
+ * The states both rosters show, each as the app's own flag maps onto it:
75
+ *
76
+ * - `active` / `inactive` — the account may sign in, or an admin switched it off
77
+ * (both apps' `is_active`).
78
+ * - `invited` — on the allowlist and mailed, not registered yet (an allowlist row).
79
+ * - `registered` — an allowlist row whose address has an account now (Kurvenschmiede).
80
+ * - `unverified` — the email address is not confirmed (keksdose).
81
+ * - `passwordChange` — must set a new password at the next sign-in (keksdose).
82
+ *
83
+ * An account can be several at once (inactive AND unverified): render one chip per
84
+ * state, as keksdose's state column does.
85
+ */
86
+ type AccountState = "active" | "inactive" | "invited" | "registered" | "unverified" | "passwordChange";
87
+ type AccountStateLabels = Record<AccountState, string>;
88
+ declare const DEFAULT_ACCOUNT_STATE_LABELS: AccountStateLabels;
89
+ /** The default tone of each state: green for the normal case, red for switched off,
90
+ * amber for something the user still has to do, blue for an open invitation. */
91
+ declare const ACCOUNT_STATE_TONES: Readonly<Record<AccountState, ChipTone>>;
92
+ interface AccountStateChipProps extends AccountChipLook {
93
+ state: AccountState;
94
+ /** Over {@link ACCOUNT_STATE_TONES} — Kurvenschmiede draws `inactive` neutral. */
95
+ tone?: ChipTone;
96
+ /** Over the label, for an app whose word for the state is its own ("Deactivated"). */
97
+ children?: ReactNode;
98
+ /** Prop > `<UiKitProvider labels={{ accountState }}>` > English. */
99
+ labels?: Partial<AccountStateLabels>;
100
+ }
101
+ /**
102
+ * An account's state as a chip, in the kit's words and tones. Carries `data-state`
103
+ * with the key.
104
+ */
105
+ declare function AccountStateChip({ state, tone, children, labels: labelsProp, size, variant, shape, caps, className, ...rest }: AccountStateChipProps): react.JSX.Element;
106
+ interface DateMarkProps {
107
+ value: DateInput;
108
+ /**
109
+ * `"date"` (default): the date in `dateStyle` — "Created". `"relative"`: how long
110
+ * ago — "Last login", where the question is "recently?" — with the full date and
111
+ * time in a tooltip (keksdose's last-seen column).
112
+ */
113
+ display?: "date" | "relative";
114
+ /** Default `medium`. Under `"relative"`, the style of the tooltip's date (default
115
+ * `dateTime`) and of the date `relative.absoluteAfterDays` switches to. */
116
+ dateStyle?: FormatDateStyle | Intl.DateTimeFormatOptions;
117
+ /** `formatRelativeTime` options: `numeric`, `style`, `absoluteAfterDays`, `now`. */
118
+ relative?: Omit<FormatRelativeTimeOptions, "locale" | "empty" | "absoluteStyle">;
119
+ /** What a missing value reads as. Default "—"; a last-login column passes its
120
+ * translated "Never". */
121
+ empty?: ReactNode;
122
+ /** Over the provider's locale. */
123
+ locale?: string;
124
+ className?: string;
125
+ }
126
+ /**
127
+ * A date in a table cell: a `<time>` with a machine-readable `dateTime`, nowrap and
128
+ * tabular figures, in the provider's locale — or `empty` when there is none.
129
+ */
130
+ declare function DateMark({ value, display, dateStyle, relative, empty, locale: localeProp, className, }: DateMarkProps): react.JSX.Element;
131
+ interface DateColumnOptions<T> extends Omit<DateMarkProps, "value" | "className"> {
132
+ key: string;
133
+ header: ReactNode;
134
+ /** The value of this row: an ISO string, epoch ms, a Date, or null for none. */
135
+ value: (row: T) => DateInput;
136
+ /** Sortable by the instant; rows with no date sort last either way. Default true. */
137
+ sortable?: boolean;
138
+ /** Default `desc` — a date column is sorted to find the newest. */
139
+ firstSort?: "asc" | "desc";
140
+ /** Add the table's from–to date filter over the column. Default false. */
141
+ filter?: boolean;
142
+ /** Further column settings (`mobileHidden`, `headClassName`, …), merged over. */
143
+ column?: Partial<DataTableColumn<T>>;
144
+ }
145
+ /**
146
+ * A {@link DataTableColumn} for a date: {@link DateMark} cells, sorted by the instant
147
+ * (newest first on the first click), optionally the date filter. The roster's
148
+ * "Created" is `dateColumn({ key, header, value })`; its "Last login" adds
149
+ * `display: "relative", empty: t("never")`.
150
+ */
151
+ declare function dateColumn<T>({ key, header, value, sortable, firstSort, filter, column, ...mark }: DateColumnOptions<T>): DataTableColumn<T>;
152
+
153
+ export { ACCOUNT_STATE_TONES, type AccountState, AccountStateChip, type AccountStateChipProps, type AccountStateLabels, DEFAULT_ACCOUNT_STATE_LABELS, type DateColumnOptions, DateMark, type DateMarkProps, RoleChip, type RoleChipProps, type RoleDefinition, type RoleVocabulary, dateColumn };
@@ -0,0 +1,135 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { cn } from "../lib/cn.js";
4
+ import { formatDate, formatRelativeTime, toDate, EMPTY_FORMATTED_VALUE } from "../lib/format.js";
5
+ import { useKitLabels, useKitLocale } from "../i18n/kit-labels.js";
6
+ import { Chip } from "./chip.js";
7
+ import { Tooltip } from "./tooltip.js";
8
+ function RoleChip({
9
+ value: role,
10
+ roles,
11
+ size = "sm",
12
+ variant,
13
+ shape = "square",
14
+ caps = true,
15
+ className,
16
+ ...rest
17
+ }) {
18
+ if (role === null || role === void 0 || role === "") return null;
19
+ const def = roles[role];
20
+ return /* @__PURE__ */ jsx(
21
+ Chip,
22
+ {
23
+ ...rest,
24
+ "data-role": role,
25
+ tone: def?.tone ?? "neutral",
26
+ icon: def?.icon,
27
+ size,
28
+ variant,
29
+ shape,
30
+ caps,
31
+ className,
32
+ children: def?.label ?? role
33
+ }
34
+ );
35
+ }
36
+ const DEFAULT_ACCOUNT_STATE_LABELS = {
37
+ active: "Active",
38
+ inactive: "Inactive",
39
+ invited: "Invited",
40
+ registered: "Registered",
41
+ unverified: "Unverified",
42
+ passwordChange: "Must change password"
43
+ };
44
+ const ACCOUNT_STATE_TONES = {
45
+ active: "success",
46
+ inactive: "danger",
47
+ invited: "info",
48
+ registered: "neutral",
49
+ unverified: "warning",
50
+ passwordChange: "warning"
51
+ };
52
+ function AccountStateChip({
53
+ state,
54
+ tone,
55
+ children,
56
+ labels: labelsProp,
57
+ size = "sm",
58
+ variant,
59
+ shape = "square",
60
+ caps = true,
61
+ className,
62
+ ...rest
63
+ }) {
64
+ const labels = useKitLabels("accountState", DEFAULT_ACCOUNT_STATE_LABELS, labelsProp);
65
+ return /* @__PURE__ */ jsx(
66
+ Chip,
67
+ {
68
+ ...rest,
69
+ "data-state": state,
70
+ tone: tone ?? ACCOUNT_STATE_TONES[state],
71
+ size,
72
+ variant,
73
+ shape,
74
+ caps,
75
+ className,
76
+ children: children ?? labels[state]
77
+ }
78
+ );
79
+ }
80
+ function DateMark({
81
+ value,
82
+ display = "date",
83
+ dateStyle,
84
+ relative,
85
+ empty = EMPTY_FORMATTED_VALUE,
86
+ locale: localeProp,
87
+ className
88
+ }) {
89
+ const locale = useKitLocale(localeProp);
90
+ const date = toDate(value);
91
+ const cls = cn("whitespace-nowrap tabular-nums", className);
92
+ if (!date) return /* @__PURE__ */ jsx("span", { className: cn(cls, "text-[var(--text-muted)]"), children: empty });
93
+ if (display === "date") {
94
+ return /* @__PURE__ */ jsx("time", { dateTime: date.toISOString(), className: cls, children: formatDate(date, dateStyle ?? "medium", { locale }) });
95
+ }
96
+ const text = formatRelativeTime(date, { ...relative, locale, absoluteStyle: dateStyle ?? "medium" });
97
+ return /* @__PURE__ */ jsx(Tooltip, { label: formatDate(date, dateStyle ?? "dateTime", { locale }), lazy: true, children: /* @__PURE__ */ jsx("time", { dateTime: date.toISOString(), className: cls, children: text }) });
98
+ }
99
+ function dateColumn({
100
+ key,
101
+ header,
102
+ value,
103
+ sortable = true,
104
+ firstSort = "desc",
105
+ filter = false,
106
+ column,
107
+ ...mark
108
+ }) {
109
+ return {
110
+ key,
111
+ header,
112
+ cell: (row) => /* @__PURE__ */ jsx(DateMark, { value: value(row), ...mark }),
113
+ sortBy: sortable ? (row) => toDate(value(row))?.getTime() ?? null : void 0,
114
+ firstSort: sortable ? firstSort : void 0,
115
+ filter: filter ? {
116
+ type: "date",
117
+ // The filter compares the first ten characters, so hand it an ISO string.
118
+ getValue: (row) => {
119
+ const raw = value(row);
120
+ if (typeof raw === "string") return raw;
121
+ return toDate(raw)?.toISOString() ?? null;
122
+ }
123
+ } : void 0,
124
+ ...column
125
+ };
126
+ }
127
+ export {
128
+ ACCOUNT_STATE_TONES,
129
+ AccountStateChip,
130
+ DEFAULT_ACCOUNT_STATE_LABELS,
131
+ DateMark,
132
+ RoleChip,
133
+ dateColumn
134
+ };
135
+ //# sourceMappingURL=account-chips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/account-chips.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { formatDate, formatRelativeTime, toDate, EMPTY_FORMATTED_VALUE } from \"../lib/format\";\nimport type { DateInput, FormatDateStyle, FormatRelativeTimeOptions } from \"../lib/format\";\nimport { useKitLabels, useKitLocale } from \"../i18n/kit-labels\";\nimport { Chip } from \"./chip\";\nimport type { ChipShape, ChipSize, ChipTone, ChipVariant } from \"./chip\";\nimport { Tooltip } from \"./tooltip\";\nimport type { DataTableColumn } from \"./data-table\";\n\n/**\n * The parts an admin roster repeats (0.18.0) — and only those.\n *\n * Kurvenschmiede (features/admin/users-panel.tsx, allowlist-panel.tsx) and keksdose\n * (features/admin/users-panel.tsx, the allowlist card in admin-page.tsx) each built the\n * same table: name over email, a role, whether the account is active, created, last\n * login, a row of actions, and an allowlist with a note. What they share is not the\n * table — the columns around it (keksdose's plan and privacy mode, Kurvenschmiede's\n * owned-work counts and its role SELECT), the actions and every rule about who may do\n * what are each app's own. What they share is the vocabulary: both spelled the same\n * square, uppercase status chip by hand (keksdose's `Badge` with its own tone map,\n * Kurvenschmiede's inline `<Chip size=\"xs\" shape=\"square\" caps>`), and both formatted\n * their two date columns by hand (`toLocaleDateString` in one, a \"3 days ago\" helper\n * in the other). So: {@link RoleChip}, {@link AccountStateChip} and\n * {@link dateColumn}, and the roster stays the app's `DataTable`.\n */\n\n/** The chip look both rosters use: a square, uppercase status tag. Each can be changed. */\ninterface AccountChipLook {\n /** Default `sm` — keksdose's roster; Kurvenschmiede's denser lists pass `xs`. */\n size?: ChipSize;\n /** Default `soft`. `dot` for a column of them that should not outshout the names. */\n variant?: ChipVariant;\n /** Default `square`: a chip in a table cell, beside square controls. */\n shape?: ChipShape;\n /** Default true — the status-badge type. */\n caps?: boolean;\n className?: string;\n [key: `data-${string}`]: string | number | boolean | undefined;\n}\n\n/* ── RoleChip ──────────────────────────────────────────────────────────────── */\n\n/** How one role is drawn. `label` is the app's, translated. */\nexport interface RoleDefinition {\n label: string;\n tone?: ChipTone;\n /** A lucide component or an element — Kurvenschmiede marks its admins with a shield. */\n icon?: LucideIcon | ReactElement;\n}\n\n/**\n * Every role an app has, keyed by the value its API sends. Annotate the app's table\n * with it (`const ROLES: RoleVocabulary<UserRole> = {…}`) and TypeScript asks for a\n * label when a role is added.\n */\nexport type RoleVocabulary<R extends string = string> = Readonly<Record<R, RoleDefinition>>;\n\nexport interface RoleChipProps<R extends string = string> extends AccountChipLook {\n /**\n * The role key as the API sends it. `null` / `undefined` renders nothing. Named\n * `value`, not `role`, because `role` on a JSX element is the ARIA role — the lint\n * rule and every reader would take it for one.\n */\n value: R | null | undefined;\n /** What each key is called and how it is toned. A key missing here is shown as the\n * key itself, in `neutral`: an unknown role is still a fact the admin should see. */\n roles: Readonly<Partial<Record<R, RoleDefinition>>>;\n}\n\n/**\n * A role as a chip: the API's key looked up in the app's {@link RoleVocabulary}.\n *\n * The vocabulary is a prop and not kit English, because the roles are the app's —\n * Kurvenschmiede has admin, member and customer, keksdose admin and user, kastlan its\n * own — and so are their names. Carries `data-role` with the key, for a test or a\n * style hook.\n */\nexport function RoleChip<R extends string = string>({\n value: role,\n roles,\n size = \"sm\",\n variant,\n shape = \"square\",\n caps = true,\n className,\n ...rest\n}: RoleChipProps<R>) {\n if (role === null || role === undefined || role === \"\") return null;\n const def = roles[role];\n return (\n <Chip\n {...rest}\n data-role={role}\n tone={def?.tone ?? \"neutral\"}\n icon={def?.icon}\n size={size}\n variant={variant}\n shape={shape}\n caps={caps}\n className={className}\n >\n {def?.label ?? role}\n </Chip>\n );\n}\n\n/* ── AccountStateChip ──────────────────────────────────────────────────────── */\n\n/**\n * The states both rosters show, each as the app's own flag maps onto it:\n *\n * - `active` / `inactive` — the account may sign in, or an admin switched it off\n * (both apps' `is_active`).\n * - `invited` — on the allowlist and mailed, not registered yet (an allowlist row).\n * - `registered` — an allowlist row whose address has an account now (Kurvenschmiede).\n * - `unverified` — the email address is not confirmed (keksdose).\n * - `passwordChange` — must set a new password at the next sign-in (keksdose).\n *\n * An account can be several at once (inactive AND unverified): render one chip per\n * state, as keksdose's state column does.\n */\nexport type AccountState = \"active\" | \"inactive\" | \"invited\" | \"registered\" | \"unverified\" | \"passwordChange\";\n\nexport type AccountStateLabels = Record<AccountState, string>;\n\nexport const DEFAULT_ACCOUNT_STATE_LABELS: AccountStateLabels = {\n active: \"Active\",\n inactive: \"Inactive\",\n invited: \"Invited\",\n registered: \"Registered\",\n unverified: \"Unverified\",\n passwordChange: \"Must change password\",\n};\n\n/** The default tone of each state: green for the normal case, red for switched off,\n * amber for something the user still has to do, blue for an open invitation. */\nexport const ACCOUNT_STATE_TONES: Readonly<Record<AccountState, ChipTone>> = {\n active: \"success\",\n inactive: \"danger\",\n invited: \"info\",\n registered: \"neutral\",\n unverified: \"warning\",\n passwordChange: \"warning\",\n};\n\nexport interface AccountStateChipProps extends AccountChipLook {\n state: AccountState;\n /** Over {@link ACCOUNT_STATE_TONES} — Kurvenschmiede draws `inactive` neutral. */\n tone?: ChipTone;\n /** Over the label, for an app whose word for the state is its own (\"Deactivated\"). */\n children?: ReactNode;\n /** Prop > `<UiKitProvider labels={{ accountState }}>` > English. */\n labels?: Partial<AccountStateLabels>;\n}\n\n/**\n * An account's state as a chip, in the kit's words and tones. Carries `data-state`\n * with the key.\n */\nexport function AccountStateChip({\n state,\n tone,\n children,\n labels: labelsProp,\n size = \"sm\",\n variant,\n shape = \"square\",\n caps = true,\n className,\n ...rest\n}: AccountStateChipProps) {\n // An `undefined` in the prop is skipped (the provider's merge does that), so an\n // optional value cannot blank a default.\n const labels = useKitLabels(\"accountState\", DEFAULT_ACCOUNT_STATE_LABELS, labelsProp);\n return (\n <Chip\n {...rest}\n data-state={state}\n tone={tone ?? ACCOUNT_STATE_TONES[state]}\n size={size}\n variant={variant}\n shape={shape}\n caps={caps}\n className={className}\n >\n {children ?? labels[state]}\n </Chip>\n );\n}\n\n/* ── Date columns ──────────────────────────────────────────────────────────── */\n\nexport interface DateMarkProps {\n value: DateInput;\n /**\n * `\"date\"` (default): the date in `dateStyle` — \"Created\". `\"relative\"`: how long\n * ago — \"Last login\", where the question is \"recently?\" — with the full date and\n * time in a tooltip (keksdose's last-seen column).\n */\n display?: \"date\" | \"relative\";\n /** Default `medium`. Under `\"relative\"`, the style of the tooltip's date (default\n * `dateTime`) and of the date `relative.absoluteAfterDays` switches to. */\n dateStyle?: FormatDateStyle | Intl.DateTimeFormatOptions;\n /** `formatRelativeTime` options: `numeric`, `style`, `absoluteAfterDays`, `now`. */\n relative?: Omit<FormatRelativeTimeOptions, \"locale\" | \"empty\" | \"absoluteStyle\">;\n /** What a missing value reads as. Default \"—\"; a last-login column passes its\n * translated \"Never\". */\n empty?: ReactNode;\n /** Over the provider's locale. */\n locale?: string;\n className?: string;\n}\n\n/**\n * A date in a table cell: a `<time>` with a machine-readable `dateTime`, nowrap and\n * tabular figures, in the provider's locale — or `empty` when there is none.\n */\nexport function DateMark({\n value,\n display = \"date\",\n dateStyle,\n relative,\n empty = EMPTY_FORMATTED_VALUE,\n locale: localeProp,\n className,\n}: DateMarkProps) {\n const locale = useKitLocale(localeProp);\n const date = toDate(value);\n const cls = cn(\"whitespace-nowrap tabular-nums\", className);\n if (!date) return <span className={cn(cls, \"text-[var(--text-muted)]\")}>{empty}</span>;\n if (display === \"date\") {\n return (\n <time dateTime={date.toISOString()} className={cls}>\n {formatDate(date, dateStyle ?? \"medium\", { locale })}\n </time>\n );\n }\n const text = formatRelativeTime(date, { ...relative, locale, absoluteStyle: dateStyle ?? \"medium\" });\n return (\n <Tooltip label={formatDate(date, dateStyle ?? \"dateTime\", { locale })} lazy>\n {/* Not a tab stop: a roster of fifty rows would be fifty more of them, and the\n relative words already answer the column's question; the exact time is extra. */}\n <time dateTime={date.toISOString()} className={cls}>\n {text}\n </time>\n </Tooltip>\n );\n}\n\nexport interface DateColumnOptions<T> extends Omit<DateMarkProps, \"value\" | \"className\"> {\n key: string;\n header: ReactNode;\n /** The value of this row: an ISO string, epoch ms, a Date, or null for none. */\n value: (row: T) => DateInput;\n /** Sortable by the instant; rows with no date sort last either way. Default true. */\n sortable?: boolean;\n /** Default `desc` — a date column is sorted to find the newest. */\n firstSort?: \"asc\" | \"desc\";\n /** Add the table's from–to date filter over the column. Default false. */\n filter?: boolean;\n /** Further column settings (`mobileHidden`, `headClassName`, …), merged over. */\n column?: Partial<DataTableColumn<T>>;\n}\n\n/**\n * A {@link DataTableColumn} for a date: {@link DateMark} cells, sorted by the instant\n * (newest first on the first click), optionally the date filter. The roster's\n * \"Created\" is `dateColumn({ key, header, value })`; its \"Last login\" adds\n * `display: \"relative\", empty: t(\"never\")`.\n */\nexport function dateColumn<T>({\n key,\n header,\n value,\n sortable = true,\n firstSort = \"desc\",\n filter = false,\n column,\n ...mark\n}: DateColumnOptions<T>): DataTableColumn<T> {\n return {\n key,\n header,\n cell: (row) => <DateMark value={value(row)} {...mark} />,\n sortBy: sortable ? (row) => toDate(value(row))?.getTime() ?? null : undefined,\n firstSort: sortable ? firstSort : undefined,\n filter: filter\n ? {\n type: \"date\",\n // The filter compares the first ten characters, so hand it an ISO string.\n getValue: (row) => {\n const raw = value(row);\n if (typeof raw === \"string\") return raw;\n return toDate(raw)?.toISOString() ?? null;\n },\n }\n : undefined,\n ...column,\n };\n}\n"],"mappings":";AA4FI;AA1FJ,SAAS,UAAU;AACnB,SAAS,YAAY,oBAAoB,QAAQ,6BAA6B;AAE9E,SAAS,cAAc,oBAAoB;AAC3C,SAAS,YAAY;AAErB,SAAS,eAAe;AAuEjB,SAAS,SAAoC;AAAA,EAClD,OAAO;AAAA,EACP;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAAqB;AACnB,MAAI,SAAS,QAAQ,SAAS,UAAa,SAAS,GAAI,QAAO;AAC/D,QAAM,MAAM,MAAM,IAAI;AACtB,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,aAAW;AAAA,MACX,MAAM,KAAK,QAAQ;AAAA,MACnB,MAAM,KAAK;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEC,eAAK,SAAS;AAAA;AAAA,EACjB;AAEJ;AAqBO,MAAM,+BAAmD;AAAA,EAC9D,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAIO,MAAM,sBAAgE;AAAA,EAC3E,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,gBAAgB;AAClB;AAgBO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAA0B;AAGxB,QAAM,SAAS,aAAa,gBAAgB,8BAA8B,UAAU;AACpF,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,cAAY;AAAA,MACZ,MAAM,QAAQ,oBAAoB,KAAK;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEC,sBAAY,OAAO,KAAK;AAAA;AAAA,EAC3B;AAEJ;AA6BO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR;AACF,GAAkB;AAChB,QAAM,SAAS,aAAa,UAAU;AACtC,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,MAAM,GAAG,kCAAkC,SAAS;AAC1D,MAAI,CAAC,KAAM,QAAO,oBAAC,UAAK,WAAW,GAAG,KAAK,0BAA0B,GAAI,iBAAM;AAC/E,MAAI,YAAY,QAAQ;AACtB,WACE,oBAAC,UAAK,UAAU,KAAK,YAAY,GAAG,WAAW,KAC5C,qBAAW,MAAM,aAAa,UAAU,EAAE,OAAO,CAAC,GACrD;AAAA,EAEJ;AACA,QAAM,OAAO,mBAAmB,MAAM,EAAE,GAAG,UAAU,QAAQ,eAAe,aAAa,SAAS,CAAC;AACnG,SACE,oBAAC,WAAQ,OAAO,WAAW,MAAM,aAAa,YAAY,EAAE,OAAO,CAAC,GAAG,MAAI,MAGzE,8BAAC,UAAK,UAAU,KAAK,YAAY,GAAG,WAAW,KAC5C,gBACH,GACF;AAEJ;AAuBO,SAAS,WAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,SAAS;AAAA,EACT;AAAA,EACA,GAAG;AACL,GAA6C;AAC3C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,CAAC,QAAQ,oBAAC,YAAS,OAAO,MAAM,GAAG,GAAI,GAAG,MAAM;AAAA,IACtD,QAAQ,WAAW,CAAC,QAAQ,OAAO,MAAM,GAAG,CAAC,GAAG,QAAQ,KAAK,OAAO;AAAA,IACpE,WAAW,WAAW,YAAY;AAAA,IAClC,QAAQ,SACJ;AAAA,MACE,MAAM;AAAA;AAAA,MAEN,UAAU,CAAC,QAAQ;AACjB,cAAM,MAAM,MAAM,GAAG;AACrB,YAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,eAAO,OAAO,GAAG,GAAG,YAAY,KAAK;AAAA,MACvC;AAAA,IACF,IACA;AAAA,IACJ,GAAG;AAAA,EACL;AACF;","names":[]}
@@ -56,8 +56,16 @@ interface TwoFactorSettingLabels {
56
56
  }
57
57
  interface PasskeysSettingLabels {
58
58
  title: string;
59
- /** The line under the title saying what a passkey is for. */
59
+ /** The line under the title saying what a passkey is for — `mode="instead"` (the
60
+ * default): the passkey stands in for the password. */
60
61
  description: string;
62
+ /**
63
+ * The same line for `mode="alongside"` (0.18.0): the password keeps working and the
64
+ * passkey is a second way in. OPTIONAL for the reason `TwoFactorSettingLabels.qrAlt`
65
+ * is — this interface is annotated at call sites — and filled from the provider's
66
+ * `accountSettings.passkeys`, then English.
67
+ */
68
+ descriptionAlongside?: string;
61
69
  empty: string;
62
70
  loading: string;
63
71
  /** Accessible name of the list. */
@@ -91,7 +99,7 @@ interface AccountSettingsLabels {
91
99
  profile: ProfileSettingLabels;
92
100
  password: PasswordSettingLabels;
93
101
  twoFactor: Required<TwoFactorSettingLabels>;
94
- passkeys: PasskeysSettingLabels;
102
+ passkeys: Required<PasskeysSettingLabels>;
95
103
  }
96
104
  declare const DEFAULT_ACCOUNT_SETTINGS_LABELS: AccountSettingsLabels;
97
105
  /**
@@ -38,6 +38,9 @@ const DEFAULT_ACCOUNT_SETTINGS_LABELS = {
38
38
  passkeys: {
39
39
  title: "Passkeys",
40
40
  description: "Sign in with your fingerprint, face or device PIN instead of a password.",
41
+ // Kurvenschmiede overrode `description` because "instead of" is false where the
42
+ // password stays; this is the sentence for those apps, picked by `mode`.
43
+ descriptionAlongside: "Sign in with your fingerprint, face or device PIN. Your password keeps working too.",
41
44
  empty: "No passkeys yet",
42
45
  loading: "Loading passkeys\u2026",
43
46
  list: "Your passkeys",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/account-settings-labels.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useKitLabelOverrides } from \"../i18n/kit-labels\";\n\n/**\n * The `accountSettings` namespace of `<UiKitProvider labels>`: one record per section —\n * `profile`, `password`, `twoFactor`, `passkeys` — each merged key by key, so an app\n * can translate `accountSettings.twoFactor.scanHint` alone.\n *\n * Before 0.12.0 every section took a REQUIRED `labels` prop and had no English of its\n * own, so each app spelled out 30-odd keys at the call site and still hard-coded some\n * (kastlan's profile page passed `email: \"Email\"` in English to a German page). The\n * prop stays, now partial, and wins over the provider as everywhere else in the kit.\n *\n * Its own module, beside the components rather than in them, so `PasskeysSetting`\n * (its own file) and the older three read one tree without importing each other.\n */\n\nexport interface ProfileSettingLabels {\n title: string;\n email: string;\n role: string;\n memberSince: string;\n displayName: string;\n save: string;\n}\n\nexport interface PasswordSettingLabels {\n title: string;\n current: string;\n next: string;\n confirm: string;\n submit: string;\n tooShort: string;\n mismatch: string;\n}\n\nexport interface TwoFactorSettingLabels {\n status: string;\n enabledText: string;\n disabledText: string;\n enable: string;\n scanHint: string;\n codeLabel: string;\n verify: string;\n disableSection: string;\n password: string;\n disable: string;\n /**\n * Alt text for the setup QR code, which shipped as a hardcoded `alt=\"QR\"`.\n *\n * OPTIONAL, like the two keys below, and not because it matters less: this interface\n * is annotated at consumer call sites (`const LABELS: TwoFactorSettingLabels = {…}`),\n * so a new REQUIRED key is a compile error in every app on the next `npm update` —\n * the additive-API rule in the README. Each falls back to the provider's\n * `accountSettings.twoFactor`, then English.\n */\n qrAlt?: string;\n /** The line over the manual-entry key, for a phone that cannot scan its own screen. */\n secretHint?: string;\n /** The copy button beside that key. */\n copySecret?: string;\n}\n\nexport interface PasskeysSettingLabels {\n title: string;\n /** The line under the title saying what a passkey is for. */\n description: string;\n empty: string;\n loading: string;\n /** Accessible name of the list. */\n list: string;\n nameLabel: string;\n namePlaceholder: string;\n add: string;\n /** The add button while the app's WebAuthn ceremony runs — the OS prompt is open. */\n adding: string;\n rename: string;\n /** The row's rename button, named for its passkey — it starts with `rename`, the\n * visible text, so voice control finds it by what it says. */\n renameItem: (name: string) => string;\n /** Accessible name of the inline rename field. */\n renameField: (name: string) => string;\n save: string;\n cancel: string;\n delete: string;\n /** The row's delete button, named for its passkey (see `renameItem`). */\n deleteItem: (name: string) => string;\n /** The inline question a delete asks first. */\n deleteConfirm: (name: string) => string;\n /** The destructive button that answers it. */\n confirmDelete: string;\n /** `date` arrives formatted in the provider's locale. */\n created: (date: string) => string;\n lastUsed: (date: string) => string;\n neverUsed: string;\n}\n\nexport interface AccountSettingsLabels {\n profile: ProfileSettingLabels;\n password: PasswordSettingLabels;\n twoFactor: Required<TwoFactorSettingLabels>;\n passkeys: PasskeysSettingLabels;\n}\n\nexport const DEFAULT_ACCOUNT_SETTINGS_LABELS: AccountSettingsLabels = {\n profile: {\n title: \"Profile\",\n email: \"Email\",\n role: \"Role\",\n memberSince: \"Member since\",\n displayName: \"Display name\",\n save: \"Save\",\n },\n password: {\n title: \"Change password\",\n current: \"Current password\",\n next: \"New password\",\n confirm: \"Confirm new password\",\n submit: \"Change password\",\n tooShort: \"The new password is too short.\",\n mismatch: \"The passwords don’t match.\",\n },\n twoFactor: {\n status: \"Two-factor authentication\",\n enabledText: \"On\",\n disabledText: \"Off\",\n enable: \"Set up two-factor authentication\",\n scanHint: \"Scan this code with your authenticator app, then enter the code it shows.\",\n codeLabel: \"Verification code\",\n verify: \"Verify and turn on\",\n disableSection: \"Turn off two-factor authentication\",\n password: \"Current password\",\n disable: \"Turn off\",\n // Unchanged from the fallback it had before the namespace (i18n-labels.test pins it).\n qrAlt: \"QR code\",\n secretHint: \"Can’t scan it? Enter this key in the app instead:\",\n copySecret: \"Copy key\",\n },\n passkeys: {\n title: \"Passkeys\",\n description: \"Sign in with your fingerprint, face or device PIN instead of a password.\",\n empty: \"No passkeys yet\",\n loading: \"Loading passkeys…\",\n list: \"Your passkeys\",\n nameLabel: \"Name (optional)\",\n namePlaceholder: \"e.g. Laptop, Phone\",\n add: \"Add passkey\",\n adding: \"Waiting for your device…\",\n rename: \"Rename\",\n renameItem: (name) => `Rename ${name}`,\n renameField: (name) => `New name for ${name}`,\n save: \"Save\",\n cancel: \"Cancel\",\n delete: \"Delete\",\n deleteItem: (name) => `Delete ${name}`,\n deleteConfirm: (name) => `Delete “${name}”? It can no longer be used to sign in.`,\n confirmDelete: \"Delete passkey\",\n created: (date) => `Added ${date}`,\n lastUsed: (date) => `Last used ${date}`,\n neverUsed: \"Never used\",\n },\n};\n\n/**\n * One section of the namespace, resolved: English, then the provider's\n * `accountSettings.<section>`, then the component's own `labels` prop. An `undefined`\n * in either source is skipped, so a prop object built from optional values cannot\n * blank out a default.\n */\nexport function useAccountSettingsLabels<K extends keyof AccountSettingsLabels>(\n section: K,\n prop?: Partial<AccountSettingsLabels[K]>,\n): AccountSettingsLabels[K] {\n const fromProvider = useKitLabelOverrides(\"accountSettings\")?.[section] as\n | Partial<AccountSettingsLabels[K]>\n | undefined;\n return useMemo(\n () => ({\n ...DEFAULT_ACCOUNT_SETTINGS_LABELS[section],\n ...definedOnly(fromProvider),\n ...definedOnly(prop),\n }),\n [section, fromProvider, prop],\n );\n}\n\nfunction definedOnly<T extends object>(value: T | undefined): Partial<T> {\n if (!value) return {};\n return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,4BAA4B;AAuG9B,MAAM,kCAAyD;AAAA,EACpE,SAAS;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IAET,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY,CAAC,SAAS,UAAU,IAAI;AAAA,IACpC,aAAa,CAAC,SAAS,gBAAgB,IAAI;AAAA,IAC3C,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY,CAAC,SAAS,UAAU,IAAI;AAAA,IACpC,eAAe,CAAC,SAAS,gBAAW,IAAI;AAAA,IACxC,eAAe;AAAA,IACf,SAAS,CAAC,SAAS,SAAS,IAAI;AAAA,IAChC,UAAU,CAAC,SAAS,aAAa,IAAI;AAAA,IACrC,WAAW;AAAA,EACb;AACF;AAQO,SAAS,yBACd,SACA,MAC0B;AAC1B,QAAM,eAAe,qBAAqB,iBAAiB,IAAI,OAAO;AAGtE,SAAO;AAAA,IACL,OAAO;AAAA,MACL,GAAG,gCAAgC,OAAO;AAAA,MAC1C,GAAG,YAAY,YAAY;AAAA,MAC3B,GAAG,YAAY,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,SAAS,cAAc,IAAI;AAAA,EAC9B;AACF;AAEA,SAAS,YAA8B,OAAkC;AACvE,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,CAAC;AACpF;","names":[]}
1
+ {"version":3,"sources":["../../src/components/account-settings-labels.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useKitLabelOverrides } from \"../i18n/kit-labels\";\n\n/**\n * The `accountSettings` namespace of `<UiKitProvider labels>`: one record per section —\n * `profile`, `password`, `twoFactor`, `passkeys` — each merged key by key, so an app\n * can translate `accountSettings.twoFactor.scanHint` alone.\n *\n * Before 0.12.0 every section took a REQUIRED `labels` prop and had no English of its\n * own, so each app spelled out 30-odd keys at the call site and still hard-coded some\n * (kastlan's profile page passed `email: \"Email\"` in English to a German page). The\n * prop stays, now partial, and wins over the provider as everywhere else in the kit.\n *\n * Its own module, beside the components rather than in them, so `PasskeysSetting`\n * (its own file) and the older three read one tree without importing each other.\n */\n\nexport interface ProfileSettingLabels {\n title: string;\n email: string;\n role: string;\n memberSince: string;\n displayName: string;\n save: string;\n}\n\nexport interface PasswordSettingLabels {\n title: string;\n current: string;\n next: string;\n confirm: string;\n submit: string;\n tooShort: string;\n mismatch: string;\n}\n\nexport interface TwoFactorSettingLabels {\n status: string;\n enabledText: string;\n disabledText: string;\n enable: string;\n scanHint: string;\n codeLabel: string;\n verify: string;\n disableSection: string;\n password: string;\n disable: string;\n /**\n * Alt text for the setup QR code, which shipped as a hardcoded `alt=\"QR\"`.\n *\n * OPTIONAL, like the two keys below, and not because it matters less: this interface\n * is annotated at consumer call sites (`const LABELS: TwoFactorSettingLabels = {…}`),\n * so a new REQUIRED key is a compile error in every app on the next `npm update` —\n * the additive-API rule in the README. Each falls back to the provider's\n * `accountSettings.twoFactor`, then English.\n */\n qrAlt?: string;\n /** The line over the manual-entry key, for a phone that cannot scan its own screen. */\n secretHint?: string;\n /** The copy button beside that key. */\n copySecret?: string;\n}\n\nexport interface PasskeysSettingLabels {\n title: string;\n /** The line under the title saying what a passkey is for — `mode=\"instead\"` (the\n * default): the passkey stands in for the password. */\n description: string;\n /**\n * The same line for `mode=\"alongside\"` (0.18.0): the password keeps working and the\n * passkey is a second way in. OPTIONAL for the reason `TwoFactorSettingLabels.qrAlt`\n * is — this interface is annotated at call sites — and filled from the provider's\n * `accountSettings.passkeys`, then English.\n */\n descriptionAlongside?: string;\n empty: string;\n loading: string;\n /** Accessible name of the list. */\n list: string;\n nameLabel: string;\n namePlaceholder: string;\n add: string;\n /** The add button while the app's WebAuthn ceremony runs — the OS prompt is open. */\n adding: string;\n rename: string;\n /** The row's rename button, named for its passkey — it starts with `rename`, the\n * visible text, so voice control finds it by what it says. */\n renameItem: (name: string) => string;\n /** Accessible name of the inline rename field. */\n renameField: (name: string) => string;\n save: string;\n cancel: string;\n delete: string;\n /** The row's delete button, named for its passkey (see `renameItem`). */\n deleteItem: (name: string) => string;\n /** The inline question a delete asks first. */\n deleteConfirm: (name: string) => string;\n /** The destructive button that answers it. */\n confirmDelete: string;\n /** `date` arrives formatted in the provider's locale. */\n created: (date: string) => string;\n lastUsed: (date: string) => string;\n neverUsed: string;\n}\n\nexport interface AccountSettingsLabels {\n profile: ProfileSettingLabels;\n password: PasswordSettingLabels;\n // `Required` here, optional on the section interfaces: the namespace is what a full\n // catalogue (`@eifi1/ui-kit/i18n/<code>`, `missingKitLabels`) is written against, so\n // it must name the late keys; the section interfaces are annotated at call sites.\n twoFactor: Required<TwoFactorSettingLabels>;\n passkeys: Required<PasskeysSettingLabels>;\n}\n\nexport const DEFAULT_ACCOUNT_SETTINGS_LABELS: AccountSettingsLabels = {\n profile: {\n title: \"Profile\",\n email: \"Email\",\n role: \"Role\",\n memberSince: \"Member since\",\n displayName: \"Display name\",\n save: \"Save\",\n },\n password: {\n title: \"Change password\",\n current: \"Current password\",\n next: \"New password\",\n confirm: \"Confirm new password\",\n submit: \"Change password\",\n tooShort: \"The new password is too short.\",\n mismatch: \"The passwords don’t match.\",\n },\n twoFactor: {\n status: \"Two-factor authentication\",\n enabledText: \"On\",\n disabledText: \"Off\",\n enable: \"Set up two-factor authentication\",\n scanHint: \"Scan this code with your authenticator app, then enter the code it shows.\",\n codeLabel: \"Verification code\",\n verify: \"Verify and turn on\",\n disableSection: \"Turn off two-factor authentication\",\n password: \"Current password\",\n disable: \"Turn off\",\n // Unchanged from the fallback it had before the namespace (i18n-labels.test pins it).\n qrAlt: \"QR code\",\n secretHint: \"Can’t scan it? Enter this key in the app instead:\",\n copySecret: \"Copy key\",\n },\n passkeys: {\n title: \"Passkeys\",\n description: \"Sign in with your fingerprint, face or device PIN instead of a password.\",\n // Kurvenschmiede overrode `description` because \"instead of\" is false where the\n // password stays; this is the sentence for those apps, picked by `mode`.\n descriptionAlongside: \"Sign in with your fingerprint, face or device PIN. Your password keeps working too.\",\n empty: \"No passkeys yet\",\n loading: \"Loading passkeys…\",\n list: \"Your passkeys\",\n nameLabel: \"Name (optional)\",\n namePlaceholder: \"e.g. Laptop, Phone\",\n add: \"Add passkey\",\n adding: \"Waiting for your device…\",\n rename: \"Rename\",\n renameItem: (name) => `Rename ${name}`,\n renameField: (name) => `New name for ${name}`,\n save: \"Save\",\n cancel: \"Cancel\",\n delete: \"Delete\",\n deleteItem: (name) => `Delete ${name}`,\n deleteConfirm: (name) => `Delete “${name}”? It can no longer be used to sign in.`,\n confirmDelete: \"Delete passkey\",\n created: (date) => `Added ${date}`,\n lastUsed: (date) => `Last used ${date}`,\n neverUsed: \"Never used\",\n },\n};\n\n/**\n * One section of the namespace, resolved: English, then the provider's\n * `accountSettings.<section>`, then the component's own `labels` prop. An `undefined`\n * in either source is skipped, so a prop object built from optional values cannot\n * blank out a default.\n */\nexport function useAccountSettingsLabels<K extends keyof AccountSettingsLabels>(\n section: K,\n prop?: Partial<AccountSettingsLabels[K]>,\n): AccountSettingsLabels[K] {\n const fromProvider = useKitLabelOverrides(\"accountSettings\")?.[section] as\n | Partial<AccountSettingsLabels[K]>\n | undefined;\n return useMemo(\n () => ({\n ...DEFAULT_ACCOUNT_SETTINGS_LABELS[section],\n ...definedOnly(fromProvider),\n ...definedOnly(prop),\n }),\n [section, fromProvider, prop],\n );\n}\n\nfunction definedOnly<T extends object>(value: T | undefined): Partial<T> {\n if (!value) return {};\n return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,4BAA4B;AAkH9B,MAAM,kCAAyD;AAAA,EACpE,SAAS;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,IAET,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA;AAAA;AAAA,IAGb,sBAAsB;AAAA,IACtB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY,CAAC,SAAS,UAAU,IAAI;AAAA,IACpC,aAAa,CAAC,SAAS,gBAAgB,IAAI;AAAA,IAC3C,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY,CAAC,SAAS,UAAU,IAAI;AAAA,IACpC,eAAe,CAAC,SAAS,gBAAW,IAAI;AAAA,IACxC,eAAe;AAAA,IACf,SAAS,CAAC,SAAS,SAAS,IAAI;AAAA,IAChC,UAAU,CAAC,SAAS,aAAa,IAAI;AAAA,IACrC,WAAW;AAAA,EACb;AACF;AAQO,SAAS,yBACd,SACA,MAC0B;AAC1B,QAAM,eAAe,qBAAqB,iBAAiB,IAAI,OAAO;AAGtE,SAAO;AAAA,IACL,OAAO;AAAA,MACL,GAAG,gCAAgC,OAAO;AAAA,MAC1C,GAAG,YAAY,YAAY;AAAA,MAC3B,GAAG,YAAY,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,SAAS,cAAc,IAAI;AAAA,EAC9B;AACF;AAEA,SAAS,YAA8B,OAAkC;AACvE,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,CAAC;AACpF;","names":[]}
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { CalculatorButtonLabels } from './calculator.js';
4
4
  import { NumberPadSheetLabels } from './numpad-sheet.js';
5
- import '../kit-labels-DE--LmCk.js';
5
+ import '../kit-labels-CPbsjlXr.js';
6
6
  import './data-table-labels.js';
7
7
  import './mini-calendar.js';
8
8
  import './calendar-heatmap.js';
@@ -53,6 +53,15 @@ import './authed-image.js';
53
53
  import '../hooks/use-authed-src.js';
54
54
  import './image-grid.js';
55
55
  import './lightbox.js';
56
+ import './write-lock.js';
57
+ import './account-chips.js';
58
+ import '../lib/format.js';
59
+ import '../data-table-3mi2R3so.js';
60
+ import './data-table-sort.js';
61
+ import './swipeable-row.js';
62
+ import './reauth-dialog.js';
63
+ import './server-wake.js';
64
+ import '../lib/server-wake.js';
56
65
 
57
66
  interface AmountInputProps {
58
67
  value: string;
@@ -203,6 +212,14 @@ interface AmountInputProps {
203
212
  * 1.789 €/l is stored as 123.46 / 1.79, and no test fails (keksdose G2, a
204
213
  * `Numeric(18,6)` holding price and a `Numeric(18,4)` unit price). Pass the column's
205
214
  * scale: `digits={4}`, `digits={6}`.
215
+ *
216
+ * **Set `digits` for any sub-currency scale** — not only a price: any field whose
217
+ * column holds more decimals than the currency's minor unit. A split line stored at
218
+ * the ledger's 4dp (`Numeric(18,4)`) and loaded as 12.3456 is SHOWN as 12.35, and
219
+ * committed as 12.35 as soon as the user tabs through it (blur settles) — so the form
220
+ * no longer equals what the server holds: the lines stop summing to the 4dp total,
221
+ * and Save is held (keksdose live #240). With a `currency`, every commit rounds to that currency's
222
+ * minor unit unless `digits` says otherwise: pass the column's scale (`digits={4}`).
206
223
  */
207
224
  digits?: number;
208
225
  /** The smallest amount the field settles on. A lower figure is raised to it when it