@eifi1/ui-kit 0.12.0 → 0.13.1
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.
- package/README.md +10 -10
- package/dist/components/amount-input.d.ts +23 -1
- package/dist/components/amount-input.js +78 -13
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/bulk-action-bar.d.ts +10 -2
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-group.d.ts +1 -1
- package/dist/components/calculator.d.ts +1 -1
- package/dist/components/chart.js +14 -8
- package/dist/components/chart.js.map +1 -1
- package/dist/components/chip.js +20 -15
- package/dist/components/chip.js.map +1 -1
- package/dist/components/combobox-core.d.ts +3 -1
- package/dist/components/combobox-core.js +16 -5
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/copy-button.d.ts +1 -1
- package/dist/components/data-table-filter-popover.js +8 -1
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table.js +28 -20
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/entity-combobox.js +22 -17
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/error-boundary.d.ts +202 -13
- package/dist/components/error-boundary.js +225 -21
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/field-sync.js +90 -83
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/file-button.d.ts +1 -1
- package/dist/components/file-dropzone.d.ts +1 -1
- package/dist/components/form-actions.d.ts +1 -1
- package/dist/components/full-bleed-dialog.js +4 -0
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/hover-menu.js +64 -56
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/list.d.ts +14 -2
- package/dist/components/list.js +3 -1
- package/dist/components/list.js.map +1 -1
- package/dist/components/modal.js.map +1 -1
- package/dist/components/multi-entity-combobox.js +23 -17
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/number-field.d.ts +1 -1
- package/dist/components/number-input.d.ts +1 -1
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.d.ts +10 -2
- package/dist/components/numpad-sheet.js +6 -4
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/page-header.d.ts +35 -6
- package/dist/components/page-header.js +7 -1
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/picker-sheet.js +3 -0
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/popover.js +3 -0
- package/dist/components/popover.js.map +1 -1
- package/dist/components/settings-fields.d.ts +1 -1
- package/dist/components/signed-amount.d.ts +2 -1
- package/dist/components/signed-amount.js +1 -1
- package/dist/components/signed-amount.js.map +1 -1
- package/dist/components/stat-tile.js +1 -1
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/swipeable-row.js +4 -3
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/text-link.d.ts +73 -11
- package/dist/components/text-link.js +45 -10
- package/dist/components/text-link.js.map +1 -1
- package/dist/components/text.d.ts +26 -2
- package/dist/components/text.js +16 -2
- package/dist/components/text.js.map +1 -1
- package/dist/components/time-input.d.ts +1 -1
- package/dist/components/toggle-group.d.ts +22 -0
- package/dist/components/toggle-group.js +8 -8
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +17 -0
- package/dist/components/toggle-legend.js +6 -2
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/tooltip.d.ts +51 -1
- package/dist/components/tooltip.js +59 -35
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/ui.d.ts +1 -1
- package/dist/components/ui.js +166 -28
- package/dist/components/ui.js.map +1 -1
- package/dist/feedback/feedback-attachment.js +4 -6
- package/dist/feedback/feedback-attachment.js.map +1 -1
- package/dist/feedback/feedback-dialog.js +5 -3
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-inbox.js +86 -75
- package/dist/feedback/feedback-inbox.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +43 -3
- package/dist/feedback/feedback-thread.js +53 -26
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +1 -1
- package/dist/hooks/use-file-drop.d.ts +1 -1
- package/dist/i18n/defaults.d.ts +1 -1
- package/dist/i18n/kit-labels.d.ts +1 -1
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/de-CH-informal.d.ts +1 -1
- package/dist/i18n/locales/de-CH.d.ts +1 -1
- package/dist/i18n/locales/de-informal.d.ts +1 -1
- package/dist/i18n/locales/de.d.ts +1 -1
- package/dist/i18n/locales/de.js +9 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +1 -1
- package/dist/i18n/locales/es.js +9 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +1 -1
- package/dist/i18n/locales/fr.js +9 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +1 -1
- package/dist/i18n/locales/hu.js +9 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +1 -1
- package/dist/i18n/locales/it.js +9 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +1 -1
- package/dist/i18n/locales/zh.js +9 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/{kit-labels-v3biUF1L.d.ts → kit-labels-Mz8zZHIF.d.ts} +102 -3
- package/dist/lib/format.d.ts +23 -5
- package/dist/lib/format.js +4 -2
- package/dist/lib/format.js.map +1 -1
- package/dist/rhf/fields.d.ts +59 -15
- package/dist/rhf/fields.js +41 -11
- package/dist/rhf/fields.js.map +1 -1
- package/dist/rhf/form.d.ts +1 -1
- package/dist/rhf.d.ts +2 -2
- package/dist/rhf.js.map +1 -1
- package/dist/search/command-palette.js +20 -14
- package/dist/search/command-palette.js.map +1 -1
- package/dist/shell/app-shell.d.ts +1 -1
- package/dist/shell/app-shell.js +62 -54
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/top-bar-brand.d.ts +1 -1
- package/dist/shell/topbar-action-menu.d.ts +9 -3
- package/dist/shell/topbar-action-menu.js +2 -1
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell.d.ts +1 -1
- package/dist/tour/tour.js +10 -4
- package/dist/tour/tour.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +1 -1
- package/dist/wizard/use-wizard.js +4 -2
- package/dist/wizard/use-wizard.js.map +1 -1
- package/dist/wizard/wizard-step.d.ts +11 -1
- package/dist/wizard/wizard-step.js +24 -6
- package/dist/wizard/wizard-step.js.map +1 -1
- package/dist/wizard.d.ts +1 -1
- package/package.json +6 -6
- package/src/components/amount-input.tsx +165 -12
- package/src/components/bulk-action-bar.tsx +16 -3
- package/src/components/chart.tsx +19 -8
- package/src/components/chip.tsx +6 -0
- package/src/components/combobox-core.tsx +28 -9
- package/src/components/combobox.tsx +2 -0
- package/src/components/data-table-filter-popover.tsx +13 -5
- package/src/components/data-table.tsx +6 -0
- package/src/components/entity-combobox.tsx +7 -4
- package/src/components/error-boundary.tsx +470 -30
- package/src/components/field-sync.tsx +48 -40
- package/src/components/full-bleed-dialog.tsx +4 -0
- package/src/components/hover-menu.tsx +26 -17
- package/src/components/list.tsx +17 -3
- package/src/components/modal.tsx +4 -0
- package/src/components/multi-entity-combobox.tsx +8 -4
- package/src/components/number-input.tsx +1 -0
- package/src/components/numpad-sheet.tsx +17 -3
- package/src/components/page-header.tsx +42 -5
- package/src/components/picker-sheet.tsx +3 -0
- package/src/components/popover.tsx +3 -0
- package/src/components/signed-amount.tsx +12 -3
- package/src/components/stat-tile.tsx +3 -1
- package/src/components/swipeable-row.tsx +7 -7
- package/src/components/text-link.tsx +126 -18
- package/src/components/text.tsx +47 -2
- package/src/components/toggle-group.tsx +35 -10
- package/src/components/toggle-legend.tsx +22 -1
- package/src/components/tooltip.tsx +79 -8
- package/src/components/ui.tsx +307 -39
- package/src/feedback/feedback-attachment.tsx +10 -7
- package/src/feedback/feedback-dialog.tsx +7 -4
- package/src/feedback/feedback-inbox.tsx +7 -0
- package/src/feedback/feedback-thread.tsx +109 -33
- package/src/i18n/kit-labels.tsx +16 -0
- package/src/i18n/locales/de.ts +8 -0
- package/src/i18n/locales/es.ts +8 -0
- package/src/i18n/locales/fr.ts +8 -0
- package/src/i18n/locales/hu.ts +8 -0
- package/src/i18n/locales/it.ts +8 -0
- package/src/i18n/locales/zh.ts +8 -0
- package/src/lib/format.ts +32 -7
- package/src/rhf/fields.tsx +99 -16
- package/src/rhf.ts +1 -1
- package/src/search/command-palette.tsx +29 -19
- package/src/shell/app-shell.tsx +6 -1
- package/src/shell/topbar-action-menu.tsx +11 -4
- package/src/tour/tour.tsx +16 -5
- package/src/wizard/use-wizard.ts +8 -4
- 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
|
|
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?:
|
|
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,
|
|
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 };
|
package/dist/lib/format.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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 };
|
package/dist/lib/format.js
CHANGED
|
@@ -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)}`;
|
|
@@ -30,11 +31,12 @@ function numberOptions(o) {
|
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
function isMissing(value) {
|
|
33
|
-
return value === null || value === void 0 || Number.
|
|
34
|
+
return value === null || value === void 0 || !Number.isFinite(value);
|
|
34
35
|
}
|
|
35
36
|
function formatNumber(value, options = {}) {
|
|
36
37
|
if (isMissing(value)) return options.empty ?? EMPTY_FORMATTED_VALUE;
|
|
37
|
-
|
|
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;
|
package/dist/lib/format.js.map
CHANGED
|
@@ -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 // ±Infinity too (lenkbank, adopting 0.13): a division by zero upstream is a missing\n // figure, and \"∞\" printed in a money or measurement column reads like data.\n return value === null || value === undefined || !Number.isFinite(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":[]}
|
package/dist/rhf/fields.d.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
84
|
-
*
|
|
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,22 @@ 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). ⚠️ A unit price or a rate needs its
|
|
213
|
+
* column's scale here (`digits={4}` for 1.789 €/l), or it is stored rounded to
|
|
214
|
+
* cents without a word (keksdose G2). See {@link AmountInput}'s `digits`. */
|
|
215
|
+
digits?: number;
|
|
216
|
+
/** Clamp the settled amount (a release capped at the deposit's balance). Validate
|
|
217
|
+
* with `rules` as well if a clamp needs explaining. */
|
|
218
|
+
min?: number;
|
|
219
|
+
max?: number;
|
|
176
220
|
};
|
|
177
221
|
/**
|
|
178
222
|
* The kit's {@link AmountInput}: a money figure with its currency chip and the
|
|
179
223
|
* calculator ("1200+80" resolves on blur or Enter). Stores a number by default — see
|
|
180
224
|
* `valueAs`.
|
|
181
225
|
*/
|
|
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;
|
|
226
|
+
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
227
|
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
228
|
/** Classes for the picker. Default `w-full`. */
|
|
185
229
|
inputClassName?: string;
|
|
@@ -188,7 +232,7 @@ type RhfDateFieldProps<TFieldValues extends FieldValues = FieldValues, TName ext
|
|
|
188
232
|
emptyValue?: "" | null;
|
|
189
233
|
};
|
|
190
234
|
/** 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;
|
|
235
|
+
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
236
|
interface RhfSelectOption {
|
|
193
237
|
value: string | number;
|
|
194
238
|
label: ReactNode;
|
|
@@ -207,14 +251,14 @@ type RhfSelectProps<TFieldValues extends FieldValues = FieldValues, TName extend
|
|
|
207
251
|
selectClassName?: string;
|
|
208
252
|
};
|
|
209
253
|
/** 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;
|
|
254
|
+
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
255
|
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
256
|
/**
|
|
213
257
|
* The kit's {@link Checkbox}, label beside the box and `hint` under it (the
|
|
214
258
|
* checkbox's own `description`). Stores a boolean. `required` is the native one here
|
|
215
259
|
* — see Checkbox — so a `<form>` refuses to submit it unticked.
|
|
216
260
|
*/
|
|
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;
|
|
261
|
+
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
262
|
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
263
|
/** What a clear stores — the picker's `clearValue`. Default `null`; `""` for a
|
|
220
264
|
* schema that spells "no choice" as an empty string. */
|
|
@@ -227,7 +271,7 @@ type RhfComboboxProps<TFieldValues extends FieldValues = FieldValues, TName exte
|
|
|
227
271
|
* Stores the option's `value`, or `clearValue` on a clear (only offered with
|
|
228
272
|
* `clearable`).
|
|
229
273
|
*/
|
|
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;
|
|
274
|
+
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
275
|
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
276
|
/** Classes for the combobox. */
|
|
233
277
|
comboClassName?: string;
|
|
@@ -236,6 +280,6 @@ type RhfTextComboboxProps<TFieldValues extends FieldValues = FieldValues, TName
|
|
|
236
280
|
* The kit's free-text {@link Combobox}: type anything, or pick one of `options`.
|
|
237
281
|
* Stores the string.
|
|
238
282
|
*/
|
|
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;
|
|
283
|
+
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
284
|
|
|
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 };
|
|
285
|
+
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 };
|