@andreyfedkovich/cozy-ui 0.9.0 → 0.10.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.
- package/CHANGELOG.md +11 -0
- package/README.md +15 -6
- package/dist-lib/index.d.ts +155 -7
- package/dist-lib/styles.css +1 -1
- package/dist-lib/styles.modules.css +1 -1
- package/dist-lib/ui-library.cjs.js +6 -6
- package/dist-lib/ui-library.cjs.js.map +1 -1
- package/dist-lib/ui-library.es.js +4209 -4027
- package/dist-lib/ui-library.es.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
Формат основан на [Keep a Changelog](https://keepachangelog.com/).
|
|
4
4
|
Версии соответствуют [Semantic Versioning](https://semver.org/) и git-тегам `v*`.
|
|
5
5
|
|
|
6
|
+
## 0.10.0 - 2026-06-04
|
|
7
|
+
|
|
8
|
+
- **feat:** New `ShowErrorPolicy` presets — `draftFriendly`, `wizardStep`, `savedInvalid`, `onBlurOrSubmit`. Recommended for ERP/wizard forms; legacy `default` unchanged (shows on `hasValue` alone).
|
|
9
|
+
- **feat:** Extended `FieldMeta` — `stepSubmitted`, `validationPending`, `errorKind`. `resolveDisplayError` suppresses stale `required` when value is non-empty.
|
|
10
|
+
- **feat:** `useFormFields` + `FieldBinding` — replaces per-app binding glue (~188 LOC in erp-hr). `markStepSubmitted`, `markFormSubmitted`, `resetInteraction`.
|
|
11
|
+
- **feat:** `useValidationRequest` — async validate with generation/stale guard and `validationPending`.
|
|
12
|
+
- **feat:** `attemptWizardStep`, `attemptFormSubmit` — validate-on-click for wizard and submit (no `disabled={!isValid}`).
|
|
13
|
+
- **feat:** `suppressError` prop on field components; dev warning when `error={null}` suppresses invalid `fieldMeta`.
|
|
14
|
+
- **feat:** Export `useFieldPresentation`, `FieldErrorCaption`, `FormField`, `hasFieldValue`.
|
|
15
|
+
- **docs:** `docs/validation-recipes.md` — recipes, anti-patterns, erp-hr migration (Задание B), consumer verification snippet.
|
|
16
|
+
|
|
6
17
|
## 0.9.0 - 2026-06-04
|
|
7
18
|
|
|
8
19
|
- **feat:** Единый контракт валидации полей — headless API: `FieldMeta`, `ShowErrorPolicy`, `resolveShowError`, `resolveFieldError`, `resolveFieldMessage`, `useFieldState`, `resolveValueChangeHandler`.
|
package/README.md
CHANGED
|
@@ -402,14 +402,19 @@ Form state stays in your app (React Hook Form, TanStack Form, or `useState`). Co
|
|
|
402
402
|
|
|
403
403
|
| Export | Description |
|
|
404
404
|
| ------ | ----------- |
|
|
405
|
-
| `FieldMeta` | `touched`, `dirty`, `submitted`, `hasValue`, `invalid`, `errorMessage` |
|
|
406
|
-
| `ShowErrorPolicy` | `"default"` \| `"
|
|
407
|
-
| `resolveShowError`, `resolveFieldError`, `resolveFieldMessage` | Pure functions (SSR-safe) |
|
|
408
|
-
| `useFieldState` | React
|
|
405
|
+
| `FieldMeta` | `touched`, `dirty`, `submitted`, `stepSubmitted`, `hasValue`, `invalid`, `errorMessage`, `validationPending`, `errorKind` |
|
|
406
|
+
| `ShowErrorPolicy` | `"default"` (legacy) \| `"draftFriendly"` \| `"wizardStep"` \| `"onBlur"` \| `"onSubmit"` \| custom |
|
|
407
|
+
| `resolveShowError`, `resolveFieldError`, `resolveFieldMessage`, `resolveDisplayError` | Pure functions (SSR-safe) |
|
|
408
|
+
| `useFieldState`, `useFormFields`, `useValidationRequest` | React hooks |
|
|
409
|
+
| `attemptWizardStep`, `attemptFormSubmit` | Validate-on-click helpers |
|
|
409
410
|
|
|
410
|
-
**
|
|
411
|
+
**Recommended policy for ERP/drafts:** `draftFriendly` — no flash on first keystroke; saved invalid visible on load.
|
|
411
412
|
|
|
412
|
-
**
|
|
413
|
+
**Legacy `default` policy:** `invalid && (touched || submitted || hasValue)`.
|
|
414
|
+
|
|
415
|
+
**Props on fields:** `error`, `suppressError`, `fieldMeta`, `showErrorPolicy`.
|
|
416
|
+
|
|
417
|
+
See [`docs/validation-recipes.md`](docs/validation-recipes.md) for recipes and erp-hr migration.
|
|
413
418
|
|
|
414
419
|
**Callback families:**
|
|
415
420
|
|
|
@@ -1170,8 +1175,12 @@ import {
|
|
|
1170
1175
|
type ShowErrorPolicy,
|
|
1171
1176
|
resolveFieldError,
|
|
1172
1177
|
resolveFieldMessage,
|
|
1178
|
+
resolveDisplayError,
|
|
1173
1179
|
resolveShowError,
|
|
1174
1180
|
useFieldState,
|
|
1181
|
+
useFormFields,
|
|
1182
|
+
useValidationRequest,
|
|
1183
|
+
attemptWizardStep,
|
|
1175
1184
|
} from "@andreyfedkovich/cozy-ui";
|
|
1176
1185
|
```
|
|
1177
1186
|
|
package/dist-lib/index.d.ts
CHANGED
|
@@ -113,6 +113,37 @@ export { ArrowDownIcon }
|
|
|
113
113
|
|
|
114
114
|
export { ArrowRightIcon }
|
|
115
115
|
|
|
116
|
+
/** Validate-on-click for form Submit. */
|
|
117
|
+
export declare function attemptFormSubmit<TValidation>(options: AttemptFormSubmitOptions<TValidation>): Promise<AttemptFormSubmitResult<TValidation>>;
|
|
118
|
+
|
|
119
|
+
export declare type AttemptFormSubmitOptions<TValidation> = {
|
|
120
|
+
markFormSubmitted: () => void;
|
|
121
|
+
validate: () => Promise<TValidation> | TValidation;
|
|
122
|
+
hasErrors: (validation: TValidation) => boolean;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export declare type AttemptFormSubmitResult<TValidation> = {
|
|
126
|
+
ok: boolean;
|
|
127
|
+
validation: TValidation;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Validate-on-click for wizard "Next" — does not require disabled={!isValid}.
|
|
132
|
+
*/
|
|
133
|
+
export declare function attemptWizardStep<TValidation>(options: AttemptWizardStepOptions<TValidation>): Promise<AttemptWizardStepResult<TValidation>>;
|
|
134
|
+
|
|
135
|
+
export declare type AttemptWizardStepOptions<TValidation> = {
|
|
136
|
+
markStepSubmitted: (step: number) => void;
|
|
137
|
+
validate: () => Promise<TValidation> | TValidation;
|
|
138
|
+
step: number;
|
|
139
|
+
hasStepErrors: (validation: TValidation, step: number) => boolean;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export declare type AttemptWizardStepResult<TValidation> = {
|
|
143
|
+
ok: boolean;
|
|
144
|
+
validation: TValidation;
|
|
145
|
+
};
|
|
146
|
+
|
|
116
147
|
export declare const BaseBlock: FC<BaseBlockProps>;
|
|
117
148
|
|
|
118
149
|
declare interface BaseBlockProps {
|
|
@@ -138,7 +169,7 @@ declare type ButtonSize = "small" | "medium" | "large";
|
|
|
138
169
|
|
|
139
170
|
declare type ButtonVariant = "default" | "primary" | "secondary" | "text" | "link" | "danger";
|
|
140
171
|
|
|
141
|
-
export declare const Calendar: ({ label, required, value, onValueChange, onChange, minDate, error, fieldMeta, showErrorPolicy, disabled, onBlur, onFocus, tooltipContent, tooltipPopperClassName, className, }: CalendarProps) => JSX.Element;
|
|
172
|
+
export declare const Calendar: ({ label, required, value, onValueChange, onChange, minDate, error, suppressError, fieldMeta, showErrorPolicy, disabled, onBlur, onFocus, tooltipContent, tooltipPopperClassName, className, }: CalendarProps) => JSX.Element;
|
|
142
173
|
|
|
143
174
|
export declare interface CalendarProps extends ValueFieldCallbacks<string | null>, FieldValidationProps {
|
|
144
175
|
label: string;
|
|
@@ -483,7 +514,7 @@ export declare interface DetailViewProps {
|
|
|
483
514
|
id?: string;
|
|
484
515
|
}
|
|
485
516
|
|
|
486
|
-
export declare const DialogSelect: <T, S extends string | number>({ value, placeholder, loadOptions, onValueChange, onChange, onBlur, onFocus, onClear, columns, label, tooltipContent, tooltipPopperClassName, title, searchPlaceholder, selectButtonText, closeButtonText, manualButtonText, onManualAdd, pageSize, debounceMs, disabled, error, fieldMeta, showErrorPolicy, className, inputClassName, selectedOptionRender, }: DialogSelectProps<T, S>) => JSX.Element;
|
|
517
|
+
export declare const DialogSelect: <T, S extends string | number>({ value, placeholder, loadOptions, onValueChange, onChange, onBlur, onFocus, onClear, columns, label, tooltipContent, tooltipPopperClassName, title, searchPlaceholder, selectButtonText, closeButtonText, manualButtonText, onManualAdd, pageSize, debounceMs, disabled, error, suppressError, fieldMeta, showErrorPolicy, className, inputClassName, selectedOptionRender, }: DialogSelectProps<T, S>) => JSX.Element;
|
|
487
518
|
|
|
488
519
|
export declare type DialogSelectColumn<T, S extends string | number> = {
|
|
489
520
|
key: string;
|
|
@@ -556,26 +587,61 @@ export { EnvelopIcon }
|
|
|
556
587
|
|
|
557
588
|
export { FeedbackIcon }
|
|
558
589
|
|
|
590
|
+
export declare type FieldBinding = {
|
|
591
|
+
fieldMeta: FieldMeta;
|
|
592
|
+
showErrorPolicy?: ShowErrorPolicy;
|
|
593
|
+
onBlur: () => void;
|
|
594
|
+
onDirty?: () => void;
|
|
595
|
+
};
|
|
596
|
+
|
|
559
597
|
declare interface FieldComponentProps extends Omit<DetailField, "value"> {
|
|
560
598
|
value?: ReactNode;
|
|
561
599
|
children?: ReactNode;
|
|
562
600
|
className?: string;
|
|
563
601
|
}
|
|
564
602
|
|
|
603
|
+
export declare function FieldErrorCaption({ id, message }: FieldErrorCaptionProps): ReactNode;
|
|
604
|
+
|
|
605
|
+
declare type FieldErrorCaptionProps = {
|
|
606
|
+
id: string;
|
|
607
|
+
message: string | null;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
export declare type FieldErrorKind = "required" | "semantic" | "custom";
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Headless field state for policy-based error display.
|
|
614
|
+
*
|
|
615
|
+
* - `touched` — user blurred the field
|
|
616
|
+
* - `dirty` — user changed the value in the current session (any change, not only clear)
|
|
617
|
+
* - `submitted` — form-level submit failed (`markFormSubmitted`)
|
|
618
|
+
* - `stepSubmitted` — wizard step "Next" failed (`markStepSubmitted`)
|
|
619
|
+
* - `hasValue` — non-empty value (trimmed string, number, selected option, etc.)
|
|
620
|
+
* - `validationPending` — async validate in flight; optionally suppresses display
|
|
621
|
+
* - `errorKind` — drives `resolveDisplayError` (stale required suppression)
|
|
622
|
+
*/
|
|
565
623
|
export declare type FieldMeta = {
|
|
566
624
|
touched?: boolean;
|
|
567
625
|
dirty?: boolean;
|
|
568
626
|
submitted?: boolean;
|
|
627
|
+
stepSubmitted?: boolean;
|
|
569
628
|
hasValue?: boolean;
|
|
570
629
|
invalid?: boolean;
|
|
571
630
|
errorMessage?: string | null;
|
|
631
|
+
validationPending?: boolean;
|
|
632
|
+
errorKind?: FieldErrorKind;
|
|
572
633
|
};
|
|
573
634
|
|
|
574
635
|
declare const FieldRow: FC<FieldComponentProps>;
|
|
575
636
|
|
|
576
637
|
export declare type FieldValidationProps = {
|
|
577
|
-
/**
|
|
638
|
+
/**
|
|
639
|
+
* Explicit error string overrides `fieldMeta` + policy.
|
|
640
|
+
* Omit to use `fieldMeta`. Do not pass `null` — use {@link suppressError} instead.
|
|
641
|
+
*/
|
|
578
642
|
error?: string | null;
|
|
643
|
+
/** Force-hide any error from `fieldMeta` or explicit `error`. */
|
|
644
|
+
suppressError?: boolean;
|
|
579
645
|
fieldMeta?: FieldMeta;
|
|
580
646
|
showErrorPolicy?: ShowErrorPolicy;
|
|
581
647
|
};
|
|
@@ -588,12 +654,29 @@ export { FilterIcon }
|
|
|
588
654
|
|
|
589
655
|
export { FolderEditIcon }
|
|
590
656
|
|
|
657
|
+
/**
|
|
658
|
+
* Optional wrapper that spreads fieldMeta, showErrorPolicy, and onBlur into a field control.
|
|
659
|
+
*/
|
|
660
|
+
export declare function FormField({ bind, children }: FormFieldProps): ReactNode;
|
|
661
|
+
|
|
662
|
+
export declare type FormFieldProps = {
|
|
663
|
+
bind: FieldBinding;
|
|
664
|
+
label?: ReactNode;
|
|
665
|
+
required?: boolean;
|
|
666
|
+
children: (props: FieldBinding) => ReactNode;
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
export declare type FormFieldsApi<TValidation> = ReturnType<typeof useFormFields<TValidation>>;
|
|
670
|
+
|
|
591
671
|
export { GraduateIcon }
|
|
592
672
|
|
|
593
673
|
export { GridIcon }
|
|
594
674
|
|
|
595
675
|
declare const GroupBlock: FC<SettingsGroup>;
|
|
596
676
|
|
|
677
|
+
/** Whether a field value counts as non-empty for `FieldMeta.hasValue`. */
|
|
678
|
+
export declare function hasFieldValue(value: unknown): boolean;
|
|
679
|
+
|
|
597
680
|
export { HeartIcon }
|
|
598
681
|
|
|
599
682
|
export { HelpIcon }
|
|
@@ -799,6 +882,19 @@ declare interface RadioGroupButtonProps<T extends string | number> {
|
|
|
799
882
|
|
|
800
883
|
export { ReloadIcon }
|
|
801
884
|
|
|
885
|
+
/**
|
|
886
|
+
* Suppresses stale or in-flight errors before display.
|
|
887
|
+
* WHY: API may still return "required" while the value is already non-empty.
|
|
888
|
+
*/
|
|
889
|
+
export declare function resolveDisplayError(options: {
|
|
890
|
+
errorMessage?: string | null;
|
|
891
|
+
errorKind?: FieldErrorKind;
|
|
892
|
+
hasValue?: boolean;
|
|
893
|
+
validationPending?: boolean;
|
|
894
|
+
}): string | null;
|
|
895
|
+
|
|
896
|
+
export declare function resolveDisplayErrorFromMeta(meta: FieldMeta): string | null;
|
|
897
|
+
|
|
802
898
|
export declare function resolveFieldError(meta: FieldMeta | undefined, policy?: ShowErrorPolicy): string | null;
|
|
803
899
|
|
|
804
900
|
/**
|
|
@@ -806,6 +902,7 @@ export declare function resolveFieldError(meta: FieldMeta | undefined, policy?:
|
|
|
806
902
|
*/
|
|
807
903
|
export declare function resolveFieldMessage(options: {
|
|
808
904
|
error?: string | null;
|
|
905
|
+
suppressError?: boolean;
|
|
809
906
|
fieldMeta?: FieldMeta;
|
|
810
907
|
showErrorPolicy?: ShowErrorPolicy;
|
|
811
908
|
}): string | null;
|
|
@@ -830,7 +927,7 @@ declare interface SectionComponentProps extends Omit<DetailSection, "fields"> {
|
|
|
830
927
|
declare interface SectionProps extends SideNavSection {
|
|
831
928
|
}
|
|
832
929
|
|
|
833
|
-
export declare const Select: <T, S extends string | number>({ options, value, mode, placeholder, onValueChange, onChange, onBlur, onFocus, dropdownRender, optionRender, selectedOptionRender, dropdownIcon, tagRender, dropDownClassName, optionClassName, inputClassName, deleteIconClassName, onDelete, onClear, label, tooltipContent, tooltipPopperClassName, onSearch, searchClassName, searchPlaceholder, isLoading, disabled, onClose, portalTarget, error, fieldMeta, showErrorPolicy, template, columns, total, }: CustomSelectProps<T, S>) => JSX.Element;
|
|
930
|
+
export declare const Select: <T, S extends string | number>({ options, value, mode, placeholder, onValueChange, onChange, onBlur, onFocus, dropdownRender, optionRender, selectedOptionRender, dropdownIcon, tagRender, dropDownClassName, optionClassName, inputClassName, deleteIconClassName, onDelete, onClear, label, tooltipContent, tooltipPopperClassName, onSearch, searchClassName, searchPlaceholder, isLoading, disabled, onClose, portalTarget, error, suppressError, fieldMeta, showErrorPolicy, template, columns, total, }: CustomSelectProps<T, S>) => JSX.Element;
|
|
834
931
|
|
|
835
932
|
export declare type SelectColumn<T, S> = {
|
|
836
933
|
key: string;
|
|
@@ -910,7 +1007,7 @@ export declare interface SettingsViewProps {
|
|
|
910
1007
|
id?: string;
|
|
911
1008
|
}
|
|
912
1009
|
|
|
913
|
-
export declare type ShowErrorPolicy = "default" | "onBlur" | "onSubmit" | "always" | ((meta: FieldMeta) => boolean);
|
|
1010
|
+
export declare type ShowErrorPolicy = "default" | "onBlur" | "onSubmit" | "always" | "draftFriendly" | "wizardStep" | "savedInvalid" | "onBlurOrSubmit" | ((meta: FieldMeta) => boolean);
|
|
914
1011
|
|
|
915
1012
|
export declare const SideNav: SideNavComponent;
|
|
916
1013
|
|
|
@@ -1131,7 +1228,7 @@ export declare type TooltipTrigger = "hover" | "click";
|
|
|
1131
1228
|
/** `yyyy-MM-dd` for API / form state */
|
|
1132
1229
|
export declare const toYmdString: (d: Date) => string;
|
|
1133
1230
|
|
|
1134
|
-
export declare const TreeDialogSelect: <T, S extends string | number>({ value, placeholder, loadChildren: loadChildrenProp, loadNodes, searchNodes, onValueChange, onChange, onBlur, onFocus, onClear, label, tooltipContent, tooltipPopperClassName, title, searchPlaceholder, selectButtonText, closeButtonText, confirmButtonText, debounceMs, disabled, error, fieldMeta, showErrorPolicy, className, inputClassName, selectedOptionRender, nodeRender, leafConfirmOnly, }: TreeDialogSelectProps<T, S>) => JSX.Element;
|
|
1231
|
+
export declare const TreeDialogSelect: <T, S extends string | number>({ value, placeholder, loadChildren: loadChildrenProp, loadNodes, searchNodes, onValueChange, onChange, onBlur, onFocus, onClear, label, tooltipContent, tooltipPopperClassName, title, searchPlaceholder, selectButtonText, closeButtonText, confirmButtonText, debounceMs, disabled, error, suppressError, fieldMeta, showErrorPolicy, className, inputClassName, selectedOptionRender, nodeRender, leafConfirmOnly, }: TreeDialogSelectProps<T, S>) => JSX.Element;
|
|
1135
1232
|
|
|
1136
1233
|
/** Pass either {@link loadNodes} or {@link loadChildren} (deprecated alias). */
|
|
1137
1234
|
export declare type TreeDialogSelectProps<T, S extends string | number> = TreeDialogSelectShared<T, S> & ({
|
|
@@ -1209,12 +1306,54 @@ declare interface UseDropdownPositionProps {
|
|
|
1209
1306
|
onAnchorFrame?: (placement: DropdownPosition) => void;
|
|
1210
1307
|
}
|
|
1211
1308
|
|
|
1212
|
-
export declare function
|
|
1309
|
+
export declare function useFieldPresentation(options: UseFieldPresentationOptions): {
|
|
1310
|
+
controlId: string;
|
|
1311
|
+
errorId: string;
|
|
1312
|
+
hintId: string | undefined;
|
|
1313
|
+
errorMessage: string | null;
|
|
1314
|
+
showError: boolean;
|
|
1315
|
+
ariaInvalid: boolean | undefined;
|
|
1316
|
+
ariaDescribedBy: string | undefined;
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
export declare type UseFieldPresentationOptions = {
|
|
1320
|
+
error?: string | null;
|
|
1321
|
+
suppressError?: boolean;
|
|
1322
|
+
fieldMeta?: FieldMeta;
|
|
1323
|
+
showErrorPolicy?: ShowErrorPolicy;
|
|
1324
|
+
/** When set and no error, included in aria-describedby */
|
|
1325
|
+
hintId?: string;
|
|
1326
|
+
idPrefix?: string;
|
|
1327
|
+
};
|
|
1328
|
+
|
|
1329
|
+
export declare function useFieldState(fieldMeta: FieldMeta | undefined, policy?: ShowErrorPolicy, explicitError?: string | null, suppressError?: boolean): {
|
|
1213
1330
|
showError: boolean;
|
|
1214
1331
|
errorMessage: string | null;
|
|
1215
1332
|
showErrorByPolicy: boolean;
|
|
1216
1333
|
};
|
|
1217
1334
|
|
|
1335
|
+
export declare function useFormFields<TValidation>(options?: UseFormFieldsOptions<TValidation>): {
|
|
1336
|
+
bindField: (path: string, value: unknown) => FieldBinding;
|
|
1337
|
+
markFieldTouched: (path: string) => void;
|
|
1338
|
+
markFieldDirty: (path: string) => void;
|
|
1339
|
+
markStepSubmitted: (step: number) => void;
|
|
1340
|
+
markFormSubmitted: () => void;
|
|
1341
|
+
resetInteraction: () => void;
|
|
1342
|
+
formSubmitted: boolean;
|
|
1343
|
+
submittedSteps: Set<number>;
|
|
1344
|
+
showErrorPolicy: ShowErrorPolicy;
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
export declare type UseFormFieldsOptions<TValidation> = {
|
|
1348
|
+
showErrorPolicy?: ShowErrorPolicy;
|
|
1349
|
+
validation?: TValidation;
|
|
1350
|
+
getFieldError?: (validation: TValidation | undefined, path: string) => string | null;
|
|
1351
|
+
getFieldErrorKind?: (validation: TValidation | undefined, path: string) => FieldErrorKind | undefined;
|
|
1352
|
+
/** Maps field path to wizard step index for stepSubmitted. */
|
|
1353
|
+
stepForField?: (path: string) => number | undefined;
|
|
1354
|
+
validationPending?: boolean;
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1218
1357
|
export declare const useMeasureElement: (element?: HTMLElement | null) => {
|
|
1219
1358
|
height: number;
|
|
1220
1359
|
width: number;
|
|
@@ -1222,6 +1361,15 @@ export declare const useMeasureElement: (element?: HTMLElement | null) => {
|
|
|
1222
1361
|
|
|
1223
1362
|
export { UserSwitchIcon }
|
|
1224
1363
|
|
|
1364
|
+
export declare function useValidationRequest<T>(validateFn: () => Promise<T>): {
|
|
1365
|
+
validate: () => Promise<T>;
|
|
1366
|
+
validationPending: boolean;
|
|
1367
|
+
validationGeneration: number;
|
|
1368
|
+
isStale: (generation: number) => boolean;
|
|
1369
|
+
};
|
|
1370
|
+
|
|
1371
|
+
export declare type ValidationRequestApi<T> = ReturnType<typeof useValidationRequest<T>>;
|
|
1372
|
+
|
|
1225
1373
|
/** Picker controls: canonical value callback + deprecated alias. */
|
|
1226
1374
|
export declare type ValueFieldCallbacks<T> = {
|
|
1227
1375
|
onValueChange?: (value: T) => void;
|