@eifi1/ui-kit 0.12.0 → 0.13.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 (197) hide show
  1. package/README.md +10 -10
  2. package/dist/components/amount-input.d.ts +17 -1
  3. package/dist/components/amount-input.js +46 -11
  4. package/dist/components/amount-input.js.map +1 -1
  5. package/dist/components/bulk-action-bar.d.ts +10 -2
  6. package/dist/components/bulk-action-bar.js.map +1 -1
  7. package/dist/components/button-group.d.ts +1 -1
  8. package/dist/components/calculator.d.ts +1 -1
  9. package/dist/components/chart.js +14 -8
  10. package/dist/components/chart.js.map +1 -1
  11. package/dist/components/chip.js +20 -15
  12. package/dist/components/chip.js.map +1 -1
  13. package/dist/components/combobox-core.d.ts +3 -1
  14. package/dist/components/combobox-core.js +16 -5
  15. package/dist/components/combobox-core.js.map +1 -1
  16. package/dist/components/combobox.js.map +1 -1
  17. package/dist/components/copy-button.d.ts +1 -1
  18. package/dist/components/data-table-filter-popover.js +8 -1
  19. package/dist/components/data-table-filter-popover.js.map +1 -1
  20. package/dist/components/data-table.js +28 -20
  21. package/dist/components/data-table.js.map +1 -1
  22. package/dist/components/entity-combobox.js +22 -17
  23. package/dist/components/entity-combobox.js.map +1 -1
  24. package/dist/components/error-boundary.d.ts +202 -13
  25. package/dist/components/error-boundary.js +211 -20
  26. package/dist/components/error-boundary.js.map +1 -1
  27. package/dist/components/field-sync.js +90 -83
  28. package/dist/components/field-sync.js.map +1 -1
  29. package/dist/components/file-button.d.ts +1 -1
  30. package/dist/components/file-dropzone.d.ts +1 -1
  31. package/dist/components/form-actions.d.ts +1 -1
  32. package/dist/components/full-bleed-dialog.js +4 -0
  33. package/dist/components/full-bleed-dialog.js.map +1 -1
  34. package/dist/components/hover-menu.js +64 -56
  35. package/dist/components/hover-menu.js.map +1 -1
  36. package/dist/components/list.d.ts +14 -2
  37. package/dist/components/list.js +3 -1
  38. package/dist/components/list.js.map +1 -1
  39. package/dist/components/modal.js.map +1 -1
  40. package/dist/components/multi-entity-combobox.js +23 -17
  41. package/dist/components/multi-entity-combobox.js.map +1 -1
  42. package/dist/components/number-field.d.ts +1 -1
  43. package/dist/components/number-input.d.ts +1 -1
  44. package/dist/components/number-input.js.map +1 -1
  45. package/dist/components/numpad-sheet.d.ts +6 -2
  46. package/dist/components/numpad-sheet.js +3 -2
  47. package/dist/components/numpad-sheet.js.map +1 -1
  48. package/dist/components/page-header.d.ts +35 -6
  49. package/dist/components/page-header.js +7 -1
  50. package/dist/components/page-header.js.map +1 -1
  51. package/dist/components/picker-sheet.js +3 -0
  52. package/dist/components/picker-sheet.js.map +1 -1
  53. package/dist/components/popover.js +3 -0
  54. package/dist/components/popover.js.map +1 -1
  55. package/dist/components/settings-fields.d.ts +1 -1
  56. package/dist/components/signed-amount.d.ts +2 -1
  57. package/dist/components/signed-amount.js +1 -1
  58. package/dist/components/signed-amount.js.map +1 -1
  59. package/dist/components/stat-tile.js +1 -1
  60. package/dist/components/stat-tile.js.map +1 -1
  61. package/dist/components/swipeable-row.js +4 -3
  62. package/dist/components/swipeable-row.js.map +1 -1
  63. package/dist/components/text-link.d.ts +73 -11
  64. package/dist/components/text-link.js +45 -10
  65. package/dist/components/text-link.js.map +1 -1
  66. package/dist/components/text.d.ts +26 -2
  67. package/dist/components/text.js +16 -2
  68. package/dist/components/text.js.map +1 -1
  69. package/dist/components/time-input.d.ts +1 -1
  70. package/dist/components/toggle-group.d.ts +22 -0
  71. package/dist/components/toggle-group.js +8 -8
  72. package/dist/components/toggle-group.js.map +1 -1
  73. package/dist/components/toggle-legend.d.ts +17 -0
  74. package/dist/components/toggle-legend.js +6 -2
  75. package/dist/components/toggle-legend.js.map +1 -1
  76. package/dist/components/tooltip.d.ts +51 -1
  77. package/dist/components/tooltip.js +59 -35
  78. package/dist/components/tooltip.js.map +1 -1
  79. package/dist/components/ui.d.ts +1 -1
  80. package/dist/components/ui.js +166 -28
  81. package/dist/components/ui.js.map +1 -1
  82. package/dist/feedback/feedback-attachment.js +4 -6
  83. package/dist/feedback/feedback-attachment.js.map +1 -1
  84. package/dist/feedback/feedback-dialog.js +5 -3
  85. package/dist/feedback/feedback-dialog.js.map +1 -1
  86. package/dist/feedback/feedback-inbox.js +86 -75
  87. package/dist/feedback/feedback-inbox.js.map +1 -1
  88. package/dist/feedback/feedback-thread.d.ts +43 -3
  89. package/dist/feedback/feedback-thread.js +53 -26
  90. package/dist/feedback/feedback-thread.js.map +1 -1
  91. package/dist/feedback.d.ts +1 -1
  92. package/dist/hooks/use-file-drop.d.ts +1 -1
  93. package/dist/i18n/defaults.d.ts +1 -1
  94. package/dist/i18n/kit-labels.d.ts +1 -1
  95. package/dist/i18n/kit-labels.js.map +1 -1
  96. package/dist/i18n/locales/de-CH-informal.d.ts +1 -1
  97. package/dist/i18n/locales/de-CH.d.ts +1 -1
  98. package/dist/i18n/locales/de-informal.d.ts +1 -1
  99. package/dist/i18n/locales/de.d.ts +1 -1
  100. package/dist/i18n/locales/de.js +9 -1
  101. package/dist/i18n/locales/de.js.map +1 -1
  102. package/dist/i18n/locales/es.d.ts +1 -1
  103. package/dist/i18n/locales/es.js +9 -1
  104. package/dist/i18n/locales/es.js.map +1 -1
  105. package/dist/i18n/locales/fr.d.ts +1 -1
  106. package/dist/i18n/locales/fr.js +9 -1
  107. package/dist/i18n/locales/fr.js.map +1 -1
  108. package/dist/i18n/locales/hu.d.ts +1 -1
  109. package/dist/i18n/locales/hu.js +9 -1
  110. package/dist/i18n/locales/hu.js.map +1 -1
  111. package/dist/i18n/locales/it.d.ts +1 -1
  112. package/dist/i18n/locales/it.js +9 -1
  113. package/dist/i18n/locales/it.js.map +1 -1
  114. package/dist/i18n/locales/zh.d.ts +1 -1
  115. package/dist/i18n/locales/zh.js +9 -1
  116. package/dist/i18n/locales/zh.js.map +1 -1
  117. package/dist/index.d.ts +6 -6
  118. package/dist/{kit-labels-v3biUF1L.d.ts → kit-labels-Mz8zZHIF.d.ts} +102 -3
  119. package/dist/lib/format.d.ts +23 -5
  120. package/dist/lib/format.js +3 -1
  121. package/dist/lib/format.js.map +1 -1
  122. package/dist/rhf/fields.d.ts +57 -15
  123. package/dist/rhf/fields.js +41 -11
  124. package/dist/rhf/fields.js.map +1 -1
  125. package/dist/rhf/form.d.ts +1 -1
  126. package/dist/rhf.d.ts +2 -2
  127. package/dist/rhf.js.map +1 -1
  128. package/dist/search/command-palette.js +20 -14
  129. package/dist/search/command-palette.js.map +1 -1
  130. package/dist/shell/app-shell.d.ts +1 -1
  131. package/dist/shell/app-shell.js +62 -54
  132. package/dist/shell/app-shell.js.map +1 -1
  133. package/dist/shell/top-bar-brand.d.ts +1 -1
  134. package/dist/shell/topbar-action-menu.d.ts +9 -3
  135. package/dist/shell/topbar-action-menu.js +2 -1
  136. package/dist/shell/topbar-action-menu.js.map +1 -1
  137. package/dist/shell.d.ts +1 -1
  138. package/dist/tour/tour.js +10 -4
  139. package/dist/tour/tour.js.map +1 -1
  140. package/dist/wizard/stepper-nav.d.ts +1 -1
  141. package/dist/wizard/use-wizard.js +4 -2
  142. package/dist/wizard/use-wizard.js.map +1 -1
  143. package/dist/wizard/wizard-step.d.ts +11 -1
  144. package/dist/wizard/wizard-step.js +24 -6
  145. package/dist/wizard/wizard-step.js.map +1 -1
  146. package/dist/wizard.d.ts +1 -1
  147. package/package.json +6 -6
  148. package/src/components/amount-input.tsx +97 -10
  149. package/src/components/bulk-action-bar.tsx +16 -3
  150. package/src/components/chart.tsx +19 -8
  151. package/src/components/chip.tsx +6 -0
  152. package/src/components/combobox-core.tsx +28 -9
  153. package/src/components/combobox.tsx +2 -0
  154. package/src/components/data-table-filter-popover.tsx +13 -5
  155. package/src/components/data-table.tsx +6 -0
  156. package/src/components/entity-combobox.tsx +7 -4
  157. package/src/components/error-boundary.tsx +453 -29
  158. package/src/components/field-sync.tsx +48 -40
  159. package/src/components/full-bleed-dialog.tsx +4 -0
  160. package/src/components/hover-menu.tsx +26 -17
  161. package/src/components/list.tsx +17 -3
  162. package/src/components/modal.tsx +4 -0
  163. package/src/components/multi-entity-combobox.tsx +8 -4
  164. package/src/components/number-input.tsx +1 -0
  165. package/src/components/numpad-sheet.tsx +6 -1
  166. package/src/components/page-header.tsx +42 -5
  167. package/src/components/picker-sheet.tsx +3 -0
  168. package/src/components/popover.tsx +3 -0
  169. package/src/components/signed-amount.tsx +12 -3
  170. package/src/components/stat-tile.tsx +3 -1
  171. package/src/components/swipeable-row.tsx +7 -7
  172. package/src/components/text-link.tsx +126 -18
  173. package/src/components/text.tsx +46 -2
  174. package/src/components/toggle-group.tsx +35 -10
  175. package/src/components/toggle-legend.tsx +22 -1
  176. package/src/components/tooltip.tsx +79 -8
  177. package/src/components/ui.tsx +307 -39
  178. package/src/feedback/feedback-attachment.tsx +10 -7
  179. package/src/feedback/feedback-dialog.tsx +7 -4
  180. package/src/feedback/feedback-inbox.tsx +7 -0
  181. package/src/feedback/feedback-thread.tsx +109 -33
  182. package/src/i18n/kit-labels.tsx +16 -0
  183. package/src/i18n/locales/de.ts +8 -0
  184. package/src/i18n/locales/es.ts +8 -0
  185. package/src/i18n/locales/fr.ts +8 -0
  186. package/src/i18n/locales/hu.ts +8 -0
  187. package/src/i18n/locales/it.ts +8 -0
  188. package/src/i18n/locales/zh.ts +8 -0
  189. package/src/lib/format.ts +29 -6
  190. package/src/rhf/fields.tsx +97 -16
  191. package/src/rhf.ts +1 -1
  192. package/src/search/command-palette.tsx +29 -19
  193. package/src/shell/app-shell.tsx +6 -1
  194. package/src/shell/topbar-action-menu.tsx +11 -4
  195. package/src/tour/tour.tsx +16 -5
  196. package/src/wizard/use-wizard.ts +8 -4
  197. package/src/wizard/wizard-step.tsx +38 -6
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { commitExpression, evaluateExpression, formatResult, isBareAmount, looksLikeExpression, sanitizeLive, splitLeadingSign } from './lib/calc.js';
2
2
  export { cn } from './lib/cn.js';
3
3
  export { logger, setStoreLog } from './lib/logger.js';
4
- export { DateInput, EMPTY_FORMATTED_VALUE, FormatDateOptions, FormatDateStyle, FormatDigits, FormatMoneyOptions, FormatNumberOptions, FormatPercentOptions, FormatRelativeTimeOptions, KitFormat, formatDate, formatMoney, formatNumber, formatPercent, formatRelativeTime, toDate, useKitFormat } from './lib/format.js';
4
+ export { DateInput, EMPTY_FORMATTED_VALUE, FormatDateOptions, FormatDateStyle, FormatDigits, FormatMoneyOptions, FormatNumberBaseOptions, FormatNumberOptions, FormatPercentOptions, FormatRelativeTimeOptions, KitFormat, formatDate, formatMoney, formatNumber, formatPercent, formatRelativeTime, toDate, useKitFormat } from './lib/format.js';
5
5
  export { readStored, writeStored } from './lib/safe-storage.js';
6
6
  export { useMediaQuery } from './hooks/use-media-query.js';
7
7
  export { useBodyScrollLock } from './hooks/use-body-scroll-lock.js';
@@ -25,7 +25,7 @@ export { AnchorRole, ChartRampReport, ContrastCheck, ContrastReport, DeriveOptio
25
25
  export { ALTERNATIVE_PRESETS, DEFAULT_PRESET, DERIVED_PRESETS, IMPRINT_PRESET, PALETTES, PalettePreset, TokenSet, applyTokenSet, presetById } from './theme/palette-presets.js';
26
26
  export { ThemeMode, ThemePreference, ThemeState, ThemeStore, applyPersistedTheme, createThemeStore } from './theme/theme-store.js';
27
27
  export { PaletteStore, applyPersistedPalette, createPaletteStore } from './theme/palette-store.js';
28
- export { A as AppShellLabels, B as Button, a as ButtonClassesOptions, b as ButtonLinkProps, c as ButtonProps, d as ButtonSize, e as ButtonTone, f as ButtonVariant, C as CalculatorLabels, g as Card, h as CardAction, i as CardActionProps, j as CardContent, k as CardContentProps, l as CardDescription, m as CardDescriptionProps, n as CardFooter, o as CardFooterProps, p as CardHeader, q as CardHeaderProps, r as CardProps, s as CardTitle, t as CardTitleProps, u as CardTone, v as ComboboxLabels, w as CommonLabels, x as CopyButton, y as CopyButtonLabels, z as CopyButtonProps, D as CurrencyLabels, E as DEFAULT_APP_SHELL_LABELS, F as DEFAULT_CALCULATOR_LABELS, G as DEFAULT_COMBOBOX_LABELS, H as DEFAULT_COMMON_LABELS, I as DEFAULT_COPY_BUTTON_LABELS, J as DEFAULT_CURRENCY_LABELS, K as DEFAULT_DATE_PICKER_LABELS, L as DEFAULT_FILE_LABELS, M as DEFAULT_FILE_PICKER_LABELS, N as DEFAULT_FORM_ACTIONS_LABELS, O as DEFAULT_MULTI_SELECT_LABELS, P as DEFAULT_PASSWORD_REVEAL_LABELS, Q as DEFAULT_PICKER_SHEET_LABELS, R as DEFAULT_SWIPEABLE_ROW_LABELS, S as DEFAULT_TABS_LABELS, T as DEFAULT_TOP_BAR_LABELS, U as DatePickerLabels, V as EmptyState, W as EmptyStateProps, X as FIELD_BASE, Y as FIELD_DISPLAY, Z as FIELD_FLOATING_PAD, _ as FIELD_INVALID, $ as FIELD_TRIGGER, a0 as FIELD_WRITABLE_LOOK, a1 as FLOATING_INPUT_CLASS, a2 as FLOATING_LABEL_CLASS, a3 as FLOATING_LABEL_STATIC, a4 as FieldChevron, a5 as FieldChevronProps, a6 as FieldHint, a7 as FieldHintProps, a8 as FieldLabel, a9 as FieldLabelProps, aa as FileButton, ab as FileButtonProps, ac as FileLabels, ad as FilePickerLabels, ae as FileRejection, af as FileRejectionReason, ag as FileScreenOptions, ah as FloatingField, ai as FloatingFieldProps, aj as FormActions, ak as FormActionsAlign, al as FormActionsDestructive, am as FormActionsLabels, an as FormActionsPlacement, ao as FormActionsProps, ap as IconButton, aq as IconButtonGlyphSize, ar as IconButtonProps, as as IconButtonSize, at as IconButtonTone, au as IconButtonVariant, av as Input, aw as InputProps, ax as KitLinkComponent, ay as KitLinkProps, az as Label, aA as LabelOverride, aB as LabelProps, aC as MultiSelectLabels, aD as PHONE_QUERY, aE as PasswordRevealLabels, aF as PickerSheetLabels, aG as Select, aH as SelectProps, aI as Spinner, aJ as SpinnerProps, aK as SwipeableRowLabels, aL as TabItem, aM as Tabs, aN as TabsLabels, aO as TabsProps, aP as Textarea, aQ as TextareaProps, aR as TopBarLabels, aS as UiKitLabelOverrides, aT as UiKitLabels, aU as UiKitProvider, aV as UiKitProviderProps, aW as UseFilePickerOptions, aX as UseFilePickerReturn, aY as buttonClasses, aZ as formatFileSize, a_ as matchesAccept, a$ as missingKitLabels, b0 as resolvePasswordRevealLabels, b1 as useFilePicker, b2 as useKitFileLabels, b3 as useKitLabelOverrides, b4 as useKitLabels, b5 as useKitLink, b6 as useKitLocale, b7 as useKitWeekStart } from './kit-labels-v3biUF1L.js';
28
+ export { A as AppShellLabels, B as Button, a as ButtonClassesOptions, b as ButtonLinkProps, c as ButtonProps, d as ButtonSize, e as ButtonTone, f as ButtonVariant, C as CalculatorLabels, g as Card, h as CardAction, i as CardActionProps, j as CardContent, k as CardContentProps, l as CardDescription, m as CardDescriptionProps, n as CardFooter, o as CardFooterProps, p as CardHeader, q as CardHeaderProps, r as CardProps, s as CardTitle, t as CardTitleProps, u as CardTone, v as ComboboxLabels, w as CommonLabels, x as CopyButton, y as CopyButtonLabels, z as CopyButtonProps, D as CurrencyLabels, E as DEFAULT_APP_SHELL_LABELS, F as DEFAULT_CALCULATOR_LABELS, G as DEFAULT_COMBOBOX_LABELS, H as DEFAULT_COMMON_LABELS, I as DEFAULT_COPY_BUTTON_LABELS, J as DEFAULT_CURRENCY_LABELS, K as DEFAULT_DATE_PICKER_LABELS, L as DEFAULT_FILE_LABELS, M as DEFAULT_FILE_PICKER_LABELS, N as DEFAULT_FORM_ACTIONS_LABELS, O as DEFAULT_MULTI_SELECT_LABELS, P as DEFAULT_PASSWORD_REVEAL_LABELS, Q as DEFAULT_PICKER_SHEET_LABELS, R as DEFAULT_SWIPEABLE_ROW_LABELS, S as DEFAULT_TABS_LABELS, T as DEFAULT_TOP_BAR_LABELS, U as DatePickerLabels, V as EmptyState, W as EmptyStateProps, X as FIELD_BASE, Y as FIELD_DISPLAY, Z as FIELD_FLOATING_PAD, _ as FIELD_INVALID, $ as FIELD_TRIGGER, a0 as FIELD_WRITABLE_LOOK, a1 as FLOATING_INPUT_CLASS, a2 as FLOATING_LABEL_CLASS, a3 as FLOATING_LABEL_STATIC, a4 as FieldChevron, a5 as FieldChevronProps, a6 as FieldHint, a7 as FieldHintProps, a8 as FieldLabel, a9 as FieldLabelProps, aa as FileButton, ab as FileButtonProps, ac as FileLabels, ad as FilePickerLabels, ae as FileRejection, af as FileRejectionReason, ag as FileScreenOptions, ah as FloatingField, ai as FloatingFieldProps, aj as FormActions, ak as FormActionsAlign, al as FormActionsDestructive, am as FormActionsLabels, an as FormActionsPlacement, ao as FormActionsProps, ap as IconButton, aq as IconButtonGlyphSize, ar as IconButtonLinkProps, as as IconButtonProps, at as IconButtonSize, au as IconButtonTone, av as IconButtonToneColor, aw as IconButtonVariant, ax as Input, ay as InputProps, az as KitLinkComponent, aA as KitLinkProps, aB as Label, aC as LabelOverride, aD as LabelProps, aE as MultiSelectLabels, aF as PHONE_QUERY, aG as PasswordRevealLabels, aH as PickerSheetLabels, aI as Select, aJ as SelectProps, aK as Spinner, aL as SpinnerProps, aM as SwipeableRowLabels, aN as TabItem, aO as Tabs, aP as TabsLabels, aQ as TabsProps, aR as Textarea, aS as TextareaProps, aT as TopBarLabels, aU as UiKitLabelOverrides, aV as UiKitLabels, aW as UiKitProvider, aX as UiKitProviderProps, aY as UseFilePickerOptions, aZ as UseFilePickerReturn, a_ as buttonClasses, a$ as formatFileSize, b0 as matchesAccept, b1 as missingKitLabels, b2 as resolvePasswordRevealLabels, b3 as useFilePicker, b4 as useKitFileLabels, b5 as useKitLabelOverrides, b6 as useKitLabels, b7 as useKitLink, b8 as useKitLocale, b9 as useKitWeekStart } from './kit-labels-Mz8zZHIF.js';
29
29
  export { Field, FieldControlProps, FieldLabelVisibility, FieldProps, FieldRenderMeta } from './components/field.js';
30
30
  export { SearchField, SearchFieldProps } from './components/search-field.js';
31
31
  export { DropdownPanel, DropdownPanelProps, DropdownSearchHeader, DropdownSearchHeaderProps, useDropdown, useDropdownSearch } from './components/dropdown.js';
@@ -101,7 +101,7 @@ export { DEFAULT_PROGRESS_BAR_LABELS, ProgressBar, ProgressBarLabels, ProgressBa
101
101
  export { Skeleton, SkeletonProps, SkeletonShape } from './components/skeleton.js';
102
102
  export { LoadingState, LoadingStateProps, LoadingStateSize } from './components/loading-state.js';
103
103
  export { DEFAULT_SIGNED_AMOUNT_LABELS, Delta, DeltaProps, GoodDirection, SignedAmount, SignedAmountLabels, SignedAmountProps, SignedAmountTone, TextTone, Tone, ToneProps, toneTextClass } from './components/signed-amount.js';
104
- export { DEFAULT_ERROR_BOUNDARY_LABELS, ErrorBoundary, ErrorBoundaryDetails, ErrorBoundaryFallbackProps, ErrorBoundaryLabels, ErrorBoundaryProps, describeThrown } from './components/error-boundary.js';
104
+ export { CrashReport, CrashReportResult, DEFAULT_ERROR_BOUNDARY_LABELS, ErrorBoundary, ErrorBoundaryDetails, ErrorBoundaryFallbackProps, ErrorBoundaryLabels, ErrorBoundaryProps, crashFingerprint, describeThrown, formatCrashReport, isChunkLoadError } from './components/error-boundary.js';
105
105
  export { AuthedImage, AuthedImageLabels, AuthedImageProps, DEFAULT_AUTHED_IMAGE_LABELS } from './components/authed-image.js';
106
106
  export { DEFAULT_IMAGE_GRID_LABELS, ImageGrid, ImageGridLabels, ImageGridProps } from './components/image-grid.js';
107
107
  export { DEFAULT_LIGHTBOX_LABELS, ImageItem, ImageItemKind, Lightbox, LightboxLabels, LightboxProps, imageItemKind } from './components/lightbox.js';
@@ -111,9 +111,9 @@ export { Separator, SeparatorProps } from './components/separator.js';
111
111
  export { ScrollArea, ScrollAreaProps } from './components/scroll-area.js';
112
112
  export { DEFAULT_LIST_LABELS, List, ListDensity, ListItem, ListItemLinkProps, ListItemProps, ListLabels, ListProps, ListSeparator } from './components/list.js';
113
113
  export { MenuItem, MenuItemLinkProps, MenuItemProps, MenuItemTone } from './components/menu-item.js';
114
- export { CAPTION_CLASS, Caption, CaptionProps, SECTION_LABEL_CLASS, SectionLabel, SectionLabelProps, SectionLabelSize } from './components/text.js';
114
+ export { CAPTION_CLASS, Caption, CaptionProps, SECTION_LABEL_CLASS, SectionLabel, SectionLabelProps, SectionLabelSize, SectionLabelVariant } from './components/text.js';
115
115
  export { StatusDot, StatusDotProps, StatusDotSize, StatusDotTone } from './components/status-dot.js';
116
- export { PageHeader, PageHeaderProps, PageHeaderSize } from './components/page-header.js';
116
+ export { PageHeader, PageHeaderMobileLayout, PageHeaderProps, PageHeaderSize } from './components/page-header.js';
117
117
  export { BreadcrumbItem, BreadcrumbLinkProps, Breadcrumbs, BreadcrumbsLabels, BreadcrumbsProps, DEFAULT_BREADCRUMBS_LABELS } from './components/breadcrumbs.js';
118
118
  export { TextLink, TextLinkCurrent, TextLinkProps, TextLinkRenderProps, TextLinkTone, TextLinkUnderline } from './components/text-link.js';
119
119
  export { DEFAULT_TOAST_LABELS, TOAST_ACTION_DURATION, ToastAction, ToastId, ToastLabels, ToastOptions, ToastPosition, ToastPromiseOptions, ToastRedoOptions, ToastSwipeDirection, ToastUndoOptions, Toaster, ToasterOffset, ToasterProps, toast } from './components/toast.js';
@@ -134,7 +134,7 @@ export { AuthLayout, AuthLayoutProps } from './shell/auth-layout.js';
134
134
  export { DEFAULT_ATTACHMENT_ACCEPT, DEFAULT_FEEDBACK_ATTACHMENT_LABELS, DEFAULT_MAX_ATTACHMENT_BYTES, FeedbackAttachmentField, FeedbackAttachmentFieldLabels, pastedName } from './feedback/feedback-attachment.js';
135
135
  export { DEFAULT_FEEDBACK_DIALOG_LABELS, FeedbackAttachmentLabels, FeedbackCategoryOption, FeedbackDialog, FeedbackDialogLabels, FeedbackDialogTextLabels, FeedbackSubmission } from './feedback/feedback-dialog.js';
136
136
  export { FEEDBACK_CATEGORY_META, FEEDBACK_CATEGORY_ORDER, FEEDBACK_STATUS_META, FEEDBACK_STATUS_ORDER, FeedbackCategory, FeedbackCategoryBadge, FeedbackDetail, FeedbackDetailSection, FeedbackNoteAttachment, FeedbackNoteEditor, FeedbackProse, FeedbackStatus, FeedbackStatusBadge, FeedbackStatusTransitions, feedbackCategoryRank, nextFeedbackStatus, selectableFeedbackStatuses, visibleFeedbackStatuses } from './feedback/feedback-inbox.js';
137
- export { DEFAULT_FEEDBACK_COMPOSER_LABELS, DEFAULT_FEEDBACK_THREAD_LABELS, FeedbackComposer, FeedbackComposerAttachment, FeedbackComposerLabels, FeedbackComposerProps, FeedbackThread, FeedbackThreadAttachment, FeedbackThreadLabels, FeedbackThreadMessage, FeedbackThreadProps } from './feedback/feedback-thread.js';
137
+ export { DEFAULT_FEEDBACK_COMPOSER_LABELS, DEFAULT_FEEDBACK_THREAD_LABELS, FeedbackComposer, FeedbackComposerAttachment, FeedbackComposerHandle, FeedbackComposerLabels, FeedbackComposerProps, FeedbackThread, FeedbackThreadAttachment, FeedbackThreadLabels, FeedbackThreadMessage, FeedbackThreadProps } from './feedback/feedback-thread.js';
138
138
  export { DEFAULT_WIZARD_LABELS, FieldErrors, StepStatus, SummaryItem, SummarySection, UseWizardOptions, UseWizardReturn, ValidateResult, WizardLabels, WizardStepConfig, WizardUrlSync, resolveWizardLabels } from './wizard/types.js';
139
139
  export { useWizard } from './wizard/use-wizard.js';
140
140
  export { WizardContextProvider, WizardContextValue, useOptionalWizardContext, useWizardContext, useWizardNextGate, useWizardStepValidate } from './wizard/wizard-context.js';
@@ -164,6 +164,8 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
164
164
  href?: never;
165
165
  renderLink?: never;
166
166
  external?: never;
167
+ replace?: never;
168
+ reloadDocument?: never;
167
169
  }
168
170
  /**
169
171
  * `<Button href>`: a link that looks like a button — for an action that NAVIGATES.
@@ -192,6 +194,21 @@ interface ButtonLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>,
192
194
  * router link, and "(opens in a new tab)" read after the label — billing-history's
193
195
  * Stripe PDF. A `target="_blank"` of your own is announced the same way. */
194
196
  external?: boolean;
197
+ /**
198
+ * Navigate by replacing the current history entry, so Back does not return here —
199
+ * keksdose F1: the "Continue" out of a one-shot page (an emailed confirmation link, a
200
+ * payment return URL) that must not be landed on again. Handed to the router link as
201
+ * `replace` (see `KitLinkProps.replace` for mapping it); on a plain `<a>` a plain click
202
+ * becomes `location.replace(href)`. Ignored when `external`.
203
+ */
204
+ replace?: boolean;
205
+ /**
206
+ * A plain `<a>` for an in-app `href`, so the browser loads the whole document instead
207
+ * of the router swapping the view — keksdose F1: a route the SPA does not own (a
208
+ * server-rendered export, a logout that must drop every in-memory cache). Wins over
209
+ * `renderLink` and the provider's `linkComponent`.
210
+ */
211
+ reloadDocument?: boolean;
195
212
  /** A link cannot be `disabled`, so this renders an `<a>` with NO `href` —
196
213
  * `role="link"` and `aria-disabled`, out of the tab order like a disabled button,
197
214
  * with the disabled look. The router link is not used: it needs somewhere to go. */
@@ -267,8 +284,12 @@ interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
267
284
  * state re-colours the glyph, its hover fill and its focus ring together. Passing it
268
285
  * implies `tone="custom"`. Or leave it out and set the variable yourself from a class
269
286
  * (`className="[--icon-button-tone:var(--success)]"`).
287
+ *
288
+ * Or a `{ light, dark }` pair, one colour per theme — keksdose: a raw colour that reads
289
+ * on the light surface (`#be123c`) is too dark on the dark one, and an inline style
290
+ * cannot say "in dark mode". See {@link IconButtonToneColor}.
270
291
  */
271
- toneColor?: string;
292
+ toneColor?: IconButtonToneColor;
272
293
  /** Glyph colour over the variant. `muted`: placeholder grey, full text colour on
273
294
  * hover. `danger`: the same grey at rest, `--danger` on hover and focus — for a
274
295
  * remove/delete that repeats down a list. `warning`: amber at rest — a flag that
@@ -376,8 +397,70 @@ interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
376
397
  * reason nobody can see is not one. Wins over `disabled`, as on Button.
377
398
  */
378
399
  disabledReason?: ReactNode;
400
+ /** The `<button>` element — a prop in React 19, as on {@link Button}. */
401
+ ref?: Ref<HTMLButtonElement>;
402
+ /** Only on the link form — see {@link IconButtonLinkProps}. */
403
+ href?: never;
404
+ renderLink?: never;
405
+ external?: never;
406
+ replace?: never;
407
+ reloadDocument?: never;
408
+ }
409
+ /**
410
+ * `<IconButton href>`: an icon-only LINK — keksdose F2 and kastlan 45, whose icon
411
+ * actions that navigate (a row's "open", a card's "edit" that goes to the edit page, a
412
+ * top bar's settings cog) were `<IconButton onClick={() => navigate(…)}>`: a button that
413
+ * changes the page, with no middle click, no "open in new tab" and no URL on hover.
414
+ *
415
+ * The same rule as {@link Button}'s `href` (see {@link ButtonLinkProps}): an in-app
416
+ * `href` goes through `renderLink`, else the provider's `linkComponent`; an external one
417
+ * or an in-page `#anchor` stays a plain `<a>`; `external` opens a new tab and says so to
418
+ * a screen reader; `replace` and `reloadDocument` as on Button. The look, the `label` →
419
+ * `aria-label` + Tooltip, the badge, `toneColor` and `stopPropagation` are the button's.
420
+ *
421
+ * `disabled` renders an inert `<a>` with no `href` — `role="link"`, `aria-disabled`, out
422
+ * of the tab order, dimmed — like Button's disabled link. `pressed`, `disabledReason` and
423
+ * `disabledStyle` are a button's and are typed out: a link is not a toggle, and a link
424
+ * that explains why it cannot be followed is a job for a disabled BUTTON.
425
+ */
426
+ interface IconButtonLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "type" | "href">, Pick<IconButtonProps, "variant" | "size" | "glyphSize" | "badge" | "stretch" | "shape" | "toneColor" | "tone" | "quiet" | "stopPropagation" | "label" | "tooltip" | "tooltipSide" | "tooltipPortal"> {
427
+ href: string;
428
+ /** See {@link ButtonLinkProps.renderLink}. */
429
+ renderLink?: KitLinkComponent;
430
+ /** See {@link ButtonLinkProps.external}. */
431
+ external?: boolean;
432
+ /** See {@link ButtonLinkProps.replace}. */
433
+ replace?: boolean;
434
+ /** See {@link ButtonLinkProps.reloadDocument}. */
435
+ reloadDocument?: boolean;
436
+ /** See {@link ButtonLinkProps.disabled}. */
437
+ disabled?: boolean;
438
+ ref?: Ref<HTMLAnchorElement>;
439
+ type?: never;
440
+ form?: never;
441
+ pressed?: never;
442
+ disabledReason?: never;
443
+ disabledStyle?: never;
444
+ }
445
+ /**
446
+ * `toneColor`: one CSS colour, or one per theme.
447
+ *
448
+ * The pair is two custom properties on the element — `--icon-button-tone-light` and
449
+ * `--icon-button-tone-dark` — and a class that points `--icon-button-tone` at one or the
450
+ * other by the kit's `dark` variant (`.dark` on an ancestor, tokens.css), so the colour
451
+ * follows a theme switch in CSS alone, with no re-render and no JS reading the theme.
452
+ * Both values are any CSS colour; a token that already flips (`var(--warning)`) needs no
453
+ * pair.
454
+ */
455
+ type IconButtonToneColor = string | {
456
+ light: string;
457
+ dark: string;
458
+ };
459
+ declare function IconButton(props: IconButtonLinkProps): ReactElement;
460
+ declare function IconButton(props: IconButtonProps): ReactElement;
461
+ declare namespace IconButton {
462
+ var displayName: string;
379
463
  }
380
- declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
381
464
  declare const FIELD_BASE: string;
382
465
  /** Cancels FIELD_BASE's read-only treatment for a field that is `readOnly` for a
383
466
  * reason other than "you may not edit this". Attribute-scoped for the same reason
@@ -1564,10 +1647,26 @@ declare function formatFileSize(bytes: number, locale?: string): string;
1564
1647
  * What every kit link receives: the anchor attributes the kit decided (href, class,
1565
1648
  * aria-current, handlers, children, ref). An app's router link maps them —
1566
1649
  * `({ href, ...p }) => <Link to={href} {...p} />` — ONCE, on the provider.
1650
+ *
1651
+ * `replace` is the one prop that is not an anchor attribute: see there. Map it
1652
+ * explicitly if your router link is not react-router's —
1653
+ * `({ href, replace, ...p }) => <Link to={href} replace={replace} {...p} />` — and never
1654
+ * spread it onto a DOM `<a>`, where React warns about an unknown attribute.
1567
1655
  */
1568
1656
  type KitLinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
1569
1657
  href: string;
1570
1658
  ref?: Ref<HTMLAnchorElement>;
1659
+ /**
1660
+ * Navigate by REPLACING the current history entry, so Back skips it — keksdose F1:
1661
+ * a one-shot URL (a magic-link landing, `?checkout=done`, a wizard's "finish" hop)
1662
+ * that must not come back when the user presses Back. Present ONLY when the kit link
1663
+ * was given `replace` (`true`), so a provider link that spreads its props onto a
1664
+ * plain `<a>` keeps working for every link that never asks for it. react-router's
1665
+ * `<Link>` takes the same prop, so `({ href, ...p }) => <Link to={href} {...p} />`
1666
+ * honours it with no change; any other router maps it to its own replace option.
1667
+ * The kit never puts it on a DOM element itself.
1668
+ */
1669
+ replace?: boolean;
1571
1670
  };
1572
1671
  type KitLinkComponent = (props: KitLinkProps) => ReactElement;
1573
1672
  interface UiKitProviderProps {
@@ -1642,4 +1741,4 @@ declare function useKitFileLabels(prop?: Partial<FileLabels>): FileLabels;
1642
1741
  */
1643
1742
  declare function missingKitLabels(labels: UiKitLabelOverrides | undefined, reference: UiKitLabels): string[];
1644
1743
 
1645
- export { FIELD_TRIGGER as $, type AppShellLabels as A, Button as B, type CalculatorLabels as C, type CurrencyLabels as D, DEFAULT_APP_SHELL_LABELS as E, DEFAULT_CALCULATOR_LABELS as F, DEFAULT_COMBOBOX_LABELS as G, DEFAULT_COMMON_LABELS as H, DEFAULT_COPY_BUTTON_LABELS as I, DEFAULT_CURRENCY_LABELS as J, DEFAULT_DATE_PICKER_LABELS as K, DEFAULT_FILE_LABELS as L, DEFAULT_FILE_PICKER_LABELS as M, DEFAULT_FORM_ACTIONS_LABELS as N, DEFAULT_MULTI_SELECT_LABELS as O, DEFAULT_PASSWORD_REVEAL_LABELS as P, DEFAULT_PICKER_SHEET_LABELS as Q, DEFAULT_SWIPEABLE_ROW_LABELS as R, DEFAULT_TABS_LABELS as S, DEFAULT_TOP_BAR_LABELS as T, type DatePickerLabels as U, EmptyState as V, type EmptyStateProps as W, FIELD_BASE as X, FIELD_DISPLAY as Y, FIELD_FLOATING_PAD as Z, FIELD_INVALID as _, type ButtonClassesOptions as a, missingKitLabels as a$, FIELD_WRITABLE_LOOK as a0, FLOATING_INPUT_CLASS as a1, FLOATING_LABEL_CLASS as a2, FLOATING_LABEL_STATIC as a3, FieldChevron as a4, type FieldChevronProps as a5, FieldHint as a6, type FieldHintProps as a7, FieldLabel as a8, type FieldLabelProps as a9, type LabelOverride as aA, type LabelProps as aB, type MultiSelectLabels as aC, PHONE_QUERY as aD, type PasswordRevealLabels as aE, type PickerSheetLabels as aF, Select as aG, type SelectProps as aH, Spinner as aI, type SpinnerProps as aJ, type SwipeableRowLabels as aK, type TabItem as aL, Tabs as aM, type TabsLabels as aN, type TabsProps as aO, Textarea as aP, type TextareaProps as aQ, type TopBarLabels as aR, type UiKitLabelOverrides as aS, type UiKitLabels as aT, UiKitProvider as aU, type UiKitProviderProps as aV, type UseFilePickerOptions as aW, type UseFilePickerReturn as aX, buttonClasses as aY, formatFileSize as aZ, matchesAccept as a_, FileButton as aa, type FileButtonProps as ab, type FileLabels as ac, type FilePickerLabels as ad, type FileRejection as ae, type FileRejectionReason as af, type FileScreenOptions as ag, FloatingField as ah, type FloatingFieldProps as ai, FormActions as aj, type FormActionsAlign as ak, type FormActionsDestructive as al, type FormActionsLabels as am, type FormActionsPlacement as an, type FormActionsProps as ao, IconButton as ap, type IconButtonGlyphSize as aq, type IconButtonProps as ar, type IconButtonSize as as, type IconButtonTone as at, type IconButtonVariant as au, Input as av, type InputProps as aw, type KitLinkComponent as ax, type KitLinkProps as ay, Label as az, type ButtonLinkProps as b, resolvePasswordRevealLabels as b0, useFilePicker as b1, useKitFileLabels as b2, useKitLabelOverrides as b3, useKitLabels as b4, useKitLink as b5, useKitLocale as b6, useKitWeekStart as b7, type FilePickHandler as b8, formatAccept as b9, judgePick as ba, screenFiles as bb, summariseRejections as bc, type ButtonProps as c, type ButtonSize as d, type ButtonTone as e, type ButtonVariant as f, Card as g, CardAction as h, type CardActionProps as i, CardContent as j, type CardContentProps as k, CardDescription as l, type CardDescriptionProps as m, CardFooter as n, type CardFooterProps as o, CardHeader as p, type CardHeaderProps as q, type CardProps as r, CardTitle as s, type CardTitleProps as t, type CardTone as u, type ComboboxLabels as v, type CommonLabels as w, CopyButton as x, type CopyButtonLabels as y, type CopyButtonProps as z };
1744
+ export { FIELD_TRIGGER as $, type AppShellLabels as A, Button as B, type CalculatorLabels as C, type CurrencyLabels as D, DEFAULT_APP_SHELL_LABELS as E, DEFAULT_CALCULATOR_LABELS as F, DEFAULT_COMBOBOX_LABELS as G, DEFAULT_COMMON_LABELS as H, DEFAULT_COPY_BUTTON_LABELS as I, DEFAULT_CURRENCY_LABELS as J, DEFAULT_DATE_PICKER_LABELS as K, DEFAULT_FILE_LABELS as L, DEFAULT_FILE_PICKER_LABELS as M, DEFAULT_FORM_ACTIONS_LABELS as N, DEFAULT_MULTI_SELECT_LABELS as O, DEFAULT_PASSWORD_REVEAL_LABELS as P, DEFAULT_PICKER_SHEET_LABELS as Q, DEFAULT_SWIPEABLE_ROW_LABELS as R, DEFAULT_TABS_LABELS as S, DEFAULT_TOP_BAR_LABELS as T, type DatePickerLabels as U, EmptyState as V, type EmptyStateProps as W, FIELD_BASE as X, FIELD_DISPLAY as Y, FIELD_FLOATING_PAD as Z, FIELD_INVALID as _, type ButtonClassesOptions as a, formatFileSize as a$, FIELD_WRITABLE_LOOK as a0, FLOATING_INPUT_CLASS as a1, FLOATING_LABEL_CLASS as a2, FLOATING_LABEL_STATIC as a3, FieldChevron as a4, type FieldChevronProps as a5, FieldHint as a6, type FieldHintProps as a7, FieldLabel as a8, type FieldLabelProps as a9, type KitLinkProps as aA, Label as aB, type LabelOverride as aC, type LabelProps as aD, type MultiSelectLabels as aE, PHONE_QUERY as aF, type PasswordRevealLabels as aG, type PickerSheetLabels as aH, Select as aI, type SelectProps as aJ, Spinner as aK, type SpinnerProps as aL, type SwipeableRowLabels as aM, type TabItem as aN, Tabs as aO, type TabsLabels as aP, type TabsProps as aQ, Textarea as aR, type TextareaProps as aS, type TopBarLabels as aT, type UiKitLabelOverrides as aU, type UiKitLabels as aV, UiKitProvider as aW, type UiKitProviderProps as aX, type UseFilePickerOptions as aY, type UseFilePickerReturn as aZ, buttonClasses as a_, FileButton as aa, type FileButtonProps as ab, type FileLabels as ac, type FilePickerLabels as ad, type FileRejection as ae, type FileRejectionReason as af, type FileScreenOptions as ag, FloatingField as ah, type FloatingFieldProps as ai, FormActions as aj, type FormActionsAlign as ak, type FormActionsDestructive as al, type FormActionsLabels as am, type FormActionsPlacement as an, type FormActionsProps as ao, IconButton as ap, type IconButtonGlyphSize as aq, type IconButtonLinkProps as ar, type IconButtonProps as as, type IconButtonSize as at, type IconButtonTone as au, type IconButtonToneColor as av, type IconButtonVariant as aw, Input as ax, type InputProps as ay, type KitLinkComponent as az, type ButtonLinkProps as b, matchesAccept as b0, missingKitLabels as b1, resolvePasswordRevealLabels as b2, useFilePicker as b3, useKitFileLabels as b4, useKitLabelOverrides as b5, useKitLabels as b6, useKitLink as b7, useKitLocale as b8, useKitWeekStart as b9, type FilePickHandler as ba, formatAccept as bb, judgePick as bc, screenFiles as bd, summariseRejections as be, type ButtonProps as c, type ButtonSize as d, type ButtonTone as e, type ButtonVariant as f, Card as g, CardAction as h, type CardActionProps as i, CardContent as j, type CardContentProps as k, CardDescription as l, type CardDescriptionProps as m, CardFooter as n, type CardFooterProps as o, CardHeader as p, type CardHeaderProps as q, type CardProps as r, CardTitle as s, type CardTitleProps as t, type CardTone as u, type ComboboxLabels as v, type CommonLabels as w, CopyButton as x, type CopyButtonLabels as y, type CopyButtonProps as z };
@@ -32,7 +32,8 @@ interface BaseOptions {
32
32
  /** Printed for a missing value. Default {@link EMPTY_FORMATTED_VALUE}. */
33
33
  empty?: string;
34
34
  }
35
- interface FormatNumberOptions extends BaseOptions {
35
+ /** The options every number formatter shares (money and percent carry their own unit). */
36
+ interface FormatNumberBaseOptions extends BaseOptions {
36
37
  digits?: FormatDigits;
37
38
  /** Compact notation: 12 400 → "12K". */
38
39
  compact?: boolean;
@@ -41,11 +42,28 @@ interface FormatNumberOptions extends BaseOptions {
41
42
  /** Any further `Intl.NumberFormat` options, merged over the ones above. */
42
43
  options?: Intl.NumberFormatOptions;
43
44
  }
44
- interface FormatMoneyOptions extends FormatNumberOptions {
45
+ /** The options {@link formatNumber} takes: the shared ones plus a free-text `unit`. */
46
+ interface FormatNumberOptions extends FormatNumberBaseOptions {
47
+ /**
48
+ * A unit printed after the figure, joined by a narrow no-break space (U+202F):
49
+ * "3.400 N", "12 kg", "4,5 m²". lenkbank (P8) prints forces, masses and lengths in
50
+ * every table and summary, and each call site glued `${n} N` together with a plain
51
+ * space — which wraps the "N" onto the next line in a narrow column and reads loose
52
+ * beside the digit grouping. The narrow no-break space is the SI brochure's and the
53
+ * Swiss typesetting rule's separator between value and unit, and it never breaks.
54
+ *
55
+ * Free text, not `Intl`'s `style: "unit"`: that one only knows the ECMA-402
56
+ * sanctioned units (no "N", no "kN", no "m³/h"), so an app would still be gluing.
57
+ * A missing value prints `empty` ALONE — "— N" says there is a newton-shaped
58
+ * nothing, which is noise in a column that already heads its unit.
59
+ */
60
+ unit?: string;
61
+ }
62
+ interface FormatMoneyOptions extends FormatNumberBaseOptions {
45
63
  /** `"symbol"` (default), `"narrowSymbol"`, `"code"` ("CHF 12.00") or `"name"`. */
46
64
  currencyDisplay?: Intl.NumberFormatOptions["currencyDisplay"];
47
65
  }
48
- interface FormatPercentOptions extends FormatNumberOptions {
66
+ interface FormatPercentOptions extends FormatNumberBaseOptions {
49
67
  /**
50
68
  * `true` (default): `value` is a RATIO, as `Intl` and `StatTile`'s percent delta read
51
69
  * it — `0.12` is 12 %. `false`: it is already a percentage — `12` is 12 %
@@ -53,7 +71,7 @@ interface FormatPercentOptions extends FormatNumberOptions {
53
71
  */
54
72
  ratio?: boolean;
55
73
  }
56
- /** A number in `locale`: "1,234.5", "1.234,5", "1’234.5". */
74
+ /** A number in `locale`: "1,234.5", "1.234,5", "1’234.5" — with `unit`, "3.400 N". */
57
75
  declare function formatNumber(value: number | null | undefined, options?: FormatNumberOptions): string;
58
76
  /** An amount of `currency` (ISO 4217) in `locale`: "CHF 1’234.50", "1.234,50 €". */
59
77
  declare function formatMoney(value: number | null | undefined, currency: string, options?: FormatMoneyOptions): string;
@@ -141,4 +159,4 @@ interface KitFormat {
141
159
  */
142
160
  declare function useKitFormat(locale?: string): KitFormat;
143
161
 
144
- export { type DateInput, EMPTY_FORMATTED_VALUE, type FormatDateOptions, type FormatDateStyle, type FormatDigits, type FormatMoneyOptions, type FormatNumberOptions, type FormatPercentOptions, type FormatRelativeTimeOptions, type KitFormat, formatDate, formatMoney, formatNumber, formatPercent, formatRelativeTime, toDate, useKitFormat };
162
+ export { type DateInput, EMPTY_FORMATTED_VALUE, type FormatDateOptions, type FormatDateStyle, type FormatDigits, type FormatMoneyOptions, type FormatNumberBaseOptions, type FormatNumberOptions, type FormatPercentOptions, type FormatRelativeTimeOptions, type KitFormat, formatDate, formatMoney, formatNumber, formatPercent, formatRelativeTime, toDate, useKitFormat };
@@ -3,6 +3,7 @@ import { useMemo } from "react";
3
3
  import { useKitLocale } from "../i18n/kit-labels.js";
4
4
  import { parseIsoDate } from "./dates.js";
5
5
  const EMPTY_FORMATTED_VALUE = "\u2014";
6
+ const UNIT_SEPARATOR = "\u202F";
6
7
  const numberFormatters = /* @__PURE__ */ new Map();
7
8
  function numberFormatter(locale, options) {
8
9
  const key = `${locale ?? ""}|${JSON.stringify(options)}`;
@@ -34,7 +35,8 @@ function isMissing(value) {
34
35
  }
35
36
  function formatNumber(value, options = {}) {
36
37
  if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;
37
- return numberFormatter(options.locale, numberOptions(options)).format(value);
38
+ const figure = numberFormatter(options.locale, numberOptions(options)).format(value);
39
+ return options.unit ? `${figure}${UNIT_SEPARATOR}${options.unit}` : figure;
38
40
  }
39
41
  function formatMoney(value, currency, options = {}) {
40
42
  if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/format.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useKitLocale } from \"../i18n/kit-labels\";\nimport { parseIsoDate } from \"./dates\";\n\n/**\n * Number, money, percentage, date and relative-time formatting — `Intl`, in one place,\n * for the figures an app prints OUTSIDE a kit component.\n *\n * Each app grew its own: kastlan's `utils/formatters.ts` (a Swiss-pinned\n * `formatNumber`/`formatCurrency`, a date-fns `formatDate`, and a `formatRelativeTime`\n * whose \"5m ago\" / \"3h ago\" / \"2d ago\" stayed English in every language), its tenancy\n * `format.ts` (`formatChf`, a `formatPct` gluing a \"+\" onto `toFixed(2)`), keksdose's\n * own set. Every one of them is `Intl` with a locale bolted on, so the only thing\n * worth sharing is the locale — and the kit already has one, the provider's.\n *\n * The plain functions take a `locale` (none: the runtime default, as every `Intl` API\n * reads `undefined`). Inside a component, {@link useKitFormat} hands back the same\n * functions bound to the `<UiKitProvider locale>`, so a page formats exactly like the\n * kit components on it.\n *\n * A missing value — `null`, `undefined`, `NaN`, an unparseable date — formats as\n * `empty` (default \"—\", the dash `StatTile` shows for no value), never as \"NaN\" or\n * \"Invalid Date\".\n */\n\n/** What every formatter here prints for a missing value, unless told otherwise. */\nexport const EMPTY_FORMATTED_VALUE = \"—\";\n\n/** Fraction digits: a number pins both the minimum and the maximum (`2` → \"3.10\");\n * an object sets them apart (a meter reading, 1–3). */\nexport type FormatDigits = number | { min?: number; max?: number };\n\ninterface BaseOptions {\n /** BCP 47 tag. Left out: the runtime default (the hook: the provider's). */\n locale?: string;\n /** Printed for a missing value. Default {@link EMPTY_FORMATTED_VALUE}. */\n empty?: string;\n}\n\nexport interface FormatNumberOptions extends BaseOptions {\n digits?: FormatDigits;\n /** Compact notation: 12 400 → \"12K\". */\n compact?: boolean;\n /** `\"exceptZero\"` for a change (\"+3\", \"−3\", \"0\"). Default: the minus only. */\n signDisplay?: Intl.NumberFormatOptions[\"signDisplay\"];\n /** Any further `Intl.NumberFormat` options, merged over the ones above. */\n options?: Intl.NumberFormatOptions;\n}\n\nexport interface FormatMoneyOptions extends FormatNumberOptions {\n /** `\"symbol\"` (default), `\"narrowSymbol\"`, `\"code\"` (\"CHF 12.00\") or `\"name\"`. */\n currencyDisplay?: Intl.NumberFormatOptions[\"currencyDisplay\"];\n}\n\nexport interface FormatPercentOptions extends FormatNumberOptions {\n /**\n * `true` (default): `value` is a RATIO, as `Intl` and `StatTile`'s percent delta read\n * it — `0.12` is 12 %. `false`: it is already a percentage — `12` is 12 %\n * (kastlan's rent `change_pct`).\n */\n ratio?: boolean;\n}\n\n// One formatter per option set: a table formats the same way thousands of times, and\n// constructing an Intl formatter is the expensive part.\nconst numberFormatters = new Map<string, Intl.NumberFormat>();\nfunction numberFormatter(locale: string | undefined, options: Intl.NumberFormatOptions): Intl.NumberFormat {\n const key = `${locale ?? \"\"}|${JSON.stringify(options)}`;\n let f = numberFormatters.get(key);\n if (!f) {\n f = new Intl.NumberFormat(locale, options);\n numberFormatters.set(key, f);\n }\n return f;\n}\n\nfunction digitOptions(digits: FormatDigits | undefined): Intl.NumberFormatOptions {\n if (digits === undefined) return {};\n if (typeof digits === \"number\") return { minimumFractionDigits: digits, maximumFractionDigits: digits };\n return {\n ...(digits.min !== undefined ? { minimumFractionDigits: digits.min } : null),\n ...(digits.max !== undefined ? { maximumFractionDigits: digits.max } : null),\n };\n}\n\nfunction numberOptions(o: FormatNumberOptions): Intl.NumberFormatOptions {\n return {\n ...digitOptions(o.digits),\n ...(o.compact ? { notation: \"compact\" } : null),\n ...(o.signDisplay ? { signDisplay: o.signDisplay } : null),\n ...o.options,\n };\n}\n\nfunction isMissing(value: number | null | undefined): value is null | undefined {\n return value === null || value === undefined || Number.isNaN(value);\n}\n\n/** A number in `locale`: \"1,234.5\", \"1.234,5\", \"1’234.5\". */\nexport function formatNumber(value: number | null | undefined, options: FormatNumberOptions = {}): string {\n if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;\n return numberFormatter(options.locale, numberOptions(options)).format(value);\n}\n\n/** An amount of `currency` (ISO 4217) in `locale`: \"CHF 1’234.50\", \"1.234,50 €\". */\nexport function formatMoney(\n value: number | null | undefined,\n currency: string,\n options: FormatMoneyOptions = {},\n): string {\n if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;\n return numberFormatter(options.locale, {\n style: \"currency\",\n currency,\n ...(options.currencyDisplay ? { currencyDisplay: options.currencyDisplay } : null),\n ...numberOptions(options),\n }).format(value);\n}\n\n/** A percentage in `locale` (\"12%\", \"12 %\", \"+1.25%\"). See {@link FormatPercentOptions.ratio}\n * for what `value` means. Default digits: at most one. */\nexport function formatPercent(value: number | null | undefined, options: FormatPercentOptions = {}): string {\n if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const ratio = options.ratio === false ? value / 100 : value;\n return numberFormatter(options.locale, {\n style: \"percent\",\n ...(options.digits === undefined ? { maximumFractionDigits: 1 } : null),\n ...numberOptions(options),\n }).format(ratio);\n}\n\n/* ── Dates ─────────────────────────────────────────────────────────────────── */\n\n/**\n * The shapes a date is printed in, each a set of `Intl.DateTimeFormat` options:\n * - `short` / `medium` / `long` / `full` — the date alone, at that `dateStyle`\n * (\"08/07/2026\", \"8 Jul 2026\", \"8 July 2026\", \"Wednesday, 8 July 2026\" in en-GB).\n * - `dateTime` — medium date and short time: a timestamp (\"8 Jul 2026, 14:05\").\n * - `time` — the short time alone (\"14:05\").\n * - `monthYear` — \"July 2026\".\n *\n * Or pass `Intl.DateTimeFormatOptions` for anything else. A date-fns PATTERN\n * (\"dd.MM.yyyy\") is deliberately not accepted: a pattern is one locale's order baked\n * into a string, which is how an English page ends up with German dates.\n */\nexport type FormatDateStyle = \"short\" | \"medium\" | \"long\" | \"full\" | \"dateTime\" | \"time\" | \"monthYear\";\n\nconst DATE_STYLES: Record<FormatDateStyle, Intl.DateTimeFormatOptions> = {\n short: { dateStyle: \"short\" },\n medium: { dateStyle: \"medium\" },\n long: { dateStyle: \"long\" },\n full: { dateStyle: \"full\" },\n dateTime: { dateStyle: \"medium\", timeStyle: \"short\" },\n time: { timeStyle: \"short\" },\n monthYear: { month: \"long\", year: \"numeric\" },\n};\n\nexport interface FormatDateOptions extends BaseOptions {\n /** An IANA zone (\"Europe/Zurich\") for a timestamp. Left out: the device's. */\n timeZone?: string;\n}\n\n/** What {@link formatDate} and {@link formatRelativeTime} accept. */\nexport type DateInput = string | number | Date | null | undefined;\n\n/**\n * `value` as a Date, or null. A bare \"YYYY-MM-DD\" is a CALENDAR day and is read on the\n * local calendar (`parseIsoDate`) — `new Date(\"2026-07-08\")` is UTC midnight, which is\n * the 7th anywhere west of Greenwich. Anything else (a full ISO timestamp, epoch\n * milliseconds, a Date) is an instant and goes through `Date` as is.\n */\nexport function toDate(value: DateInput): Date | null {\n if (value === null || value === undefined || value === \"\") return null;\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return parseIsoDate(value);\n const d = value instanceof Date ? value : new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\nconst dateFormatters = new Map<string, Intl.DateTimeFormat>();\nfunction dateFormatter(locale: string | undefined, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = `${locale ?? \"\"}|${JSON.stringify(options)}`;\n let f = dateFormatters.get(key);\n if (!f) {\n f = new Intl.DateTimeFormat(locale, options);\n dateFormatters.set(key, f);\n }\n return f;\n}\n\n/**\n * A date or timestamp in `locale`. Takes an ISO date (\"2026-07-08\", read on the local\n * calendar), an ISO timestamp (\"2026-07-08T14:05:00Z\"), epoch milliseconds or a Date.\n * `style` defaults to `medium`; see {@link FormatDateStyle}.\n *\n * `formatIsoDate` (`@eifi1/ui-kit/dates`) remains for a plain \"YYYY-MM-DD\" with an\n * explicit locale; this is its superset for timestamps and the named styles.\n */\nexport function formatDate(\n value: DateInput,\n style: FormatDateStyle | Intl.DateTimeFormatOptions = \"medium\",\n options: FormatDateOptions = {},\n): string {\n const d = toDate(value);\n if (!d) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const base = typeof style === \"string\" ? DATE_STYLES[style] : style;\n return dateFormatter(options.locale, options.timeZone ? { ...base, timeZone: options.timeZone } : base).format(d);\n}\n\nexport interface FormatRelativeTimeOptions extends BaseOptions {\n /** The moment it is measured from. Default: now. */\n now?: DateInput;\n /** `\"auto\"` (default): \"yesterday\", \"now\", \"next week\". `\"always\"`: \"1 day ago\". */\n numeric?: Intl.RelativeTimeFormatNumeric;\n /** `\"long\"` (default) \"3 hours ago\", `\"short\"` \"3 hr. ago\", `\"narrow\"` \"3h ago\". */\n style?: Intl.RelativeTimeFormatStyle;\n /**\n * Past this many days either way, print the date instead ({@link formatDate} in\n * `absoluteStyle`) — kastlan's feed switches to the date after a week, because \"5\n * weeks ago\" makes a reader do sums. Default: never.\n */\n absoluteAfterDays?: number;\n /** The style of that date. Default `medium`. */\n absoluteStyle?: FormatDateStyle | Intl.DateTimeFormatOptions;\n}\n\nconst SECOND = 1000;\nconst MINUTE = 60 * SECOND;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\n\n/** [the largest |difference| a unit is used for, the unit, its length]. */\nconst RELATIVE_STEPS: Array<[number, Intl.RelativeTimeFormatUnit, number]> = [\n [45 * SECOND, \"second\", SECOND],\n [45 * MINUTE, \"minute\", MINUTE],\n [22 * HOUR, \"hour\", HOUR],\n [6.5 * DAY, \"day\", DAY],\n [26 * DAY, \"week\", 7 * DAY],\n [320 * DAY, \"month\", 30.44 * DAY],\n [Infinity, \"year\", 365.25 * DAY],\n];\n\nconst relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();\nfunction relativeFormatter(\n locale: string | undefined,\n numeric: Intl.RelativeTimeFormatNumeric,\n style: Intl.RelativeTimeFormatStyle,\n): Intl.RelativeTimeFormat {\n const key = `${locale ?? \"\"}|${numeric}|${style}`;\n let f = relativeFormatters.get(key);\n if (!f) {\n f = new Intl.RelativeTimeFormat(locale, { numeric, style });\n relativeFormatters.set(key, f);\n }\n return f;\n}\n\n/**\n * How long ago (or until) `value` is, in `locale`'s words, through\n * `Intl.RelativeTimeFormat`: \"3 hours ago\", \"vor 3 Stunden\", \"il y a 3 heures\",\n * \"in 2 days\", and under 45 seconds \"now\". The unit is picked by size — seconds,\n * minutes, hours, days, weeks, months, years — and the count is rounded.\n */\nexport function formatRelativeTime(value: DateInput, options: FormatRelativeTimeOptions = {}): string {\n const d = toDate(value);\n if (!d) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const now = toDate(options.now ?? new Date()) ?? new Date();\n const diff = d.getTime() - now.getTime();\n const abs = Math.abs(diff);\n if (options.absoluteAfterDays !== undefined && abs > options.absoluteAfterDays * DAY) {\n return formatDate(d, options.absoluteStyle ?? \"medium\", options);\n }\n const rtf = relativeFormatter(options.locale, options.numeric ?? \"auto\", options.style ?? \"long\");\n const [, unit, size] = RELATIVE_STEPS.find(([limit]) => abs < limit)!;\n // Under 45 seconds is \"now\" rather than \"12 seconds ago\": a feed that ticks through\n // the seconds is noise, and nothing reads a timestamp to the second.\n const count = unit === \"second\" ? 0 : Math.round(diff / size);\n // `+ 0` folds -0 into 0: `format(-0, …)` says \"0 seconds ago\" instead of \"now\".\n return rtf.format(count + 0, unit);\n}\n\n/* ── Bound to the provider ─────────────────────────────────────────────────── */\n\ntype WithoutLocale<T> = Omit<T, \"locale\"> & { locale?: string };\n\n/** What {@link useKitFormat} returns: the formatters above with the provider's locale\n * as their default (an explicit `locale` in the options still wins). */\nexport interface KitFormat {\n /** The locale they format in — the provider's, or `undefined` (runtime default). */\n locale: string | undefined;\n formatNumber: (value: number | null | undefined, options?: WithoutLocale<FormatNumberOptions>) => string;\n formatMoney: (\n value: number | null | undefined,\n currency: string,\n options?: WithoutLocale<FormatMoneyOptions>,\n ) => string;\n formatPercent: (value: number | null | undefined, options?: WithoutLocale<FormatPercentOptions>) => string;\n formatDate: (\n value: DateInput,\n style?: FormatDateStyle | Intl.DateTimeFormatOptions,\n options?: WithoutLocale<FormatDateOptions>,\n ) => string;\n formatRelativeTime: (value: DateInput, options?: WithoutLocale<FormatRelativeTimeOptions>) => string;\n}\n\n/**\n * The formatters, bound to the `<UiKitProvider locale>` (or to `locale`, which wins\n * over it — the same precedence as a component's `locale` prop):\n *\n * const { formatMoney, formatRelativeTime } = useKitFormat();\n * formatMoney(row.balance, \"CHF\");\n */\nexport function useKitFormat(locale?: string): KitFormat {\n const kitLocale = useKitLocale(locale);\n return useMemo<KitFormat>(\n () => ({\n locale: kitLocale,\n formatNumber: (value, options) => formatNumber(value, { locale: kitLocale, ...options }),\n formatMoney: (value, currency, options) => formatMoney(value, currency, { locale: kitLocale, ...options }),\n formatPercent: (value, options) => formatPercent(value, { locale: kitLocale, ...options }),\n formatDate: (value, style, options) => formatDate(value, style, { locale: kitLocale, ...options }),\n formatRelativeTime: (value, options) => formatRelativeTime(value, { locale: kitLocale, ...options }),\n }),\n [kitLocale],\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/lib/format.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useKitLocale } from \"../i18n/kit-labels\";\nimport { parseIsoDate } from \"./dates\";\n\n/**\n * Number, money, percentage, date and relative-time formatting — `Intl`, in one place,\n * for the figures an app prints OUTSIDE a kit component.\n *\n * Each app grew its own: kastlan's `utils/formatters.ts` (a Swiss-pinned\n * `formatNumber`/`formatCurrency`, a date-fns `formatDate`, and a `formatRelativeTime`\n * whose \"5m ago\" / \"3h ago\" / \"2d ago\" stayed English in every language), its tenancy\n * `format.ts` (`formatChf`, a `formatPct` gluing a \"+\" onto `toFixed(2)`), keksdose's\n * own set. Every one of them is `Intl` with a locale bolted on, so the only thing\n * worth sharing is the locale — and the kit already has one, the provider's.\n *\n * The plain functions take a `locale` (none: the runtime default, as every `Intl` API\n * reads `undefined`). Inside a component, {@link useKitFormat} hands back the same\n * functions bound to the `<UiKitProvider locale>`, so a page formats exactly like the\n * kit components on it.\n *\n * A missing value — `null`, `undefined`, `NaN`, an unparseable date — formats as\n * `empty` (default \"—\", the dash `StatTile` shows for no value), never as \"NaN\" or\n * \"Invalid Date\".\n */\n\n/** What every formatter here prints for a missing value, unless told otherwise. */\nexport const EMPTY_FORMATTED_VALUE = \"—\";\n\n/** Fraction digits: a number pins both the minimum and the maximum (`2` → \"3.10\");\n * an object sets them apart (a meter reading, 1–3). */\nexport type FormatDigits = number | { min?: number; max?: number };\n\ninterface BaseOptions {\n /** BCP 47 tag. Left out: the runtime default (the hook: the provider's). */\n locale?: string;\n /** Printed for a missing value. Default {@link EMPTY_FORMATTED_VALUE}. */\n empty?: string;\n}\n\n/** The options every number formatter shares (money and percent carry their own unit). */\nexport interface FormatNumberBaseOptions extends BaseOptions {\n digits?: FormatDigits;\n /** Compact notation: 12 400 → \"12K\". */\n compact?: boolean;\n /** `\"exceptZero\"` for a change (\"+3\", \"−3\", \"0\"). Default: the minus only. */\n signDisplay?: Intl.NumberFormatOptions[\"signDisplay\"];\n /** Any further `Intl.NumberFormat` options, merged over the ones above. */\n options?: Intl.NumberFormatOptions;\n}\n\n/** The options {@link formatNumber} takes: the shared ones plus a free-text `unit`. */\nexport interface FormatNumberOptions extends FormatNumberBaseOptions {\n /**\n * A unit printed after the figure, joined by a narrow no-break space (U+202F):\n * \"3.400 N\", \"12 kg\", \"4,5 m²\". lenkbank (P8) prints forces, masses and lengths in\n * every table and summary, and each call site glued `${n} N` together with a plain\n * space — which wraps the \"N\" onto the next line in a narrow column and reads loose\n * beside the digit grouping. The narrow no-break space is the SI brochure's and the\n * Swiss typesetting rule's separator between value and unit, and it never breaks.\n *\n * Free text, not `Intl`'s `style: \"unit\"`: that one only knows the ECMA-402\n * sanctioned units (no \"N\", no \"kN\", no \"m³/h\"), so an app would still be gluing.\n * A missing value prints `empty` ALONE — \"— N\" says there is a newton-shaped\n * nothing, which is noise in a column that already heads its unit.\n */\n unit?: string;\n}\n\n/** Narrow no-break space (U+202F): between a figure and its {@link FormatNumberOptions.unit}. */\nconst UNIT_SEPARATOR = \"\\u202F\";\n\nexport interface FormatMoneyOptions extends FormatNumberBaseOptions {\n /** `\"symbol\"` (default), `\"narrowSymbol\"`, `\"code\"` (\"CHF 12.00\") or `\"name\"`. */\n currencyDisplay?: Intl.NumberFormatOptions[\"currencyDisplay\"];\n}\n\nexport interface FormatPercentOptions extends FormatNumberBaseOptions {\n /**\n * `true` (default): `value` is a RATIO, as `Intl` and `StatTile`'s percent delta read\n * it — `0.12` is 12 %. `false`: it is already a percentage — `12` is 12 %\n * (kastlan's rent `change_pct`).\n */\n ratio?: boolean;\n}\n\n// One formatter per option set: a table formats the same way thousands of times, and\n// constructing an Intl formatter is the expensive part.\nconst numberFormatters = new Map<string, Intl.NumberFormat>();\nfunction numberFormatter(locale: string | undefined, options: Intl.NumberFormatOptions): Intl.NumberFormat {\n const key = `${locale ?? \"\"}|${JSON.stringify(options)}`;\n let f = numberFormatters.get(key);\n if (!f) {\n f = new Intl.NumberFormat(locale, options);\n numberFormatters.set(key, f);\n }\n return f;\n}\n\nfunction digitOptions(digits: FormatDigits | undefined): Intl.NumberFormatOptions {\n if (digits === undefined) return {};\n if (typeof digits === \"number\") return { minimumFractionDigits: digits, maximumFractionDigits: digits };\n return {\n ...(digits.min !== undefined ? { minimumFractionDigits: digits.min } : null),\n ...(digits.max !== undefined ? { maximumFractionDigits: digits.max } : null),\n };\n}\n\nfunction numberOptions(o: FormatNumberBaseOptions): Intl.NumberFormatOptions {\n return {\n ...digitOptions(o.digits),\n ...(o.compact ? { notation: \"compact\" } : null),\n ...(o.signDisplay ? { signDisplay: o.signDisplay } : null),\n ...o.options,\n };\n}\n\nfunction isMissing(value: number | null | undefined): value is null | undefined {\n return value === null || value === undefined || Number.isNaN(value);\n}\n\n/** A number in `locale`: \"1,234.5\", \"1.234,5\", \"1’234.5\" — with `unit`, \"3.400 N\". */\nexport function formatNumber(value: number | null | undefined, options: FormatNumberOptions = {}): string {\n if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const figure = numberFormatter(options.locale, numberOptions(options)).format(value);\n return options.unit ? `${figure}${UNIT_SEPARATOR}${options.unit}` : figure;\n}\n\n/** An amount of `currency` (ISO 4217) in `locale`: \"CHF 1’234.50\", \"1.234,50 €\". */\nexport function formatMoney(\n value: number | null | undefined,\n currency: string,\n options: FormatMoneyOptions = {},\n): string {\n if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;\n return numberFormatter(options.locale, {\n style: \"currency\",\n currency,\n ...(options.currencyDisplay ? { currencyDisplay: options.currencyDisplay } : null),\n ...numberOptions(options),\n }).format(value);\n}\n\n/** A percentage in `locale` (\"12%\", \"12 %\", \"+1.25%\"). See {@link FormatPercentOptions.ratio}\n * for what `value` means. Default digits: at most one. */\nexport function formatPercent(value: number | null | undefined, options: FormatPercentOptions = {}): string {\n if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const ratio = options.ratio === false ? value / 100 : value;\n return numberFormatter(options.locale, {\n style: \"percent\",\n ...(options.digits === undefined ? { maximumFractionDigits: 1 } : null),\n ...numberOptions(options),\n }).format(ratio);\n}\n\n/* ── Dates ─────────────────────────────────────────────────────────────────── */\n\n/**\n * The shapes a date is printed in, each a set of `Intl.DateTimeFormat` options:\n * - `short` / `medium` / `long` / `full` — the date alone, at that `dateStyle`\n * (\"08/07/2026\", \"8 Jul 2026\", \"8 July 2026\", \"Wednesday, 8 July 2026\" in en-GB).\n * - `dateTime` — medium date and short time: a timestamp (\"8 Jul 2026, 14:05\").\n * - `time` — the short time alone (\"14:05\").\n * - `monthYear` — \"July 2026\".\n *\n * Or pass `Intl.DateTimeFormatOptions` for anything else. A date-fns PATTERN\n * (\"dd.MM.yyyy\") is deliberately not accepted: a pattern is one locale's order baked\n * into a string, which is how an English page ends up with German dates.\n */\nexport type FormatDateStyle = \"short\" | \"medium\" | \"long\" | \"full\" | \"dateTime\" | \"time\" | \"monthYear\";\n\nconst DATE_STYLES: Record<FormatDateStyle, Intl.DateTimeFormatOptions> = {\n short: { dateStyle: \"short\" },\n medium: { dateStyle: \"medium\" },\n long: { dateStyle: \"long\" },\n full: { dateStyle: \"full\" },\n dateTime: { dateStyle: \"medium\", timeStyle: \"short\" },\n time: { timeStyle: \"short\" },\n monthYear: { month: \"long\", year: \"numeric\" },\n};\n\nexport interface FormatDateOptions extends BaseOptions {\n /** An IANA zone (\"Europe/Zurich\") for a timestamp. Left out: the device's. */\n timeZone?: string;\n}\n\n/** What {@link formatDate} and {@link formatRelativeTime} accept. */\nexport type DateInput = string | number | Date | null | undefined;\n\n/**\n * `value` as a Date, or null. A bare \"YYYY-MM-DD\" is a CALENDAR day and is read on the\n * local calendar (`parseIsoDate`) — `new Date(\"2026-07-08\")` is UTC midnight, which is\n * the 7th anywhere west of Greenwich. Anything else (a full ISO timestamp, epoch\n * milliseconds, a Date) is an instant and goes through `Date` as is.\n */\nexport function toDate(value: DateInput): Date | null {\n if (value === null || value === undefined || value === \"\") return null;\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return parseIsoDate(value);\n const d = value instanceof Date ? value : new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\nconst dateFormatters = new Map<string, Intl.DateTimeFormat>();\nfunction dateFormatter(locale: string | undefined, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = `${locale ?? \"\"}|${JSON.stringify(options)}`;\n let f = dateFormatters.get(key);\n if (!f) {\n f = new Intl.DateTimeFormat(locale, options);\n dateFormatters.set(key, f);\n }\n return f;\n}\n\n/**\n * A date or timestamp in `locale`. Takes an ISO date (\"2026-07-08\", read on the local\n * calendar), an ISO timestamp (\"2026-07-08T14:05:00Z\"), epoch milliseconds or a Date.\n * `style` defaults to `medium`; see {@link FormatDateStyle}.\n *\n * `formatIsoDate` (`@eifi1/ui-kit/dates`) remains for a plain \"YYYY-MM-DD\" with an\n * explicit locale; this is its superset for timestamps and the named styles.\n */\nexport function formatDate(\n value: DateInput,\n style: FormatDateStyle | Intl.DateTimeFormatOptions = \"medium\",\n options: FormatDateOptions = {},\n): string {\n const d = toDate(value);\n if (!d) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const base = typeof style === \"string\" ? DATE_STYLES[style] : style;\n return dateFormatter(options.locale, options.timeZone ? { ...base, timeZone: options.timeZone } : base).format(d);\n}\n\nexport interface FormatRelativeTimeOptions extends BaseOptions {\n /** The moment it is measured from. Default: now. */\n now?: DateInput;\n /** `\"auto\"` (default): \"yesterday\", \"now\", \"next week\". `\"always\"`: \"1 day ago\". */\n numeric?: Intl.RelativeTimeFormatNumeric;\n /** `\"long\"` (default) \"3 hours ago\", `\"short\"` \"3 hr. ago\", `\"narrow\"` \"3h ago\". */\n style?: Intl.RelativeTimeFormatStyle;\n /**\n * Past this many days either way, print the date instead ({@link formatDate} in\n * `absoluteStyle`) — kastlan's feed switches to the date after a week, because \"5\n * weeks ago\" makes a reader do sums. Default: never.\n */\n absoluteAfterDays?: number;\n /** The style of that date. Default `medium`. */\n absoluteStyle?: FormatDateStyle | Intl.DateTimeFormatOptions;\n}\n\nconst SECOND = 1000;\nconst MINUTE = 60 * SECOND;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\n\n/** [the largest |difference| a unit is used for, the unit, its length]. */\nconst RELATIVE_STEPS: Array<[number, Intl.RelativeTimeFormatUnit, number]> = [\n [45 * SECOND, \"second\", SECOND],\n [45 * MINUTE, \"minute\", MINUTE],\n [22 * HOUR, \"hour\", HOUR],\n [6.5 * DAY, \"day\", DAY],\n [26 * DAY, \"week\", 7 * DAY],\n [320 * DAY, \"month\", 30.44 * DAY],\n [Infinity, \"year\", 365.25 * DAY],\n];\n\nconst relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();\nfunction relativeFormatter(\n locale: string | undefined,\n numeric: Intl.RelativeTimeFormatNumeric,\n style: Intl.RelativeTimeFormatStyle,\n): Intl.RelativeTimeFormat {\n const key = `${locale ?? \"\"}|${numeric}|${style}`;\n let f = relativeFormatters.get(key);\n if (!f) {\n f = new Intl.RelativeTimeFormat(locale, { numeric, style });\n relativeFormatters.set(key, f);\n }\n return f;\n}\n\n/**\n * How long ago (or until) `value` is, in `locale`'s words, through\n * `Intl.RelativeTimeFormat`: \"3 hours ago\", \"vor 3 Stunden\", \"il y a 3 heures\",\n * \"in 2 days\", and under 45 seconds \"now\". The unit is picked by size — seconds,\n * minutes, hours, days, weeks, months, years — and the count is rounded.\n */\nexport function formatRelativeTime(value: DateInput, options: FormatRelativeTimeOptions = {}): string {\n const d = toDate(value);\n if (!d) return options.empty ?? EMPTY_FORMATTED_VALUE;\n const now = toDate(options.now ?? new Date()) ?? new Date();\n const diff = d.getTime() - now.getTime();\n const abs = Math.abs(diff);\n if (options.absoluteAfterDays !== undefined && abs > options.absoluteAfterDays * DAY) {\n return formatDate(d, options.absoluteStyle ?? \"medium\", options);\n }\n const rtf = relativeFormatter(options.locale, options.numeric ?? \"auto\", options.style ?? \"long\");\n const [, unit, size] = RELATIVE_STEPS.find(([limit]) => abs < limit)!;\n // Under 45 seconds is \"now\" rather than \"12 seconds ago\": a feed that ticks through\n // the seconds is noise, and nothing reads a timestamp to the second.\n const count = unit === \"second\" ? 0 : Math.round(diff / size);\n // `+ 0` folds -0 into 0: `format(-0, …)` says \"0 seconds ago\" instead of \"now\".\n return rtf.format(count + 0, unit);\n}\n\n/* ── Bound to the provider ─────────────────────────────────────────────────── */\n\ntype WithoutLocale<T> = Omit<T, \"locale\"> & { locale?: string };\n\n/** What {@link useKitFormat} returns: the formatters above with the provider's locale\n * as their default (an explicit `locale` in the options still wins). */\nexport interface KitFormat {\n /** The locale they format in — the provider's, or `undefined` (runtime default). */\n locale: string | undefined;\n formatNumber: (value: number | null | undefined, options?: WithoutLocale<FormatNumberOptions>) => string;\n formatMoney: (\n value: number | null | undefined,\n currency: string,\n options?: WithoutLocale<FormatMoneyOptions>,\n ) => string;\n formatPercent: (value: number | null | undefined, options?: WithoutLocale<FormatPercentOptions>) => string;\n formatDate: (\n value: DateInput,\n style?: FormatDateStyle | Intl.DateTimeFormatOptions,\n options?: WithoutLocale<FormatDateOptions>,\n ) => string;\n formatRelativeTime: (value: DateInput, options?: WithoutLocale<FormatRelativeTimeOptions>) => string;\n}\n\n/**\n * The formatters, bound to the `<UiKitProvider locale>` (or to `locale`, which wins\n * over it — the same precedence as a component's `locale` prop):\n *\n * const { formatMoney, formatRelativeTime } = useKitFormat();\n * formatMoney(row.balance, \"CHF\");\n */\nexport function useKitFormat(locale?: string): KitFormat {\n const kitLocale = useKitLocale(locale);\n return useMemo<KitFormat>(\n () => ({\n locale: kitLocale,\n formatNumber: (value, options) => formatNumber(value, { locale: kitLocale, ...options }),\n formatMoney: (value, currency, options) => formatMoney(value, currency, { locale: kitLocale, ...options }),\n formatPercent: (value, options) => formatPercent(value, { locale: kitLocale, ...options }),\n formatDate: (value, style, options) => formatDate(value, style, { locale: kitLocale, ...options }),\n formatRelativeTime: (value, options) => formatRelativeTime(value, { locale: kitLocale, ...options }),\n }),\n [kitLocale],\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ReactElement } from 'react';
3
3
  import { FieldValues, FieldPath, ControllerProps, ControllerRenderProps, ControllerFieldState } from 'react-hook-form';
4
- import { aH as SelectProps, aw as InputProps, aQ as TextareaProps } from '../kit-labels-v3biUF1L.js';
4
+ import { aJ as SelectProps, ay as InputProps, aS as TextareaProps } from '../kit-labels-Mz8zZHIF.js';
5
5
  import { NumberFieldProps } from '../components/number-field.js';
6
6
  import { DatePickerProps } from '../components/date-picker.js';
7
7
  import { CheckboxProps } from '../components/checkbox.js';
@@ -80,9 +80,17 @@ interface RhfFieldBaseProps<TFieldValues extends FieldValues = FieldValues, TNam
80
80
  /** Draws the label's required mark and sets `aria-required` where the control
81
81
  * takes it. Whether the field IS required is `rules`' or the resolver's to say. */
82
82
  required?: boolean;
83
- /** Disables the field — through react-hook-form, so its value is left out of the
84
- * submitted values as a disabled input's would be. */
83
+ /** Disables the control and KEEPS the value: a field locked to a preset (a lease's
84
+ * preselected unit, a fixed period) still submits it, and `rules` still run.
85
+ * react-hook-form's own Controller `disabled` drops the value from `handleSubmit`'s
86
+ * data instead, which a locked preset must never do (kastlan, 0.12). To get that,
87
+ * add `excludeWhenDisabled`. A form-wide `useForm({ disabled })` still disables
88
+ * every field the RHF way. */
85
89
  disabled?: boolean;
90
+ /** With `disabled`: disable through react-hook-form, so the value is left out of
91
+ * the submitted data and validation skips it, like a disabled native input in a
92
+ * plain form post. Default `false`. */
93
+ excludeWhenDisabled?: boolean;
86
94
  /** Classes for the item's box (a `grid gap-1`). */
87
95
  className?: string;
88
96
  }
@@ -126,18 +134,27 @@ interface RhfFieldProps<TFieldValues extends FieldValues = FieldValues, TName ex
126
134
  * )} />
127
135
  * ```
128
136
  */
129
- declare function RhfField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, render, asControl, message, showLabel, }: RhfFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
130
- type OwnInputProps = Omit<InputProps, "name" | "value" | "defaultValue" | "onChange" | "onBlur" | "ref" | "label" | "error" | "invalid" | "className" | "disabled" | "required">;
137
+ declare function RhfField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, render, asControl, message, showLabel, }: RhfFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
138
+ type OwnInputProps = Omit<InputProps, "name" | "value" | "defaultValue" | "onChange" | "onBlur" | "ref" | "label" | "error" | "invalid" | "className" | "disabled" | "required" | "inputClassName"> & {
139
+ /**
140
+ * Classes for the `<input>` — `className` is the item's box (kastlan 42: a
141
+ * `font-mono` IBAN, a `tabular-nums` reference number). {@link RhfTextarea} and
142
+ * {@link RhfNumberField} had it; this one only reached `Input`'s prop of the same
143
+ * name by accident of the rest-spread, undocumented and one refactor from being
144
+ * dropped. Declared, it is part of the contract the three share.
145
+ */
146
+ inputClassName?: string;
147
+ };
131
148
  type RhfTextFieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnInputProps;
132
149
  /** A text {@link Input} — `type` for email, tel, password, url. Stores the string. */
133
- declare function RhfTextField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, ...inputProps }: RhfTextFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
150
+ declare function RhfTextField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, ...inputProps }: RhfTextFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
134
151
  type OwnTextareaProps = Omit<TextareaProps, "name" | "value" | "defaultValue" | "onChange" | "onBlur" | "ref" | "label" | "error" | "invalid" | "className" | "disabled" | "required"> & {
135
152
  /** Classes for the `<textarea>`. */
136
153
  inputClassName?: string;
137
154
  };
138
155
  type RhfTextareaProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextareaProps;
139
156
  /** A multi-line {@link Textarea}; takes `rows`. Stores the string. */
140
- declare function RhfTextarea<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, inputClassName, ...areaProps }: RhfTextareaProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
157
+ declare function RhfTextarea<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, inputClassName, ...areaProps }: RhfTextareaProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
141
158
  type RhfNumberFieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & Pick<NumberFieldProps, "digits" | "min" | "max" | "step" | "calculator" | "unit" | "unitPlacement" | "placeholder" | "inputClassName" | "locale" | "ariaLabel" | "autoFocus"> & {
142
159
  /** What an emptied field stores. Default `null`; `""` for a schema written
143
160
  * against a native number input (`z.coerce.number()` over `""`). */
@@ -151,7 +168,25 @@ type RhfNumberFieldProps<TFieldValues extends FieldValues = FieldValues, TName e
151
168
  * `max`) number, committed on blur or Enter in the locale's decimal mark. Stores a
152
169
  * number, or `emptyValue` when emptied.
153
170
  */
154
- declare function RhfNumberField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, emptyValue, nullable, ...numberProps }: RhfNumberFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
171
+ declare function RhfNumberField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, emptyValue, nullable, ...numberProps }: RhfNumberFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
172
+ type RhfIntegerFieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfNumberFieldProps<TFieldValues, TName, TTransformed>;
173
+ /**
174
+ * {@link RhfNumberField} for a whole number — a floor, a room count, a year, a
175
+ * notice period in months. Every such call site in kastlan (item 41) spelled out the
176
+ * same three props, `digits={0} calculator={false} emptyValue=""`, and a preset
177
+ * written thirty times is one that is eventually written wrong once:
178
+ *
179
+ * - `digits={0}`: rounds on commit, so "2.5" rooms settles to 3 instead of reaching
180
+ * an `Integer` column and failing server-side;
181
+ * - `calculator={false}`: a count is typed, not worked out — the trigger is noise
182
+ * beside a two-digit field;
183
+ * - `emptyValue=""`: kastlan's integer schemas are `z.coerce.number()` over `""`,
184
+ * written against the native number inputs these fields replaced.
185
+ *
186
+ * Each is only a default: pass the prop to override it (`emptyValue={null}` for a
187
+ * nullable column). Everything else is {@link RhfNumberField}'s.
188
+ */
189
+ declare function RhfIntegerField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>(props: RhfIntegerFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
155
190
  type RhfMoneyFieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & {
156
191
  placeholder?: string;
157
192
  /** The currency chip's code ("CHF"). */
@@ -173,13 +208,20 @@ type RhfMoneyFieldProps<TFieldValues extends FieldValues = FieldValues, TName ex
173
208
  valueAs?: "number" | "string";
174
209
  /** What an emptied field stores when `valueAs` is `"number"`. Default `null`. */
175
210
  emptyValue?: null | "";
211
+ /** Decimals the amount settles to on blur, Enter or a calculator result. Default:
212
+ * the currency's minor unit (CHF 2, JPY 0). See {@link AmountInput}'s `digits`. */
213
+ digits?: number;
214
+ /** Clamp the settled amount (a release capped at the deposit's balance). Validate
215
+ * with `rules` as well if a clamp needs explaining. */
216
+ min?: number;
217
+ max?: number;
176
218
  };
177
219
  /**
178
220
  * The kit's {@link AmountInput}: a money figure with its currency chip and the
179
221
  * calculator ("1200+80" resolves on blur or Enter). Stores a number by default — see
180
222
  * `valueAs`.
181
223
  */
182
- declare function RhfMoneyField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, ...amountProps }: RhfMoneyFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
224
+ declare function RhfMoneyField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, ...amountProps }: RhfMoneyFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
183
225
  type RhfDateFieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & Omit<DatePickerProps, "value" | "onChange" | "label" | "invalid" | "disabled" | "className" | "id"> & {
184
226
  /** Classes for the picker. Default `w-full`. */
185
227
  inputClassName?: string;
@@ -188,7 +230,7 @@ type RhfDateFieldProps<TFieldValues extends FieldValues = FieldValues, TName ext
188
230
  emptyValue?: "" | null;
189
231
  };
190
232
  /** The kit's {@link DatePicker}, holding an ISO `"YYYY-MM-DD"` string. */
191
- declare function RhfDateField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, inputClassName, emptyValue, ...pickerProps }: RhfDateFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
233
+ declare function RhfDateField<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, inputClassName, emptyValue, ...pickerProps }: RhfDateFieldProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
192
234
  interface RhfSelectOption {
193
235
  value: string | number;
194
236
  label: ReactNode;
@@ -207,14 +249,14 @@ type RhfSelectProps<TFieldValues extends FieldValues = FieldValues, TName extend
207
249
  selectClassName?: string;
208
250
  };
209
251
  /** A native {@link Select}, from `options` or `<option>` children. */
210
- declare function RhfSelect<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, options, children, placeholder, valueAsNumber, selectClassName, ...selectProps }: RhfSelectProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
252
+ declare function RhfSelect<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, options, children, placeholder, valueAsNumber, selectClassName, ...selectProps }: RhfSelectProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
211
253
  type RhfCheckboxProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & Pick<CheckboxProps, "inputClassName" | "autoFocus" | "aria-label">;
212
254
  /**
213
255
  * The kit's {@link Checkbox}, label beside the box and `hint` under it (the
214
256
  * checkbox's own `description`). Stores a boolean. `required` is the native one here
215
257
  * — see Checkbox — so a `<form>` refuses to submit it unticked.
216
258
  */
217
- declare function RhfCheckbox<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, ...boxProps }: RhfCheckboxProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
259
+ declare function RhfCheckbox<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, ...boxProps }: RhfCheckboxProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
218
260
  type RhfComboboxProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, V extends string | number = string | number, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & Pick<EntityComboboxProps<V>, "options" | "loadOptions" | "loading" | "placeholder" | "searchPlaceholder" | "emptyLabel" | "clearable" | "clearLabel" | "onCreate" | "createLabel" | "filter" | "minChars" | "debounceMs"> & {
219
261
  /** What a clear stores — the picker's `clearValue`. Default `null`; `""` for a
220
262
  * schema that spells "no choice" as an empty string. */
@@ -227,7 +269,7 @@ type RhfComboboxProps<TFieldValues extends FieldValues = FieldValues, TName exte
227
269
  * Stores the option's `value`, or `clearValue` on a clear (only offered with
228
270
  * `clearable`).
229
271
  */
230
- declare function RhfCombobox<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, V extends string | number = string | number, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, clearValue, comboClassName, ...comboProps }: RhfComboboxProps<TFieldValues, TName, V, TTransformed>): react.JSX.Element;
272
+ declare function RhfCombobox<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, V extends string | number = string | number, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, clearValue, comboClassName, ...comboProps }: RhfComboboxProps<TFieldValues, TName, V, TTransformed>): react.JSX.Element;
231
273
  type RhfTextComboboxProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & Pick<ComboboxProps, "options" | "placeholder" | "groupBy" | "maxSuggestions" | "searchPlaceholder" | "createLabel" | "optionAdornment" | "autoFocus" | "aria-label"> & {
232
274
  /** Classes for the combobox. */
233
275
  comboClassName?: string;
@@ -236,6 +278,6 @@ type RhfTextComboboxProps<TFieldValues extends FieldValues = FieldValues, TName
236
278
  * The kit's free-text {@link Combobox}: type anything, or pick one of `options`.
237
279
  * Stores the string.
238
280
  */
239
- declare function RhfTextCombobox<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, className, comboClassName, ...comboProps }: RhfTextComboboxProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
281
+ declare function RhfTextCombobox<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TTransformed = TFieldValues>({ name, control, rules, label, hint, required, disabled, excludeWhenDisabled, className, comboClassName, ...comboProps }: RhfTextComboboxProps<TFieldValues, TName, TTransformed>): react.JSX.Element;
240
282
 
241
- export { RhfCheckbox, type RhfCheckboxProps, RhfCombobox, type RhfComboboxProps, RhfDateField, type RhfDateFieldProps, RhfField, type RhfFieldBaseProps, type RhfFieldProps, type RhfFieldRenderContext, RhfMoneyField, type RhfMoneyFieldProps, RhfNumberField, type RhfNumberFieldProps, RhfSelect, type RhfSelectOption, type RhfSelectProps, RhfTextCombobox, type RhfTextComboboxProps, RhfTextField, type RhfTextFieldProps, RhfTextarea, type RhfTextareaProps };
283
+ export { RhfCheckbox, type RhfCheckboxProps, RhfCombobox, type RhfComboboxProps, RhfDateField, type RhfDateFieldProps, RhfField, type RhfFieldBaseProps, type RhfFieldProps, type RhfFieldRenderContext, RhfIntegerField, type RhfIntegerFieldProps, RhfMoneyField, type RhfMoneyFieldProps, RhfNumberField, type RhfNumberFieldProps, RhfSelect, type RhfSelectOption, type RhfSelectProps, RhfTextCombobox, type RhfTextComboboxProps, RhfTextField, type RhfTextFieldProps, RhfTextarea, type RhfTextareaProps };