react-f0rm 1.3.0 → 1.5.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/README.md +98 -1140
- package/devtools.d.ts +1 -0
- package/devtools.js +1 -0
- package/dist/array-Bu7W8BSz.d.ts +54 -0
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.cjs.js.map +1 -1
- package/dist/devtools/index.d.cts +24 -0
- package/dist/devtools/index.d.mts +24 -0
- package/dist/devtools/index.d.ts +8 -17
- package/dist/devtools/index.mjs +1 -1
- package/dist/devtools/index.mjs.map +1 -1
- package/dist/errors-DA4ReEd9.mjs +2 -0
- package/dist/errors-DA4ReEd9.mjs.map +1 -0
- package/dist/errors-TzyWwBfw.cjs.js +2 -0
- package/dist/errors-TzyWwBfw.cjs.js.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.cts +1253 -0
- package/dist/index.d.mts +1253 -0
- package/dist/index.d.ts +570 -895
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1256 -535
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +2 -2
- package/dist/index.umd.min.js.map +1 -1
- package/dist/persist.cjs.js +1 -1
- package/dist/persist.cjs.js.map +1 -1
- package/dist/persist.d.cts +28 -0
- package/dist/persist.d.mts +28 -0
- package/dist/persist.d.ts +9 -30
- package/dist/persist.mjs +1 -1
- package/dist/persist.mjs.map +1 -1
- package/dist/resolvers/standard-schema.cjs.js +1 -1
- package/dist/resolvers/standard-schema.cjs.js.map +1 -1
- package/dist/resolvers/standard-schema.d.cts +2 -0
- package/dist/resolvers/standard-schema.d.mts +2 -0
- package/dist/resolvers/standard-schema.d.ts +1 -67
- package/dist/resolvers/standard-schema.mjs +1 -1
- package/dist/resolvers/standard-schema.mjs.map +1 -1
- package/dist/resolvers/yup.cjs.js +1 -1
- package/dist/resolvers/yup.cjs.js.map +1 -1
- package/dist/resolvers/yup.d.cts +6 -0
- package/dist/resolvers/yup.d.mts +6 -0
- package/dist/resolvers/yup.d.ts +0 -1
- package/dist/resolvers/yup.mjs +1 -1
- package/dist/resolvers/yup.mjs.map +1 -1
- package/dist/resolvers/zod.cjs.js +1 -1
- package/dist/resolvers/zod.cjs.js.map +1 -1
- package/dist/resolvers/zod.d.cts +34 -0
- package/dist/resolvers/zod.d.mts +34 -0
- package/dist/resolvers/zod.d.ts +30 -3
- package/dist/resolvers/zod.mjs +1 -1
- package/dist/resolvers/zod.mjs.map +1 -1
- package/dist/server/index.cjs.js +1 -1
- package/dist/server/index.cjs.js.map +1 -1
- package/dist/server/index.d.cts +38 -0
- package/dist/server/index.d.mts +38 -0
- package/dist/server/index.d.ts +26 -65
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/standard-schema-BAaTmAHh.d.ts +682 -0
- package/dist/standardSchema-5WezjHlp.mjs +2 -0
- package/dist/standardSchema-5WezjHlp.mjs.map +1 -0
- package/dist/standardSchema-DINHlsYR.cjs.js +2 -0
- package/dist/standardSchema-DINHlsYR.cjs.js.map +1 -0
- package/dist/validate-2pX-N1O6.cjs.js +2 -0
- package/dist/validate-2pX-N1O6.cjs.js.map +1 -0
- package/dist/validate-C0HOsP9v.mjs +2 -0
- package/dist/validate-C0HOsP9v.mjs.map +1 -0
- package/dist/values-BbPnLByD.cjs.js +2 -0
- package/dist/values-BbPnLByD.cjs.js.map +1 -0
- package/dist/values-CHsmcZk4.mjs +2 -0
- package/dist/values-CHsmcZk4.mjs.map +1 -0
- package/package.json +75 -28
- package/persist.d.ts +1 -0
- package/persist.js +1 -0
- package/resolvers/standard-schema.d.ts +1 -0
- package/resolvers/standard-schema.js +1 -0
- package/resolvers/yup.d.ts +1 -0
- package/resolvers/yup.js +1 -0
- package/resolvers/zod.d.ts +1 -0
- package/resolvers/zod.js +1 -0
- package/server.d.ts +1 -0
- package/server.js +1 -0
- package/dist/errors-BKrUdpfI.cjs.js +0 -2
- package/dist/errors-BKrUdpfI.cjs.js.map +0 -1
- package/dist/errors-CrQBddrJ.mjs +0 -2
- package/dist/errors-CrQBddrJ.mjs.map +0 -1
- package/dist/form-CeKSBs31.d.ts +0 -486
- package/dist/validate-CNtuUhmk.mjs +0 -2
- package/dist/validate-CNtuUhmk.mjs.map +0 -1
- package/dist/validate-Cl4ksNFu.cjs.js +0 -2
- package/dist/validate-Cl4ksNFu.cjs.js.map +0 -1
- package/dist/validate-nksgv1pR.d.ts +0 -272
- package/dist/values-Cu6awQOJ.cjs.js +0 -2
- package/dist/values-Cu6awQOJ.cjs.js.map +0 -1
- package/dist/values-DRY-a32G.mjs +0 -2
- package/dist/values-DRY-a32G.mjs.map +0 -1
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1253 @@
|
|
|
1
|
+
import { a as FieldRules, f as FieldError, F as Form$1, P as Path, A as AnyPath, g as PathValueOf, N as Name, h as ValidationMode, R as RegisterOptions, i as RegisterProps, b as FieldErrorEntry, V as Validator, S as StandardSchemaV1, j as FieldPath, k as FieldErrors, l as FieldErrorsTree, O as Options, m as FormEvents } from './standard-schema-BAaTmAHh.js';
|
|
2
|
+
export { e as ArrayItemOf, D as DottedPath, n as FORM_ERROR, o as FormMessages, p as FormValidateFn, q as FormValidateMeta, r as FormValidateMode, s as FormValidationError, I as InferSchemaValues, t as OpaqueTypes, u as PathSegments, v as PathValue, w as ReValidateMode, x as SetErrorOptions, y as SetFocusOptions, z as SetServerErrorsOptions, B as SyncValidator, T as TriggerOptions, c as VALIDATION_OUTCOME, C as ValidateResult, d as ValidationOutcome, E as ValidatorOutput, G as ValidatorRegistration, H as clearErrors, J as clearServerErrors, K as createForm, L as dottedKeyToFieldPath, M as ensureValidate, Q as fieldPathToDottedKey, U as getError, W as getErrorByPath, X as getErrors, Y as getErrorsRecord, Z as getErrorsTree, _ as getFieldErrors, $ as getFieldErrorsByPath, a0 as getFirstError, a1 as hasErrors, a2 as registerFieldValidateDeps, a3 as registerValidatorByPath, a4 as revalidateDependentsOnChange, a5 as revalidateFormOnChange, a6 as runFormValidate, a7 as setError, a8 as setErrorByPath, a9 as setFocus, aa as setServerErrors, ab as setValidatingByPath, ac as shouldKick, ad as trigger, ae as unregisterFieldValidateDeps, af as unsetValidatingByPath, ag as validate } from './standard-schema-BAaTmAHh.js';
|
|
3
|
+
import { EventEmitter } from '@for-fun/event-emitter';
|
|
4
|
+
export { EventEmitter } from '@for-fun/event-emitter';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { Context, Provider, ReactNode } from 'react';
|
|
7
|
+
export { a as appendValue, c as appendValueByPath, i as insertValue, d as insertValueByPath, m as moveValue, e as moveValueByPath, p as prependValue, f as prependValueByPath, r as removeValue, g as removeValueByPath, b as replaceValues, h as replaceValuesByPath, s as swapValues, j as swapValuesByPath, u as updateValue, k as updateValueByPath } from './array-Bu7W8BSz.js';
|
|
8
|
+
|
|
9
|
+
/** Option spellings shared across the field, field-array and validator
|
|
10
|
+
* hooks — private to the hooks slice, never part of the public facade. */
|
|
11
|
+
type FieldOptionBase = {
|
|
12
|
+
/** Declarative rules compiled into a sync validator. */
|
|
13
|
+
rules?: FieldRules;
|
|
14
|
+
/** Whether unmounting removes the branch; defaults to the form-level
|
|
15
|
+
* `shouldUnregister` (tombstone). `false` keeps the values. */
|
|
16
|
+
shouldUnregister?: boolean;
|
|
17
|
+
/** Keep the debounced validator running when the sync gate failed
|
|
18
|
+
* (TanStack `asyncAlways`): gate errors land immediately, the
|
|
19
|
+
* validator's result lands alongside them per-source. */
|
|
20
|
+
asyncAlways?: boolean;
|
|
21
|
+
/** Validate once on mount (overrides the form-level flag in either
|
|
22
|
+
* direction). Deferred while async `initialValues` is pending. */
|
|
23
|
+
validateOnMount?: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Get form values: the values Map layered over parsedValues (when a
|
|
27
|
+
* schema validation produced them) over initialValues. Merged with
|
|
28
|
+
* copy-on-write ownership tracking ({@link setOwned}), so untouched
|
|
29
|
+
* branches share references with the baseline. Memoized per form via a
|
|
30
|
+
* version-bump/read counter ({@link bumpValuesVersion}): consecutive reads
|
|
31
|
+
* hand back the same reference; treat it as read-only. parsedValues never
|
|
32
|
+
* affects dirty state — dirty compares live edits against initialValues. */
|
|
33
|
+
declare function getValues<T extends Record<string, any> = any>(form: Form$1<T>): T;
|
|
34
|
+
/** Get a field's value. */
|
|
35
|
+
declare function getValue<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): PathValueOf<T, P>;
|
|
36
|
+
/** Get a field's value by path. */
|
|
37
|
+
declare function getValueByPath({ initialValues, parsedValues, values, deleted }: Form$1, path: Path): any;
|
|
38
|
+
/** Options accepted by {@link setValue} / {@link setValueByPath} / {@link
|
|
39
|
+
* changeValue} / {@link changeValueByPath}. `shouldValidate`/`shouldTouch`
|
|
40
|
+
* default to `false`. */
|
|
41
|
+
type SetFieldOptions = {
|
|
42
|
+
/** Run the field's registered validator (if any) after the value lands.
|
|
43
|
+
* Defaults to `false`. */
|
|
44
|
+
shouldValidate?: boolean;
|
|
45
|
+
/** Mark the field as touched. Defaults to `false`. */
|
|
46
|
+
shouldTouch?: boolean;
|
|
47
|
+
/** Land the value as a commit instead of an edit: it becomes the field's
|
|
48
|
+
* dirty-comparison baseline. `true` (or omitting) keeps the default
|
|
49
|
+
* derived behavior — dirty while the live value differs from
|
|
50
|
+
* initialValues. */
|
|
51
|
+
shouldDirty?: boolean;
|
|
52
|
+
};
|
|
53
|
+
/** Set a field's value. `value` may be an updater function receiving the
|
|
54
|
+
* current value and returning the next (TanStack Form's `setFieldValue`
|
|
55
|
+
* contract) — so a function can never itself be stored as a value. */
|
|
56
|
+
declare function setValue<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P, value: PathValueOf<T, P> | ((prev: PathValueOf<T, P>) => PathValueOf<T, P>), options?: SetFieldOptions): void;
|
|
57
|
+
/** Set a field's value by path. `value` may be an updater function (see
|
|
58
|
+
* {@link setValue}). */
|
|
59
|
+
declare function setValueByPath(form: Form$1, path: Path, value: any | ((prev: any) => any), options?: SetFieldOptions): void;
|
|
60
|
+
/** The write of {@link setValueByPath} minus the `'change'` emit: the
|
|
61
|
+
* render-time `useField` `initialValue` seed. The field's first paint
|
|
62
|
+
* (SSR included) must already carry the value, so the write happens during
|
|
63
|
+
* render where emitting is illegal; the field announces it post-commit via
|
|
64
|
+
* {@link emitChangeByPath}. */
|
|
65
|
+
declare function seedValueByPath(form: Form$1, path: Path, value: any): void;
|
|
66
|
+
/** Announce a {@link seedValueByPath} that happened during render: the
|
|
67
|
+
* payload-carrying `'change'` emit {@link setValueByPath} would have
|
|
68
|
+
* fired, split out so it runs post-commit where emitting is safe. */
|
|
69
|
+
declare function emitChangeByPath({ emitter }: Form$1, path: Path): void;
|
|
70
|
+
/** One field's aggregated state, as {@link getFieldState} returns it.
|
|
71
|
+
* `errors` is the stored array shared with the form — treat it read-only. */
|
|
72
|
+
type FieldState<T = any> = {
|
|
73
|
+
value: T;
|
|
74
|
+
error: FieldError | undefined;
|
|
75
|
+
errors: FieldError[];
|
|
76
|
+
isDirty: boolean;
|
|
77
|
+
isTouched: boolean;
|
|
78
|
+
isValidating: boolean;
|
|
79
|
+
};
|
|
80
|
+
/** Get one field's aggregated state: layered value, first/every error,
|
|
81
|
+
* dirtiness, touched flag, and validating flag. `isDirty` applies the same
|
|
82
|
+
* per-field rule as {@link getDirtyFields}. */
|
|
83
|
+
declare function getFieldState<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): FieldState<PathValueOf<T, P>>;
|
|
84
|
+
/** Options accepted by {@link removeField}. All flags default to `false` —
|
|
85
|
+
* the historical remove semantics (value dropped, path tombstoned, dirty
|
|
86
|
+
* baseline/touched/errors cleared). */
|
|
87
|
+
type RemoveFieldOptions = {
|
|
88
|
+
/** Keep the field's live value and dirty baseline instead of
|
|
89
|
+
* tombstoning: reads, `getValues()`, and submit keep the value. */
|
|
90
|
+
keepValue?: boolean;
|
|
91
|
+
/** Keep the field's dirty baseline. Implies `keepValue`. */
|
|
92
|
+
keepDirty?: boolean;
|
|
93
|
+
/** Keep the field's touched flag instead of clearing it. */
|
|
94
|
+
keepTouched?: boolean;
|
|
95
|
+
/** Keep the field's errors instead of clearing them. */
|
|
96
|
+
keepError?: boolean;
|
|
97
|
+
};
|
|
98
|
+
declare function removeField(form: Form$1, name: Name, options?: RemoveFieldOptions): void;
|
|
99
|
+
/** Remove a field by path; the keep-flags preserve slices of state. */
|
|
100
|
+
declare function removeFieldByPath(form: Form$1, path: Path, options?: RemoveFieldOptions): void;
|
|
101
|
+
/** Set form initialValues. Content-based early return: a new reference with
|
|
102
|
+
* equal content is a no-op (committed edits survive); genuinely changed
|
|
103
|
+
* content swaps the baseline and re-seeds — live values and tombstones are
|
|
104
|
+
* cleared, touched flags and errors survive. */
|
|
105
|
+
declare function setInitialValues(form: Form$1, initialValues: any): void;
|
|
106
|
+
/** Options accepted by {@link reset}. Every flag defaults to `false`. */
|
|
107
|
+
type ResetOptions = {
|
|
108
|
+
/** Keep the current values of fields that are dirty — differ from the
|
|
109
|
+
* pre-reset initialValues (the same rule {@link getDirtyFields} applies). */
|
|
110
|
+
keepDirtyValues?: boolean;
|
|
111
|
+
/** Keep every field's current live value instead of returning to the
|
|
112
|
+
* baseline (a superset of `keepDirtyValues`). Dirtiness is recomputed
|
|
113
|
+
* against the post-reset baseline. */
|
|
114
|
+
keepValues?: boolean;
|
|
115
|
+
/** Ignore a newly provided `initialValues` and keep the current baseline. */
|
|
116
|
+
keepDefaultValues?: boolean;
|
|
117
|
+
/** Keep the touched set instead of clearing it. */
|
|
118
|
+
keepTouched?: boolean;
|
|
119
|
+
/** Keep field errors instead of clearing them. */
|
|
120
|
+
keepErrors?: boolean;
|
|
121
|
+
/** Keep the submitted flag (`isSubmitted`) instead of clearing it. */
|
|
122
|
+
keepIsSubmitted?: boolean;
|
|
123
|
+
/** Keep the last submit's success flag (`isSubmitSuccessful`). */
|
|
124
|
+
keepIsSubmitSuccessful?: boolean;
|
|
125
|
+
/** Keep `submitCount` instead of resetting it to 0. */
|
|
126
|
+
keepSubmitCount?: boolean;
|
|
127
|
+
/** Keep `isSubmitting` instead of resetting it to false. */
|
|
128
|
+
keepIsSubmitting?: boolean;
|
|
129
|
+
};
|
|
130
|
+
/** Reset the form. Omitted (or undefined) `initialValues` keeps the current
|
|
131
|
+
* baseline — fields simply return to it (react-hook-form's
|
|
132
|
+
* reset-without-values semantics). */
|
|
133
|
+
declare function reset(form: Form$1, initialValues?: any, options?: ResetOptions): void;
|
|
134
|
+
/** Options accepted by {@link resetField}. Flags default to `false`;
|
|
135
|
+
* `value` has no default — omitted, the field falls back to initialValues. */
|
|
136
|
+
type ResetFieldOptions = {
|
|
137
|
+
/** Keep the field's touched flag instead of clearing it. */
|
|
138
|
+
keepTouched?: boolean;
|
|
139
|
+
/** Keep the field's errors instead of clearing them. */
|
|
140
|
+
keepErrors?: boolean;
|
|
141
|
+
/** Explicit post-reset value — never falls back to initialValues. */
|
|
142
|
+
value?: any;
|
|
143
|
+
};
|
|
144
|
+
/** Reset a single field: drop its live value (reads fall back to the
|
|
145
|
+
* baseline), clear touched/errors, and revive the path's tombstones — the
|
|
146
|
+
* inverse of {@link removeFieldByPath}. Other fields are untouched. */
|
|
147
|
+
declare function resetField<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P, options?: ResetFieldOptions): void;
|
|
148
|
+
|
|
149
|
+
/** Set a field's touched state. */
|
|
150
|
+
declare function setTouched(form: Form$1, name: Name): void;
|
|
151
|
+
/** Set a field's touched state by path. */
|
|
152
|
+
declare function setTouchedByPath({ emitter, touched }: Form$1, path: Path): void;
|
|
153
|
+
/** Check if a field has been touched. */
|
|
154
|
+
declare function hasTouched<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): boolean;
|
|
155
|
+
/** Check if a field has been touched by path. */
|
|
156
|
+
declare function hasTouchedByPath({ touched }: Form$1, path: Path): boolean;
|
|
157
|
+
/** Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'). */
|
|
158
|
+
declare function getTouchedFields({ touched }: Form$1): string[];
|
|
159
|
+
/** Is touched — any field has been touched. */
|
|
160
|
+
declare function isTouched({ touched }: Form$1): boolean;
|
|
161
|
+
|
|
162
|
+
/** Is one field dirty — the per-field rule behind `getFieldState`'s
|
|
163
|
+
* `isDirty`: a live value exists at the path and differs from the field's
|
|
164
|
+
* effective baseline (committed `shouldDirty: false` baselines included).
|
|
165
|
+
* A leaf under a wholesale ancestor write reports clean — dirtiness
|
|
166
|
+
* belongs to the branch that actually diverged. */
|
|
167
|
+
declare function isFieldDirtyByPath(form: Form$1, path: Path): boolean;
|
|
168
|
+
/** Is dirty — any value differs from initialValues. */
|
|
169
|
+
declare function isDirty(form: Form$1): boolean;
|
|
170
|
+
/** Get dirty fields — fields whose current value differs from
|
|
171
|
+
* initialValues. Keys are user-facing dotted paths ('a.b', 'a.0.c'); the
|
|
172
|
+
* same reference is returned until the dirty set actually changes. */
|
|
173
|
+
declare function getDirtyFields(form: Form$1): Record<string, boolean>;
|
|
174
|
+
|
|
175
|
+
/** Set a field's value as a user change. When a field is mounted on the
|
|
176
|
+
* path it rides the gated user-change pipeline (the field's effective
|
|
177
|
+
* `mode` and the form's `reValidateMode` drive validation, as in
|
|
178
|
+
* {@link userChangeByPath}); with no mounted field it degrades to a plain
|
|
179
|
+
* {@link setValue}. Contrast {@link setValue}, whose `shouldValidate`
|
|
180
|
+
* kicks the validator unconditionally. */
|
|
181
|
+
declare function changeValue<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P, value: PathValueOf<T, P>, options?: SetFieldOptions): void;
|
|
182
|
+
/** Set a field's value as a user change, by parsed path. */
|
|
183
|
+
declare function changeValueByPath(form: Form$1, path: Path, value: any, options?: SetFieldOptions): void;
|
|
184
|
+
/** Register a mounted field's `mode` override at `path` for user-change
|
|
185
|
+
* gating. Returns the registration token for {@link unregisterFieldMode}
|
|
186
|
+
* plus whether the slot was already occupied — two fields at one path is
|
|
187
|
+
* almost always a bug (the latest mount's mode governs). */
|
|
188
|
+
declare function registerFieldMode(form: Form$1, path: Path, mode: ValidationMode | undefined): {
|
|
189
|
+
token: object;
|
|
190
|
+
displaced: boolean;
|
|
191
|
+
};
|
|
192
|
+
/** Drop a {@link registerFieldMode} registration; only the entry owned by
|
|
193
|
+
* `token` is removed, so a later mount keeps its slot. */
|
|
194
|
+
declare function unregisterFieldMode(form: Form$1, path: Path, token: object): void;
|
|
195
|
+
/** First key in the mounted-field registry that is a strict descendant of
|
|
196
|
+
* `ancestor`, in registration order — undefined when none is mounted.
|
|
197
|
+
* Same descendant rule as `onPathEvent` ('['+','+segment keeps sibling
|
|
198
|
+
* lookalike keys from matching). */
|
|
199
|
+
declare function firstMountedDescendantKey(form: Form$1, ancestor: Path): string | undefined;
|
|
200
|
+
/** Write a bound field's user change by path: the write plus the
|
|
201
|
+
* mode/reValidateMode-gated validation pipeline. Reads the effective mode
|
|
202
|
+
* from the field-mode registry, so a plain write happens when no field is
|
|
203
|
+
* registered at `path`. Framework adapters forward their change events
|
|
204
|
+
* here. */
|
|
205
|
+
declare function userChangeByPath(form: Form$1, path: Path, value: any): void;
|
|
206
|
+
/** A bound field's blur: mark the path touched (unconditional), then kick
|
|
207
|
+
* its validator under the blur-side gate. Framework adapters forward blur
|
|
208
|
+
* events here. */
|
|
209
|
+
declare function userBlur(form: Form$1, path: Path): void;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Create a non-hook field binding — react-hook-form's `register`
|
|
213
|
+
* contract, wired onto this library's store: the bound element never
|
|
214
|
+
* re-renders, every change still lands in the store through the gated
|
|
215
|
+
* user-change pipeline, and `trigger`/submit/`getValues` read it like
|
|
216
|
+
* any other field. `useField({uncontrolled: true})` already covers the
|
|
217
|
+
* hook case; `register` exists for the call sites a hook cannot serve —
|
|
218
|
+
* dynamic lists, conditional fields, non-React adapters — and for RHF
|
|
219
|
+
* migration (`{...register('name')}` spreads unchanged).
|
|
220
|
+
*
|
|
221
|
+
* Lifecycle rides the returned `ref` callback, exactly like React's own
|
|
222
|
+
* ref semantics guarantee attach/detach:
|
|
223
|
+
* - **attach** (element handed over): restore a StrictMode-detached
|
|
224
|
+
* snapshot (React 19 detaches refs on the dev remount), seed the
|
|
225
|
+
* element's initial DOM content into the store when the path has no
|
|
226
|
+
* live value yet (an uncontrolled element's `defaultValue`/`checked`
|
|
227
|
+
* is invisible to React state, so the DOM is the source), register the
|
|
228
|
+
* field-mode entry (the "mounted field" signal routing `changeValue`
|
|
229
|
+
* into the gated pipeline), wire declarative `rules` through
|
|
230
|
+
* `registerValidatorByPath`, and subscribe the `'focusError'` channel
|
|
231
|
+
* (`setFocus`, failed-submit auto-focus) plus the bulk-reset DOM sync
|
|
232
|
+
* (payload-less `'change'` rewrites the element, register-style);
|
|
233
|
+
* - **detach** (`null`): unregister mode entry and validator, drop the
|
|
234
|
+
* subscriptions, and tombstone the path unless
|
|
235
|
+
* `shouldUnregister: false` — the library's historical unmount
|
|
236
|
+
* default, snapshot/restore-safe under StrictMode.
|
|
237
|
+
*
|
|
238
|
+
* Event extraction defaults to the element's own protocol (files →
|
|
239
|
+
* `target.files`, checkbox → `target.checked`, `valueAsNumber`/
|
|
240
|
+
* `valueAsDate` under their flags, else `target.value`), overridable
|
|
241
|
+
* with `eventToValue` — the same extraction `<Field>` performs.
|
|
242
|
+
*
|
|
243
|
+
* @param form
|
|
244
|
+
* @param name path or segment array
|
|
245
|
+
* @param options {@link RegisterOptions}
|
|
246
|
+
* @return spreadable props {@link RegisterProps}
|
|
247
|
+
*/
|
|
248
|
+
declare function registerField(form: Form$1, name: Name, options?: RegisterOptions): RegisterProps;
|
|
249
|
+
|
|
250
|
+
declare function setIsSubmitting(form: Form$1, value: boolean): void;
|
|
251
|
+
declare function incrementSubmitCount(form: Form$1): void;
|
|
252
|
+
declare function setSubmitSuccessful(form: Form$1, value: boolean): void;
|
|
253
|
+
/** Set the form-level disabled flag and emit a payload-less 'disabled'
|
|
254
|
+
* event — subscribed fields re-render with the merged state (form flag ||
|
|
255
|
+
* their own `disabled` option). */
|
|
256
|
+
declare function setDisabled(form: Form$1, value: boolean): void;
|
|
257
|
+
/** Set the form's user-owned metadata slot (Formik's `status` role): the
|
|
258
|
+
* payload-less 'status' event wakes {@link useStatus} and imperative
|
|
259
|
+
* `subscribe` listeners. Nothing else interprets the value. */
|
|
260
|
+
declare function setStatus(form: Form$1, value: any): void;
|
|
261
|
+
/** A submit callback: the submitted values plus the triggering event. */
|
|
262
|
+
type SubmitCallback<T> = (values: T, e?: any) => void | Promise<void>;
|
|
263
|
+
/** Submit callbacks for {@link handleSubmit}. All optional — a missing
|
|
264
|
+
* callback is simply skipped, matching the <Form> component semantics. */
|
|
265
|
+
type HandleSubmitOptions<T extends Record<string, any> = any> = {
|
|
266
|
+
/** Called after validation passes, before onValidSubmit. */
|
|
267
|
+
onSubmit?: SubmitCallback<T>;
|
|
268
|
+
/** Called after validation passes, following a successful onSubmit. */
|
|
269
|
+
onValidSubmit?: SubmitCallback<T>;
|
|
270
|
+
/** Called when validation fails, with the flattened error entries and
|
|
271
|
+
* current values. */
|
|
272
|
+
onInvalidSubmit?: (errors: FieldErrorEntry[], values: T) => void;
|
|
273
|
+
/** Called after validation passes with the final (schema-coerced)
|
|
274
|
+
* values — the slot <Form>'s `action` prop uses to dispatch React 19
|
|
275
|
+
* server actions. May return an {@link ActionErrorResult}: its `errors`
|
|
276
|
+
* record lands as `type: 'server'` errors and the submit counts
|
|
277
|
+
* unsuccessful; any other return means success. */
|
|
278
|
+
onAction?: (values: T, e?: any) => void | Promise<void | ActionErrorResult>;
|
|
279
|
+
/** Focus the first error field after a failed submit. Defaults to true. */
|
|
280
|
+
shouldFocusError?: boolean;
|
|
281
|
+
/** Whether native constraint validation gates this attempt. Defaults to
|
|
282
|
+
* the form's {@link Form.shouldUseNativeValidation} flag. Targets
|
|
283
|
+
* without checkValidity never gate. */
|
|
284
|
+
shouldUseNativeValidation?: boolean;
|
|
285
|
+
};
|
|
286
|
+
/** What a server action / onAction callback returns when the server
|
|
287
|
+
* rejected the payload: a field-path → message(s) record, landed as
|
|
288
|
+
* `type: 'server'` errors. Undefined (or anything else) means success. */
|
|
289
|
+
type ActionErrorResult = {
|
|
290
|
+
errors?: Record<string, string | string[]>;
|
|
291
|
+
};
|
|
292
|
+
/** Create an async submit handler for `form` — the headless counterpart of
|
|
293
|
+
* the <Form> component's onSubmit wiring. Runs the submit state machine
|
|
294
|
+
* around native constraint validation (skipped for targets without
|
|
295
|
+
* checkValidity) and custom validators; failed validation fires
|
|
296
|
+
* onInvalidSubmit, a passing submit runs onSubmit then onValidSubmit.
|
|
297
|
+
* Errors thrown by either are swallowed into isSubmitSuccessful=false.
|
|
298
|
+
* A new attempt while one is in flight is ignored outright (no state
|
|
299
|
+
* changes at all) — including handleSubmit calls nested inside onSubmit. */
|
|
300
|
+
declare function handleSubmit<T extends Record<string, any> = any>(form: Form$1<T>, options?: HandleSubmitOptions<T>): (e?: {
|
|
301
|
+
preventDefault?: () => void;
|
|
302
|
+
currentTarget?: any;
|
|
303
|
+
}) => Promise<void>;
|
|
304
|
+
|
|
305
|
+
type UseFieldOptions$1<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = {
|
|
306
|
+
form?: Form$1<TValues>;
|
|
307
|
+
name: TPath;
|
|
308
|
+
initialValue?: any;
|
|
309
|
+
shouldUnregister?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Field-level validator. The value argument follows the path: with a
|
|
312
|
+
* typed form the callback receives `PathValueOf<TValues, TPath>` (the
|
|
313
|
+
* TanStack-parity inference — `name: 'age'` on a `{age: number}` shape
|
|
314
|
+
* types `value` as `number`), and falls back to `any` for untyped call
|
|
315
|
+
* sites (segment arrays, dynamic names). The return shape mirrors
|
|
316
|
+
* {@link Validator} — an error (string / FieldError / mixed array) or
|
|
317
|
+
* undefined when valid, possibly a Promise for async validation. The
|
|
318
|
+
* second argument carries the validation context (`meta.signal` aborts
|
|
319
|
+
* when the round is superseded).
|
|
320
|
+
*/
|
|
321
|
+
validate?: ((value: PathValueOf<TValues, TPath>, meta: {
|
|
322
|
+
form: Form$1<TValues>;
|
|
323
|
+
path: Path;
|
|
324
|
+
signal: AbortSignal;
|
|
325
|
+
}) => ReturnType<Validator>) | StandardSchemaV1<PathValueOf<TValues, TPath>>;
|
|
326
|
+
/**
|
|
327
|
+
* Declarative rules (required/min/max/minLength/maxLength/pattern),
|
|
328
|
+
* compiled into a synchronous validator. `required` is special: it runs
|
|
329
|
+
* immediately on every kick — never debounced — and while it fails,
|
|
330
|
+
* `validate` is skipped (the expensive check never sees an empty value).
|
|
331
|
+
* The other rules compose with `validate` — rules run first, then
|
|
332
|
+
* `validate` (awaited when async), merging both sources' errors with
|
|
333
|
+
* rules errors ahead. Failures land in the form's error state with the
|
|
334
|
+
* given or default messages.
|
|
335
|
+
*/
|
|
336
|
+
rules?: FieldRules;
|
|
337
|
+
/**
|
|
338
|
+
* Milliseconds to debounce this field's validation kicks. Defaults to 0
|
|
339
|
+
* (validate immediately); while the timer is pending the field counts as
|
|
340
|
+
* validating, so `trigger`/`ensureValidate` wait out the window. Only the
|
|
341
|
+
* last kick inside the window runs the validator. The `required` rule is
|
|
342
|
+
* exempt: it runs synchronously on every kick, so a required failure
|
|
343
|
+
* shows immediately instead of waiting out the window.
|
|
344
|
+
*/
|
|
345
|
+
validateDebounce?: number;
|
|
346
|
+
/**
|
|
347
|
+
* Run this field's debounced validator even when its `required` gate
|
|
348
|
+
* failed — TanStack Form's `asyncAlways`. The gate's errors land
|
|
349
|
+
* immediately (never debounced) and the validator's own result lands
|
|
350
|
+
* alongside them, per-source: a passing async round clears only its
|
|
351
|
+
* own errors while the gate's verdict stays. Falls back to the
|
|
352
|
+
* form-level `createForm({asyncAlways})` flag when omitted, so a field
|
|
353
|
+
* opts out with `asyncAlways: false`. The use case: the cheap format
|
|
354
|
+
* check fails (gate) but the expensive backend check should still run
|
|
355
|
+
* ("not in the right shape — and the backend says taken, too").
|
|
356
|
+
*/
|
|
357
|
+
asyncAlways?: boolean;
|
|
358
|
+
/**
|
|
359
|
+
* Milliseconds to delay showing a newly appearing error in the render
|
|
360
|
+
* layer (`error`/`errorObject`/`errors` stay undefined/empty until the
|
|
361
|
+
* window passes). The form's error state is never delayed — trigger,
|
|
362
|
+
* submit and `getError` read it immediately. An error that clears inside
|
|
363
|
+
* the window never shows; once an error is visible, later changes apply
|
|
364
|
+
* immediately. Only the none → some transition waits.
|
|
365
|
+
*/
|
|
366
|
+
delayError?: number;
|
|
367
|
+
/**
|
|
368
|
+
* Disable this field: merged into the result's `disabled` as
|
|
369
|
+
* `form.disabled || own === true || (own !== false && an ancestor
|
|
370
|
+
* declared disabled)`. `disabled: true` on a parent path disables every
|
|
371
|
+
* descendant field too (react-hook-form subtree semantics), and a
|
|
372
|
+
* descendant declares `disabled: false` to opt back out of that
|
|
373
|
+
* ancestor. The form-level flag (`createForm({disabled})` /
|
|
374
|
+
* `setDisabled`) cannot be opted out of.
|
|
375
|
+
*/
|
|
376
|
+
disabled?: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Uncontrolled mode: the field never subscribes to its own value, so
|
|
379
|
+
* typing re-renders nothing — the store still carries every write
|
|
380
|
+
* (getValues/submit/validation read it), and errors/touched/disabled/
|
|
381
|
+
* validating still re-render the field like react-hook-form's
|
|
382
|
+
* `register`. The result's `value` is the mount-time snapshot (initial
|
|
383
|
+
* value seed or baseline); it never refreshes, and bulk operations
|
|
384
|
+
* (reset/setInitialValues) sync the DOM element directly through the
|
|
385
|
+
* `focusRef`-held element instead of a render — the register-style
|
|
386
|
+
* contract, RHF's reset clears the input the same way. Attach the
|
|
387
|
+
* result with `<input defaultValue={field.value} ref={field.focusRef}>`
|
|
388
|
+
* -style binding (no `value` prop), exactly like <Field uncontrolled />
|
|
389
|
+
* does. The DOM sync writes the raw stored value (file inputs are
|
|
390
|
+
* skipped); read live values with useValue/getValues.
|
|
391
|
+
*/
|
|
392
|
+
uncontrolled?: boolean;
|
|
393
|
+
/**
|
|
394
|
+
* Field-level validation mode override: when given, this field validates
|
|
395
|
+
* on its own schedule instead of `form.mode` — every other field keeps
|
|
396
|
+
* the form-level timing (e.g. a form that defaults to `'onSubmit'` with
|
|
397
|
+
* one field declared `'onBlur'` shows that field's error on blur while
|
|
398
|
+
* the rest wait for submit). `reValidateMode` stays form-level: once any
|
|
399
|
+
* field has an error (after a failed submit, say), re-validation follows
|
|
400
|
+
* the form's `reValidateMode` for every field, overriding this one too.
|
|
401
|
+
* See {@link ValidationMode}.
|
|
402
|
+
*/
|
|
403
|
+
mode?: ValidationMode;
|
|
404
|
+
/**
|
|
405
|
+
* Field paths whose **user changes re-run this field's validator** —
|
|
406
|
+
* the field-level counterpart of the form-level `validateDeps` option
|
|
407
|
+
* (cross-field linkage: `password` changed → re-check
|
|
408
|
+
* `passwordConfirm`). TanStack Form's `onChangeListenTo` / RHF trigger
|
|
409
|
+
* chains are the ecosystem analogues.
|
|
410
|
+
*
|
|
411
|
+
* The re-run rides the changed field's own onChange pipeline, so typing
|
|
412
|
+
* and `changeValue` both fire it while programmatic `setValue` does
|
|
413
|
+
* not, and its timing is gated by the same mode matrix as the form
|
|
414
|
+
* level: the changed field's effective `mode` (per-field override
|
|
415
|
+
* included) and the form's `reValidateMode` — under the default
|
|
416
|
+
* `'onSubmit'`/`'onChange'` pair, a dep change re-validates this field
|
|
417
|
+
* once this field already shows an error (the submit-then-fix flow: the
|
|
418
|
+
* mismatch lands on submit, editing the password re-checks the confirm
|
|
419
|
+
* and a passing round clears the error, because a field validator owns
|
|
420
|
+
* its whole key).
|
|
421
|
+
*
|
|
422
|
+
* `validateDebounce` applies to the re-run like to any kick. Declaring
|
|
423
|
+
* the field's own path is a no-op (its own change already validates it).
|
|
424
|
+
*/
|
|
425
|
+
validateDeps?: FieldPath<TValues>[];
|
|
426
|
+
/**
|
|
427
|
+
* Validate this field once on mount instead of waiting for the first
|
|
428
|
+
* submit/change — errors show immediately for an untouched field.
|
|
429
|
+
* Overrides the form-level `createForm({validateOnMount})` flag in
|
|
430
|
+
* either direction (`false` opts a field out of a validating form).
|
|
431
|
+
* While an async `initialValues` source is still pending the kick waits
|
|
432
|
+
* for the resolved baseline; a field unmounted in between never kicks.
|
|
433
|
+
*/
|
|
434
|
+
validateOnMount?: boolean;
|
|
435
|
+
/**
|
|
436
|
+
* DOM event → value extractor for the result's {@link
|
|
437
|
+
* UseFieldResult.inputProps} binding. Defaults to the element's own
|
|
438
|
+
* protocol (files → `target.files`, checkbox → `target.checked`,
|
|
439
|
+
* `valueAsNumber`/`valueAsDate` under their flags, else
|
|
440
|
+
* `target.value`); a non-DOM event passes through unchanged, so custom
|
|
441
|
+
* controls can hand raw values. Only consumed by `inputProps` — the
|
|
442
|
+
* headless `onChange` keeps taking raw values.
|
|
443
|
+
*/
|
|
444
|
+
eventToValue?: (e: any) => any;
|
|
445
|
+
/** `inputProps` stores `e.target.valueAsNumber` instead of the string
|
|
446
|
+
* value (number inputs, RHF's `register({valueAsNumber})`). An
|
|
447
|
+
* explicit `eventToValue` takes precedence. */
|
|
448
|
+
valueAsNumber?: boolean;
|
|
449
|
+
/** `inputProps` stores `e.target.valueAsDate` instead of the string
|
|
450
|
+
* value (date/time inputs, RHF's `register({valueAsDate})`). An
|
|
451
|
+
* explicit `eventToValue` takes precedence; combining with
|
|
452
|
+
* `valueAsNumber` is a TypeError (`valueAsNumber` wins). */
|
|
453
|
+
valueAsDate?: boolean;
|
|
454
|
+
/**
|
|
455
|
+
* Element type hint for {@link UseFieldResult.inputProps} only:
|
|
456
|
+
* `'checkbox'` renders `checked` instead of `value`, `'file'` renders
|
|
457
|
+
* neither (file inputs cannot be value-controlled). The extraction
|
|
458
|
+
* itself already auto-detects both types from the event's target.
|
|
459
|
+
*/
|
|
460
|
+
type?: string;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* The result of {@link useField}. Deliberately a closed shape: no index
|
|
464
|
+
* signature, so a typo'd property access (`field.vlaue`) is a type error
|
|
465
|
+
* instead of silently reading `undefined`.
|
|
466
|
+
*/
|
|
467
|
+
type UseFieldResult<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = {
|
|
468
|
+
/** The form instance this field is bound to (explicit prop or context) —
|
|
469
|
+
* handy for consumers that need direct access to the headless API. */
|
|
470
|
+
form: Form$1<TValues>;
|
|
471
|
+
value: PathValueOf<TValues, TPath>;
|
|
472
|
+
/** Error message string (FieldError#message) for display, or undefined */
|
|
473
|
+
error: string | undefined;
|
|
474
|
+
/** Full FieldError object ({type, message}), or undefined */
|
|
475
|
+
errorObject: FieldError | undefined;
|
|
476
|
+
/** Every error registered for the field, in insertion order — `error`
|
|
477
|
+
* and `errorObject` are its first entry. Empty (and reference-stable)
|
|
478
|
+
* when the field has no errors. */
|
|
479
|
+
errors: FieldError[];
|
|
480
|
+
/**
|
|
481
|
+
* Whether the field is dirty: its live value exists and differs from
|
|
482
|
+
* the field's effective baseline (the same per-field rule
|
|
483
|
+
* `getFieldState(form, name).isDirty` applies — committed
|
|
484
|
+
* `shouldDirty: false` baselines included). Live in controlled mode;
|
|
485
|
+
* pinned at mount in uncontrolled mode (like `value`) so typing never
|
|
486
|
+
* re-renders the field — {@link useIsFieldDirty} is the live scoped
|
|
487
|
+
* channel for either mode.
|
|
488
|
+
*/
|
|
489
|
+
isDirty: boolean;
|
|
490
|
+
/**
|
|
491
|
+
* Whether a validator round for this field is currently in flight —
|
|
492
|
+
* a pending debounce window or an unresolved async validator (the
|
|
493
|
+
* `getFieldState(form, name).isValidating` reading, made reactive).
|
|
494
|
+
*/
|
|
495
|
+
validating: boolean;
|
|
496
|
+
onChange: (v: any) => void;
|
|
497
|
+
onBlur: () => void;
|
|
498
|
+
name: string;
|
|
499
|
+
/** Merged disabled flag: the form-level flag (`createForm({disabled})`
|
|
500
|
+
* toggled by `setDisabled`) OR-ed with this field's own `disabled`
|
|
501
|
+
* option, updated live through the form's event core. */
|
|
502
|
+
disabled: boolean;
|
|
503
|
+
/**
|
|
504
|
+
* Callback ref carrying the focus channel: attach it to your input
|
|
505
|
+
* element (`<input ref={field.focusRef} />`) so `setFocus` and a failed
|
|
506
|
+
* submit's first-error auto-focus (`shouldFocusError`) can focus this
|
|
507
|
+
* headless field — the same 'focusError' wiring `<Field>` performs for
|
|
508
|
+
* its own input. Without it, focus requests aimed at this field are
|
|
509
|
+
* silent no-ops, matching `setFocus`'s contract: focusing a field
|
|
510
|
+
* whose element is not bound neither throws nor focuses anything.
|
|
511
|
+
*/
|
|
512
|
+
focusRef: (el: any) => void;
|
|
513
|
+
/**
|
|
514
|
+
* DOM-ready props for an `<input>`: `<input {...field.inputProps} />`
|
|
515
|
+
* binds the element to the field without hand-wiring value/onChange/
|
|
516
|
+
* onBlur/ref/a11y. `onChange` takes the DOM event (extraction per
|
|
517
|
+
* {@link UseFieldOptions}' `eventToValue`/`valueAsNumber`/`valueAsDate`
|
|
518
|
+
* /`type`), `ref` is the focus channel, `aria-invalid`/`aria-describedby`
|
|
519
|
+
* complete the {@link errorIdFromKey} chain — render the error element
|
|
520
|
+
* with `fieldErrorId(name)` to finish it. The headless `value`/
|
|
521
|
+
* `onChange`/`onBlur`/`focusRef` stay available for custom controls
|
|
522
|
+
* that hand raw values (design systems) — `inputProps` is the DOM
|
|
523
|
+
* boundary adapter, never a replacement.
|
|
524
|
+
*/
|
|
525
|
+
inputProps: UseFieldInputProps;
|
|
526
|
+
};
|
|
527
|
+
/**
|
|
528
|
+
* The spreadable DOM props {@link UseFieldResult.inputProps} carries:
|
|
529
|
+
* `name`, `onChange` (event-based), `onBlur`, `ref`, `disabled`, the
|
|
530
|
+
* error a11y wiring, and exactly one of `value` (controlled),
|
|
531
|
+
* `defaultValue` (uncontrolled) or `checked` (`type: 'checkbox'`) —
|
|
532
|
+
* `type: 'file'` carries none. Always spread `inputProps` FIRST, so the
|
|
533
|
+
* caller's own props (placeholder, className, an explicit `ref` they
|
|
534
|
+
* merge themselves) win.
|
|
535
|
+
*/
|
|
536
|
+
type UseFieldInputProps = {
|
|
537
|
+
name: string;
|
|
538
|
+
value?: any;
|
|
539
|
+
defaultValue?: any;
|
|
540
|
+
checked?: boolean;
|
|
541
|
+
onChange: (e: any) => void;
|
|
542
|
+
onBlur: () => void;
|
|
543
|
+
ref: (el: any) => void;
|
|
544
|
+
disabled: boolean;
|
|
545
|
+
'aria-invalid'?: boolean;
|
|
546
|
+
'aria-describedby'?: string;
|
|
547
|
+
};
|
|
548
|
+
declare function useField<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(options: UseFieldOptions$1<TValues, TPath>): UseFieldResult<TValues, TPath>;
|
|
549
|
+
|
|
550
|
+
type FieldArrayItem<K extends string> = {
|
|
551
|
+
id: string;
|
|
552
|
+
index: number;
|
|
553
|
+
} & Record<K, string>;
|
|
554
|
+
/** Options accepted by {@link useFieldArray} and the per-instance hook
|
|
555
|
+
* returned by `createFormContext()`. */
|
|
556
|
+
type UseFieldArrayOptions<K extends string = 'id'> = Pick<FieldOptionBase, 'rules' | 'shouldUnregister'> & {
|
|
557
|
+
name: Name;
|
|
558
|
+
form?: Form$1;
|
|
559
|
+
/**
|
|
560
|
+
* Property name the stable row key is exposed under on each `fields`
|
|
561
|
+
* entry (react-hook-form's `keyName`): defaults to `'id'`, a custom
|
|
562
|
+
* name (e.g. `'key'`) avoids clashing with a row data field of the
|
|
563
|
+
* same name. The underlying id is unchanged.
|
|
564
|
+
*/
|
|
565
|
+
keyName?: K;
|
|
566
|
+
};
|
|
567
|
+
/** Second argument of the row-adding movers: `focus` decides whether the
|
|
568
|
+
* new row takes focus once it commits — `true` targets its first mounted
|
|
569
|
+
* child field, a string names the child field. */
|
|
570
|
+
type FieldArrayFocusOptions = {
|
|
571
|
+
focus?: boolean | string;
|
|
572
|
+
};
|
|
573
|
+
type UseFieldArrayResult<TItem = any, K extends string = 'id'> = {
|
|
574
|
+
fields: FieldArrayItem<K>[];
|
|
575
|
+
/** Append one row. With the item type declared —
|
|
576
|
+
* `useFieldArray<Item>({name: 'items'})` — the value is checked
|
|
577
|
+
* against the array's element type. */
|
|
578
|
+
append: (value: TItem, options?: FieldArrayFocusOptions) => void;
|
|
579
|
+
prepend: (value: TItem, options?: FieldArrayFocusOptions) => void;
|
|
580
|
+
insert: (index: number, value: TItem, options?: FieldArrayFocusOptions) => void;
|
|
581
|
+
/** Remove one row, or several in a single write (`remove([0, 2])` —
|
|
582
|
+
* order-insensitive, duplicates ignored, out-of-range indices are
|
|
583
|
+
* silent no-ops). */
|
|
584
|
+
remove: (indices: number | number[]) => void;
|
|
585
|
+
swap: (from: number, to: number) => void;
|
|
586
|
+
move: (from: number, to: number) => void;
|
|
587
|
+
replace: (values: TItem[]) => void;
|
|
588
|
+
update: (index: number, value: TItem) => void;
|
|
589
|
+
};
|
|
590
|
+
declare function useFieldArray<TItem = any, K extends string = 'id'>(options: UseFieldArrayOptions<K>): UseFieldArrayResult<TItem, K>;
|
|
591
|
+
/**
|
|
592
|
+
* The result of {@link useFieldArrayItem}. Mirrors the {@link useField}
|
|
593
|
+
* return shape (`value`/`errors`/`error`) plus the row's `index` and
|
|
594
|
+
* `name` (path key) so nested fields can build on it —
|
|
595
|
+
* `useField({name: ['tags', item.index, 'label']})`.
|
|
596
|
+
*/
|
|
597
|
+
type UseFieldArrayItemResult<TValue = any> = {
|
|
598
|
+
value: TValue;
|
|
599
|
+
/** Overwrite this row's value in place (same array-layer write as
|
|
600
|
+
* `update(index, value)`: the row's id and position are kept). */
|
|
601
|
+
setValue: (value: TValue) => void;
|
|
602
|
+
/** Every error registered for the row's path, insertion order; the
|
|
603
|
+
* shared empty constant while clean, so consumers can memo on it. */
|
|
604
|
+
errors: FieldError[];
|
|
605
|
+
/** First error's message — the display text — or undefined. */
|
|
606
|
+
error: string | undefined;
|
|
607
|
+
/** The row's current path key (JSON-stringified segments, e.g.
|
|
608
|
+
* `["tags",0]`); moves with the row across reorder/remove. */
|
|
609
|
+
name: string;
|
|
610
|
+
/** The row's current position in the array. `-1` while the row is being
|
|
611
|
+
* removed (or when no useFieldArray is mounted at `name`): reads return
|
|
612
|
+
* undefined and nothing writes the dangling path. */
|
|
613
|
+
index: number;
|
|
614
|
+
form: Form$1;
|
|
615
|
+
};
|
|
616
|
+
/** Options for {@link useFieldArrayItem} and its per-instance core: the
|
|
617
|
+
* array's `name`, the row's stable `id` (from `fields[i].id`), and an
|
|
618
|
+
* optional explicit `form`. */
|
|
619
|
+
type UseFieldArrayItemOptions = {
|
|
620
|
+
name: Name;
|
|
621
|
+
id: string;
|
|
622
|
+
form?: Form$1;
|
|
623
|
+
};
|
|
624
|
+
/**
|
|
625
|
+
* Subscribe to a single row of a {@link useFieldArray} field — the
|
|
626
|
+
* per-item counterpart `useFieldArray` alone cannot offer. `useFieldArray`
|
|
627
|
+
* subscribes to the whole branch, so any row's edit re-renders the
|
|
628
|
+
* component holding the array (and, without memoization, every row);
|
|
629
|
+
* `useFieldArrayItem` scopes what re-renders to one row identified by its
|
|
630
|
+
* stable id: editing row K re-renders only row K's component, and a
|
|
631
|
+
* whole-array rewrite re-renders only rows whose value reference actually
|
|
632
|
+
* changed. Pair it with a `React.memo` row component that takes stable
|
|
633
|
+
* props (`form`, `id`) so the array component's own re-render cannot drag
|
|
634
|
+
* the rows along.
|
|
635
|
+
*
|
|
636
|
+
* Rows whose index migrates — remove/move/swap/insert reshuffles —
|
|
637
|
+
* re-render by design: the row's path contains the index, exactly like
|
|
638
|
+
* TanStack Form's per-field api. The win is single-row edits staying
|
|
639
|
+
* single-row.
|
|
640
|
+
*
|
|
641
|
+
* Value reads and writes live on the array layer — the same layer every
|
|
642
|
+
* `useFieldArray` operation touches — so `value`, `setValue` and
|
|
643
|
+
* `update`/`append`/… always agree with each other.
|
|
644
|
+
*
|
|
645
|
+
* @param options `name` of the array (a useFieldArray must be mounted at
|
|
646
|
+
* the same path — it publishes the id table), the row's `id` from
|
|
647
|
+
* `fields[i].id`, and optionally an explicit `form`
|
|
648
|
+
*/
|
|
649
|
+
declare function useFieldArrayItem<TValue = any>(options: UseFieldArrayItemOptions): UseFieldArrayItemResult<TValue>;
|
|
650
|
+
|
|
651
|
+
declare const FormContext: Context<Form$1<any> | null>;
|
|
652
|
+
declare const FormProvider: Provider<Form$1<any> | null>;
|
|
653
|
+
/**
|
|
654
|
+
* Read the form from the module-level {@link FormContext}; pass the values
|
|
655
|
+
* shape (`useFormContext<Values>()`) for a typed `Form<Values>`. Use
|
|
656
|
+
* {@link createFormContext} for multiple forms in one subtree.
|
|
657
|
+
* @throws when no `<FormProvider>` is mounted above the call site.
|
|
658
|
+
*/
|
|
659
|
+
declare function useFormContext<T extends Record<string, any> = any>(): Form$1<T>;
|
|
660
|
+
/** Options the bundle's pre-bound hooks take: the underlying hook's
|
|
661
|
+
* options minus `form` — this factory's own context supplies it. For
|
|
662
|
+
* `useField`, `{name: TPath}` keeps `name` a direct TPath inference site. */
|
|
663
|
+
type BoundFieldOptions<TValues extends Record<string, any>, TPath extends AnyPath<TValues>> = {
|
|
664
|
+
name: TPath;
|
|
665
|
+
} & Omit<UseFieldOptions$1<TValues, TPath>, 'form'>;
|
|
666
|
+
type BoundFieldArrayOptions<TValues extends Record<string, any>, K extends string = 'id'> = {
|
|
667
|
+
name: FieldPath<TValues> | Name;
|
|
668
|
+
keyName?: K;
|
|
669
|
+
rules?: FieldRules;
|
|
670
|
+
shouldUnregister?: boolean;
|
|
671
|
+
};
|
|
672
|
+
type BoundFieldArrayItemOptions<TValues extends Record<string, any>> = {
|
|
673
|
+
name: FieldPath<TValues> | Name;
|
|
674
|
+
id: string;
|
|
675
|
+
};
|
|
676
|
+
/** The bundle {@link createFormContext} returns: a private React context
|
|
677
|
+
* plus the hooks pre-bound to it, all typed against `TValues`. */
|
|
678
|
+
type FormContextBundle<TValues extends Record<string, any> = any> = {
|
|
679
|
+
/** The raw React context, for `<Form context={...}>`: the component
|
|
680
|
+
* keeps its submit machinery while providing into this instance's
|
|
681
|
+
* private context. */
|
|
682
|
+
context: Context<Form$1<TValues> | null>;
|
|
683
|
+
FormProvider: (props: {
|
|
684
|
+
form: Form$1<TValues>;
|
|
685
|
+
children: ReactNode;
|
|
686
|
+
}) => ReactNode;
|
|
687
|
+
useFormContext: () => Form$1<TValues>;
|
|
688
|
+
useField: <TPath extends AnyPath<TValues> = AnyPath<TValues>>(options: BoundFieldOptions<TValues, TPath>) => UseFieldResult<TValues, TPath>;
|
|
689
|
+
useFieldArray: <TItem = any, K extends string = 'id'>(options: BoundFieldArrayOptions<TValues, K>) => UseFieldArrayResult<TItem, K>;
|
|
690
|
+
useFieldArrayItem: <TValue = any>(options: BoundFieldArrayItemOptions<TValues>) => UseFieldArrayItemResult<TValue>;
|
|
691
|
+
};
|
|
692
|
+
/**
|
|
693
|
+
* Create an isolated bundle of form-context bindings: its own React context
|
|
694
|
+
* plus `useField`/`useFieldArray`/`useFieldArrayItem`/`useFormContext`
|
|
695
|
+
* hooks resolving from it. One factory per app area scopes a separate
|
|
696
|
+
* form and fixes the value shape (`Ctx.useField` gets typed `name`/`value`);
|
|
697
|
+
* `Ctx.context` lets `<Form context={Ctx.context}>` provide into it.
|
|
698
|
+
*/
|
|
699
|
+
declare function createFormContext<TValues extends Record<string, any> = any>(): FormContextBundle<TValues>;
|
|
700
|
+
declare const CheckboxGroupContext: Context<any>;
|
|
701
|
+
declare const CheckboxGroupProvider: Provider<any>;
|
|
702
|
+
declare function useCheckboxGroupContext(): any;
|
|
703
|
+
|
|
704
|
+
/** Subscription granularity for {@link onPathEvent}: `'leaf'` reads one
|
|
705
|
+
* key (only writes at it or above matter); `'branch'` aggregates a whole
|
|
706
|
+
* subtree (descendant writes matter too). */
|
|
707
|
+
type WatchScope = 'leaf' | 'branch';
|
|
708
|
+
/** Events {@link subscribe} can watch. `'errors'`/`'touched'` match exact
|
|
709
|
+
* keys ({@link onKeyEvent}); `'change'`/`'validating'` match by path
|
|
710
|
+
* ({@link onPathEvent}); the rest are payload-less broadcasts every
|
|
711
|
+
* subscriber hears. */
|
|
712
|
+
type SubscribeEvent = 'change' | 'errors' | 'touched' | 'validating' | 'submitting' | 'submitCount' | 'submitSuccessful' | 'disabled' | 'status' | 'loading';
|
|
713
|
+
type SubscribeOptions = {
|
|
714
|
+
/** Path or paths to watch; omit to receive every emission. A segments
|
|
715
|
+
* path vs a name list is told apart by `trigger`'s rule: only segments
|
|
716
|
+
* hold a number. */
|
|
717
|
+
name?: Name | Name[];
|
|
718
|
+
/** Event to watch. Defaults to `'change'`. */
|
|
719
|
+
event?: SubscribeEvent;
|
|
720
|
+
/** Which writes around `name` are relevant. Only meaningful for the
|
|
721
|
+
* path-carrying events; defaults to `'branch'` (subscribing to `'tags'`
|
|
722
|
+
* means the whole branch). */
|
|
723
|
+
scope?: WatchScope;
|
|
724
|
+
/** Invoked after each matching emission; read fresh state through the
|
|
725
|
+
* `get*` readers inside it. */
|
|
726
|
+
callback: () => void;
|
|
727
|
+
};
|
|
728
|
+
/**
|
|
729
|
+
* Subscribe to form events imperatively — the non-render counterpart of
|
|
730
|
+
* the `use*` hooks. Without `name`, `callback` fires on every emission;
|
|
731
|
+
* with `name`, matching follows the event's shape (`'errors'`/`'touched'`
|
|
732
|
+
* match exact keys, the rest match by path or broadcast). A name array
|
|
733
|
+
* builds one subscription per path.
|
|
734
|
+
*/
|
|
735
|
+
declare function subscribe(form: Form$1, options: SubscribeOptions): () => void;
|
|
736
|
+
/** The handle {@link watch} returns: a subscribe/getSnapshot pair any
|
|
737
|
+
* reactive runtime can bind to. One internal listener stays alive from
|
|
738
|
+
* creation, so `getSnapshot()` is always fresh; `dispose` ends it. */
|
|
739
|
+
type WatchHandle<T> = {
|
|
740
|
+
/** Read the current snapshot, cached between events; repeated reads
|
|
741
|
+
* share one reference until state changes. */
|
|
742
|
+
getSnapshot: () => T;
|
|
743
|
+
/** Register a change listener; fires only when the projection changed.
|
|
744
|
+
* With `isEqual`, an equal verdict skips the callback; without one,
|
|
745
|
+
* every event wakes it. */
|
|
746
|
+
subscribe: (invalidate: () => void) => () => void;
|
|
747
|
+
/** Remove the internal listener and every consumer callback; the handle
|
|
748
|
+
* is dead afterwards. */
|
|
749
|
+
dispose: () => void;
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* Watch a projection of form state without React — the framework-free
|
|
753
|
+
* {@link useWatch} (same `isEqual` bailout), tree-shaken when unused.
|
|
754
|
+
* Returns a {@link WatchHandle}: read `getSnapshot()`, re-read/re-render
|
|
755
|
+
* when `subscribe`'s listener fires. The handle subscribes eagerly, so
|
|
756
|
+
* reads are never stale; `getter`/`isEqual` are captured at creation.
|
|
757
|
+
*/
|
|
758
|
+
declare function watch<T>(form: Form$1, event: SubscribeEvent, getter: () => T, isEqual?: (prev: T, next: T) => boolean): WatchHandle<T>;
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Create a form instance bound to this component.
|
|
762
|
+
*
|
|
763
|
+
* Beyond {@link Options}, the optional `values` object enables controlled
|
|
764
|
+
* usage: when it genuinely changes it is re-synced into the form with
|
|
765
|
+
* setInitialValues semantics -- uncommitted user edits are discarded
|
|
766
|
+
* (master-detail semantics: selecting another record replaces the draft),
|
|
767
|
+
* while touched flags and errors survive. Change detection is
|
|
768
|
+
* reference-first with a structural fallback, so re-renders that pass an
|
|
769
|
+
* inline literal with equal content never re-sync -- the user's
|
|
770
|
+
* in-progress typing is never clobbered. Passing `resetOptions` reroutes
|
|
771
|
+
* those changed-content syncs through {@link reset} instead, so its keep*
|
|
772
|
+
* flags govern what survives (`keepDirtyValues: true` keeps the user's
|
|
773
|
+
* uncommitted edits on dirty fields); the reference/structural guard
|
|
774
|
+
* applies to both routes.
|
|
775
|
+
*/
|
|
776
|
+
declare function useForm<T extends Record<string, any> = any>(options?: Options<T> & {
|
|
777
|
+
values?: T;
|
|
778
|
+
resetOptions?: ResetOptions;
|
|
779
|
+
}): Form$1<T>;
|
|
780
|
+
/** Snapshot equality comparator — the `isEqual` contract {@link
|
|
781
|
+
* useWatchCore} documents. */
|
|
782
|
+
type SnapshotComparator<T> = (prev: T, next: T) => boolean;
|
|
783
|
+
/**
|
|
784
|
+
* Shared core of {@link useWatch} and the path-scoped hooks: a
|
|
785
|
+
* useSyncExternalStore binding over a custom event subscription.
|
|
786
|
+
* `subscribeFactory` receives the invalidate callback (drop the snapshot
|
|
787
|
+
* cache, then notify React) and returns its unsubscribe function, so the
|
|
788
|
+
* core stays identical whether the subscription is global or scoped to
|
|
789
|
+
* one path.
|
|
790
|
+
*
|
|
791
|
+
* The optional `isEqual` comparator redirects `invalidate`: instead of
|
|
792
|
+
* dropping the cache and waking React unconditionally, an event first
|
|
793
|
+
* recomputes the getter and asks `isEqual` whether anything observable
|
|
794
|
+
* changed — an equal verdict keeps the cached snapshot and skips the
|
|
795
|
+
* notify entirely (no render at all), an unequal one stores the fresh
|
|
796
|
+
* snapshot and notifies. Omitted, the historical drop-and-notify pipeline
|
|
797
|
+
* runs byte-for-byte unchanged.
|
|
798
|
+
*/
|
|
799
|
+
declare function useWatchCore<T>(subscribeFactory: (invalidate: () => void) => () => void, getter: () => T, isEqual?: SnapshotComparator<T>): T;
|
|
800
|
+
/**
|
|
801
|
+
* Subscribe to a form event and keep the component's snapshot of `getter()`
|
|
802
|
+
* in sync with the form state.
|
|
803
|
+
*
|
|
804
|
+
* Built on useSyncExternalStore, so snapshots taken while React renders are
|
|
805
|
+
* guaranteed consistent (no tearing under concurrent rendering) and changes
|
|
806
|
+
* emitted before the subscription effect runs are still picked up.
|
|
807
|
+
*
|
|
808
|
+
* The first argument is the form for the unified `fn(form, ...)` context
|
|
809
|
+
* shape every hook shares; the raw emitter form remains accepted for
|
|
810
|
+
* back-compat and for subscription sources that are not a full form.
|
|
811
|
+
*
|
|
812
|
+
* Framework-free counterpart: {@link watch} — the same event/getter/
|
|
813
|
+
* `isEqual` contract exposed as a named export returning a
|
|
814
|
+
* subscribe/getSnapshot handle any reactive runtime can bind to
|
|
815
|
+
* (useWatch is its React binding; the ref-based cache here keeps inline
|
|
816
|
+
* getters from re-subscribing per render).
|
|
817
|
+
*
|
|
818
|
+
* By default the re-render surface is the event's own scope: every emit
|
|
819
|
+
* the subscription hears drops the snapshot cache and wakes React, which
|
|
820
|
+
* then bails out when the recomputed snapshot is reference-identical
|
|
821
|
+
* (Object.is) — the path/leaf scoping every built-in reader relies on.
|
|
822
|
+
* The optional `isEqual` comparator exists for wide-scope getters that
|
|
823
|
+
* return a fresh reference per call (a whole-values selector, say): each
|
|
824
|
+
* event recomputes the getter and asks `isEqual` whether the result is
|
|
825
|
+
* observably the same, and an equal verdict skips notifying React
|
|
826
|
+
* altogether — no render, not even a bailed-out one. An unequal verdict
|
|
827
|
+
* stores the new snapshot and re-renders. Same contract as TanStack's
|
|
828
|
+
* `useSelector` compare. Omitted, behavior is unchanged.
|
|
829
|
+
*/
|
|
830
|
+
declare function useWatch<T>(formOrEmitter: Form$1 | EventEmitter<FormEvents>, event: SubscribeEvent, getter: () => T, isEqual?: SnapshotComparator<T>): T;
|
|
831
|
+
/** Options for {@link useValue} and {@link useValueByPath}. */
|
|
832
|
+
type UseValueOptions<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>> = {
|
|
833
|
+
/** Value to return while the field reads undefined — react-hook-form's
|
|
834
|
+
* `useWatch` `defaultValue`: an untouched, never-seeded field reads
|
|
835
|
+
* this instead of `undefined`. */
|
|
836
|
+
defaultValue?: PathValueOf<T, P>;
|
|
837
|
+
/** Watch descendants too (react-hook-form's `exact: false`): a write
|
|
838
|
+
* to `a.b` invalidates a `useValue(form, 'a')` read, and the read
|
|
839
|
+
* resolves the merged subtree (the copy-on-write `getValues` tree) so
|
|
840
|
+
* descendant edits show up in the result. Defaults to true — the leaf
|
|
841
|
+
* scope, where only the exact key and its ancestors invalidate (the
|
|
842
|
+
* long-standing behavior). */
|
|
843
|
+
exact?: boolean;
|
|
844
|
+
};
|
|
845
|
+
/**
|
|
846
|
+
* Get field value state
|
|
847
|
+
*/
|
|
848
|
+
declare function useValue<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P, options?: UseValueOptions<T, P>): PathValueOf<T, P>;
|
|
849
|
+
/**
|
|
850
|
+
* Get field value state by path
|
|
851
|
+
*/
|
|
852
|
+
declare function useValueByPath(form: Form$1, path: Path, options?: {
|
|
853
|
+
defaultValue?: any;
|
|
854
|
+
exact?: boolean;
|
|
855
|
+
}): any;
|
|
856
|
+
/**
|
|
857
|
+
* Subscribe to the whole values tree: re-renders the calling component
|
|
858
|
+
* whenever any 'change' event lands — react-hook-form's `watch()` with no
|
|
859
|
+
* arguments. The snapshot is the memoized `getValues(form)` result, so
|
|
860
|
+
* repeated reads during one render share one reference and, under
|
|
861
|
+
* `__DEV__`, one frozen copy.
|
|
862
|
+
*
|
|
863
|
+
* Broad scope by design: read it in components that must stay cheap and
|
|
864
|
+
* need the full tree; per-field readers should reach for {@link useValue}
|
|
865
|
+
* instead so a keystroke re-renders exactly the affected field.
|
|
866
|
+
*/
|
|
867
|
+
declare function useValues<T extends Record<string, any> = any>(form: Form$1<T>): T;
|
|
868
|
+
/**
|
|
869
|
+
* Get field touched state
|
|
870
|
+
*/
|
|
871
|
+
declare function useTouched<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): boolean;
|
|
872
|
+
/**
|
|
873
|
+
* Get field touched state by path
|
|
874
|
+
*/
|
|
875
|
+
declare function useTouchedByPath(form: Form$1, path: Path): boolean;
|
|
876
|
+
/**
|
|
877
|
+
* Get field error message state
|
|
878
|
+
* @return current error's message string (display text), or undefined
|
|
879
|
+
*/
|
|
880
|
+
declare function useError<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): string | undefined;
|
|
881
|
+
/**
|
|
882
|
+
* Get field error state by path
|
|
883
|
+
* @return current FieldError object ({type, message}), or undefined
|
|
884
|
+
*/
|
|
885
|
+
declare function useErrorByPath(form: Form$1, path: Path): FieldError | undefined;
|
|
886
|
+
/**
|
|
887
|
+
* Get all field errors
|
|
888
|
+
* @return every error registered for the field (insertion order); an empty
|
|
889
|
+
* array when the field has none
|
|
890
|
+
*/
|
|
891
|
+
declare function useFieldErrors<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): FieldError[];
|
|
892
|
+
/**
|
|
893
|
+
* Get all field errors by path
|
|
894
|
+
* @return every error registered for the field (insertion order); an empty
|
|
895
|
+
* array when the field has none
|
|
896
|
+
*/
|
|
897
|
+
declare function useFieldErrorsByPath(form: Form$1, path: Path): FieldError[];
|
|
898
|
+
declare function useIsDirty(form: Form$1): boolean;
|
|
899
|
+
/**
|
|
900
|
+
* Get whether one field is dirty: its live value exists and differs from
|
|
901
|
+
* the field's effective baseline — the same per-field rule
|
|
902
|
+
* `getFieldState(form, name).isDirty` applies (committed
|
|
903
|
+
* `shouldDirty: false` baselines included). Subscribes to 'change' at
|
|
904
|
+
* leaf scope like {@link useValue}: own-key and ancestor writes re-check
|
|
905
|
+
* the flag, payload-less broadcasts (reset, setInitialValues) always
|
|
906
|
+
* sync, and writes elsewhere never re-render it.
|
|
907
|
+
*/
|
|
908
|
+
declare function useIsFieldDirty<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): boolean;
|
|
909
|
+
/**
|
|
910
|
+
* Get whether one field is dirty, by parsed path. See {@link
|
|
911
|
+
* useIsFieldDirty}.
|
|
912
|
+
*/
|
|
913
|
+
declare function useIsFieldDirtyByPath(form: Form$1, path: Path): boolean;
|
|
914
|
+
/**
|
|
915
|
+
* Get dirty fields state -- object mapping each dirty field's user-facing
|
|
916
|
+
* dotted path ('a.b', 'a.0.c') to true; recalculated after 'change' events
|
|
917
|
+
*/
|
|
918
|
+
declare function useDirtyFields(form: Form$1): Record<string, boolean>;
|
|
919
|
+
/**
|
|
920
|
+
* Get touched fields state -- array of touched fields' user-facing dotted
|
|
921
|
+
* paths ('a.b', 'a.0.c'); recalculated after 'touched' events
|
|
922
|
+
*/
|
|
923
|
+
declare function useTouchedFields(form: Form$1): string[];
|
|
924
|
+
/**
|
|
925
|
+
* Aggregate snapshot of the whole form's state flags — the one-subscription
|
|
926
|
+
* counterpart of react-hook-form's `formState` object (no errors object;
|
|
927
|
+
* per-field error state stays with `useError`/`useFieldErrors`, and
|
|
928
|
+
* `hasErrors`/`isValid` cover the whole-form questions).
|
|
929
|
+
*
|
|
930
|
+
* Recomputed on every state-bearing event; the field-wise comparator keeps
|
|
931
|
+
* the returned reference stable while nothing observably changed, so
|
|
932
|
+
* `useFormState(form).isDirty` re-renders no more often than the dedicated
|
|
933
|
+
* {@link useIsDirty}. Cheaper than calling the granular hooks one by one
|
|
934
|
+
* (one subscription and one snapshot instead of one per flag).
|
|
935
|
+
*/
|
|
936
|
+
type FormState<T extends Record<string, any> = any> = {
|
|
937
|
+
/** Any live value differs from its baseline (see {@link isDirty}). */
|
|
938
|
+
isDirty: boolean;
|
|
939
|
+
/** Dirty fields keyed by user-facing dotted path ('a.b', 'a.0.c'). */
|
|
940
|
+
dirtyFields: Record<string, boolean>;
|
|
941
|
+
/** At least one field is touched. */
|
|
942
|
+
isTouched: boolean;
|
|
943
|
+
/** Touched fields' user-facing dotted paths. */
|
|
944
|
+
touchedFields: string[];
|
|
945
|
+
/** Any error registered (field or form level). */
|
|
946
|
+
hasErrors: boolean;
|
|
947
|
+
/** No errors are registered — react-hook-form's `isValid` semantics.
|
|
948
|
+
* In-flight validation is NOT factored in ({@link isValidating} is the
|
|
949
|
+
* separate signal; async rounds temporarily pass this flag like RHF's). */
|
|
950
|
+
isValid: boolean;
|
|
951
|
+
/** Every error as one record keyed by user-facing dotted path
|
|
952
|
+
* ('a.b', 'list.0') — react-hook-form's `formState.errors` shape,
|
|
953
|
+
* typed as {@link FieldErrors} (per-key values optional). Memoized
|
|
954
|
+
* (see {@link getErrorsRecord}): the reference is stable between error
|
|
955
|
+
* writes, so the snapshot comparator can bail on it. */
|
|
956
|
+
errors: FieldErrors<T>;
|
|
957
|
+
isSubmitting: boolean;
|
|
958
|
+
/**
|
|
959
|
+
* Whether a submit has been attempted on this form — set on the first
|
|
960
|
+
* `handleSubmit` call (validation outcome aside) and cleared by
|
|
961
|
+
* `reset`, react-hook-form's `formState.isSubmitted` semantics. Read
|
|
962
|
+
* after a failed submit to render a "fix the errors below" panel.
|
|
963
|
+
*/
|
|
964
|
+
isSubmitted: boolean;
|
|
965
|
+
/** Any validation round is running (field, form-level, or a pending
|
|
966
|
+
* debounce window). */
|
|
967
|
+
isValidating: boolean;
|
|
968
|
+
isSubmitSuccessful: boolean | undefined;
|
|
969
|
+
submitCount: number;
|
|
970
|
+
/** Async initialValues still pending ({@link Form.isLoading}). */
|
|
971
|
+
isLoading: boolean;
|
|
972
|
+
/** The form-level disabled flag (fields OR their own `disabled`). */
|
|
973
|
+
disabled: boolean;
|
|
974
|
+
};
|
|
975
|
+
declare function useFormState<T extends Record<string, any> = any>(form: Form$1<T>): FormState<T>;
|
|
976
|
+
/**
|
|
977
|
+
* The official selector primitive — TanStack Form's
|
|
978
|
+
* `useStore(store, selector)` counterpart. Subscribes to every
|
|
979
|
+
* state-bearing form event and keeps `selector()`'s result as the
|
|
980
|
+
* snapshot; the selector itself is a plain closure (read the form through
|
|
981
|
+
* any getter — `getValue`, `getValues`, `form.errors.size`, …).
|
|
982
|
+
*
|
|
983
|
+
* Without `isEqual` the subscription is object-identity based: each event
|
|
984
|
+
* recomputes the selector and React bails out when the result is
|
|
985
|
+
* reference-identical (the contract every `useWatch` reader relies on).
|
|
986
|
+
* The optional `isEqual(prev, next)` comparator is for wide-scope
|
|
987
|
+
* selectors that return a fresh reference per call (a whole-values
|
|
988
|
+
* projection, say): an equal verdict skips notifying React altogether —
|
|
989
|
+
* no render, not even a bailed-out one (TanStack `useSelector` compare
|
|
990
|
+
* contract).
|
|
991
|
+
*
|
|
992
|
+
* `useFormState` is the built-in aggregate selector; {@link useWatch} is
|
|
993
|
+
* the single-event version. Reach for `useStore` when the projection is
|
|
994
|
+
* yours and spans state events — e.g. `form.validating.size > 0 &&
|
|
995
|
+
* form.isSubmitting` as one flag.
|
|
996
|
+
*/
|
|
997
|
+
declare function useStore<T>(form: Form$1, selector: () => T, isEqual?: SnapshotComparator<T>): T;
|
|
998
|
+
declare function useHasErrors(form: Form$1): boolean;
|
|
999
|
+
/**
|
|
1000
|
+
* Get every error as one record keyed by user-facing dotted path
|
|
1001
|
+
* ('a.b', 'list.0') — react-hook-form's `formState.errors` shape, for
|
|
1002
|
+
* error-summary panels and a11y announcements. Values are the stored
|
|
1003
|
+
* FieldError[] arrays shared with the form (treat as read-only). The
|
|
1004
|
+
* record is memoized per form (see {@link getErrorsRecord}): the hook
|
|
1005
|
+
* re-renders only when an error write actually changed the record's
|
|
1006
|
+
* content.
|
|
1007
|
+
*/
|
|
1008
|
+
declare function useErrors<T extends Record<string, any> = any>(form: Form$1<T>): FieldErrors<T>;
|
|
1009
|
+
/**
|
|
1010
|
+
* Get every error as one nested object following the values tree
|
|
1011
|
+
* (`errors.items?.[0]?.name` reads) — the typed optional-chaining
|
|
1012
|
+
* counterpart of {@link useErrors}' flat dotted record. Leaves hold the
|
|
1013
|
+
* stored FieldError[] arrays shared with the form (treat as read-only).
|
|
1014
|
+
* Memoized alongside the record (see {@link getErrorsTree}): the hook
|
|
1015
|
+
* re-renders only when an error write actually changed the tree's
|
|
1016
|
+
* content.
|
|
1017
|
+
*/
|
|
1018
|
+
declare function useErrorsTree<T extends Record<string, any> = any>(form: Form$1<T>): FieldErrorsTree<T>;
|
|
1019
|
+
/**
|
|
1020
|
+
* Get whether the form currently has no errors — react-hook-form's
|
|
1021
|
+
* `formState.isValid` counterpart. Subscribes to the `'errors'` event only;
|
|
1022
|
+
* in-flight validation does not flip it (see {@link useIsValidating}).
|
|
1023
|
+
*/
|
|
1024
|
+
declare function useIsValid(form: Form$1): boolean;
|
|
1025
|
+
declare function useIsSubmitting(form: Form$1): boolean;
|
|
1026
|
+
/**
|
|
1027
|
+
* Get whether an async {@link Options.initialValues} source is still
|
|
1028
|
+
* pending — the flag a loading skeleton or a disabled submit button gates
|
|
1029
|
+
* on until the resolved baseline lands. Subscribes to the 'loading' event
|
|
1030
|
+
* the core emits around the resolution cycle.
|
|
1031
|
+
*/
|
|
1032
|
+
declare function useIsLoading(form: Form$1): boolean;
|
|
1033
|
+
/**
|
|
1034
|
+
* Get the form's user-owned metadata slot reactively (Formik's `status`
|
|
1035
|
+
* counterpart): any value the app stores through {@link setStatus} —
|
|
1036
|
+
* server session flags, wizard step state, non-field errors. Subscribes
|
|
1037
|
+
* to the payload-less 'status' event, so unrelated events never re-render
|
|
1038
|
+
* the caller, and the returned reference is stable between writes that
|
|
1039
|
+
* store an equal value (useSyncExternalStore's Object.is bailout).
|
|
1040
|
+
*/
|
|
1041
|
+
declare function useStatus<T = any>(form: Form$1): T;
|
|
1042
|
+
/**
|
|
1043
|
+
* Get whether the form accepts a submit right now:
|
|
1044
|
+
* `!isSubmitting && !hasErrors`. This is the single flag a submit
|
|
1045
|
+
* button's `disabled` prop wants — it is `false` for the whole async
|
|
1046
|
+
* `onSubmit` span (not just the validation pass) and whenever any field
|
|
1047
|
+
* holds an error (client validation or server backfill), replacing the
|
|
1048
|
+
* hand-rolled `useHasErrors(form) || useIsSubmitting(form)` pair.
|
|
1049
|
+
* Deliberately no dirty or validating semantics: an untouched-but-clean
|
|
1050
|
+
* form can submit.
|
|
1051
|
+
*/
|
|
1052
|
+
declare function useCanSubmit(form: Form$1): boolean;
|
|
1053
|
+
declare function useSubmitCount(form: Form$1): number;
|
|
1054
|
+
/**
|
|
1055
|
+
* Get whether any validation round is currently running: a field
|
|
1056
|
+
* validator's pending `validateDebounce` window, an async field validator
|
|
1057
|
+
* still in flight, or the form-level validate's debounce window / in-flight
|
|
1058
|
+
* round — every one of them holds a key in `form.validating`, and the
|
|
1059
|
+
* 'validating' events they emit (field rounds with a path payload, the
|
|
1060
|
+
* form-level round as a payload-less broadcast) are what this subscribes
|
|
1061
|
+
* to. The boolean snapshot is Object.is-stable, so churn among the marks
|
|
1062
|
+
* (a second field opening while the first settles) costs no render while
|
|
1063
|
+
* the flag holds. This is the flag a submit button disables itself on, or
|
|
1064
|
+
* spins a spinner with, through the pre-submit validation pass — it flips
|
|
1065
|
+
* true the moment the first round opens and back false when the last one
|
|
1066
|
+
* settles.
|
|
1067
|
+
*/
|
|
1068
|
+
declare function useIsValidating(form: Form$1): boolean;
|
|
1069
|
+
/**
|
|
1070
|
+
* Get whether the last submit succeeded: `true` once a submit's validation
|
|
1071
|
+
* and `onSubmit` completed without throwing, `false` after a failed submit
|
|
1072
|
+
* (validation rejection or a thrown callback) and before any submit ran —
|
|
1073
|
+
* the falsy reading of the undefined initial/reset state. Subscribes to
|
|
1074
|
+
* the 'submitSuccessful' event the core's setSubmitSuccessful emits, so
|
|
1075
|
+
* the flag flips in the same tick the outcome lands: the usual consumers
|
|
1076
|
+
* are a success banner and a redirect-on-success effect.
|
|
1077
|
+
*/
|
|
1078
|
+
declare function useIsSubmitSuccessful(form: Form$1): boolean;
|
|
1079
|
+
/**
|
|
1080
|
+
* Get the form-level error message: the first error stored under the
|
|
1081
|
+
* reserved {@link FORM_ERROR} key, as display text — or undefined while
|
|
1082
|
+
* the slot is clean. That key is where a form-level `validate` record's
|
|
1083
|
+
* `_form` entry lands and where the Standard Schema adapter drops
|
|
1084
|
+
* path-less issues, so errors that belong to no single field still have a
|
|
1085
|
+
* reader. The classic usage renders it once above the submit button —
|
|
1086
|
+
* `useFormError(form) || null` — and the imperative twin is
|
|
1087
|
+
* `getError(form, FORM_ERROR)`.
|
|
1088
|
+
*/
|
|
1089
|
+
declare function useFormError(form: Form$1): string | undefined;
|
|
1090
|
+
/**
|
|
1091
|
+
* Get every form-level error: all errors stored under the reserved
|
|
1092
|
+
* {@link FORM_ERROR} key (insertion order), an empty array when the slot
|
|
1093
|
+
* is clean. The plural twin of {@link useFormError} for forms that stack
|
|
1094
|
+
* several form-level issues — each path-less Standard Schema issue lands
|
|
1095
|
+
* in this slot. The array reference is stable between unrelated events
|
|
1096
|
+
* (the stored array or a shared empty constant), so consumers can memo on
|
|
1097
|
+
* it; the imperative counterpart is `getFieldErrors(form, FORM_ERROR)`.
|
|
1098
|
+
*/
|
|
1099
|
+
declare function useFormErrors(form: Form$1): FieldError[];
|
|
1100
|
+
|
|
1101
|
+
type UseTransformOptions<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>, TDisplay = PathValueOf<TValues, TPath>> = {
|
|
1102
|
+
/** Map the stored (raw) value to the display value (read direction);
|
|
1103
|
+
* omitted = identity. */
|
|
1104
|
+
toDisplay?: (raw: PathValueOf<TValues, TPath>) => TDisplay;
|
|
1105
|
+
/** Map a display value back to the raw value (write direction);
|
|
1106
|
+
* omitted = identity. May return a Promise — only the latest write
|
|
1107
|
+
* commits (stale resolutions drop). The round trip should be an
|
|
1108
|
+
* identity; non-invertible store values must be handled by
|
|
1109
|
+
* `toDisplay`, which runs first. */
|
|
1110
|
+
fromDisplay?: (display: TDisplay) => PathValueOf<TValues, TPath> | Promise<PathValueOf<TValues, TPath>>;
|
|
1111
|
+
/** Debounce the display→raw commit; only the last write in the window
|
|
1112
|
+
* commits (TanStack `asyncDebounceMs`). `0`/omitted commits
|
|
1113
|
+
* immediately; validation fires at commit time through the
|
|
1114
|
+
* user-change pipeline. */
|
|
1115
|
+
asyncDebounceMs?: number;
|
|
1116
|
+
};
|
|
1117
|
+
/**
|
|
1118
|
+
* Bind a control whose display value differs from the stored raw value
|
|
1119
|
+
* (TanStack `useTransform`): `toDisplay` maps store→display,
|
|
1120
|
+
* `fromDisplay` maps display→store. The store always carries the raw
|
|
1121
|
+
* value. `value` subscribes to 'change' at leaf scope; `onChange` writes
|
|
1122
|
+
* through the user-change channel, so mode-gated validation fires as if
|
|
1123
|
+
* the user typed. Transform functions are read fresh each render.
|
|
1124
|
+
*/
|
|
1125
|
+
declare function useTransform<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>, TDisplay = PathValueOf<TValues, TPath>>(form: Form$1<TValues>, name: TPath, options?: UseTransformOptions<TValues, TPath, TDisplay>): {
|
|
1126
|
+
value: TDisplay;
|
|
1127
|
+
onChange: (display: TDisplay) => void;
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
/** Props for <Form>. Native constraint validation gates submission: the
|
|
1131
|
+
* form always sets noValidate, but checkValidity() runs before custom
|
|
1132
|
+
* validators and a failure stops submission (onInvalidSubmit fires).
|
|
1133
|
+
* `shouldUseNativeValidation={false}` skips the gate (targets without
|
|
1134
|
+
* checkValidity are always exempt). The flow itself lives in the headless
|
|
1135
|
+
* `handleSubmit`; this is a thin wrapper binding it to the <form>. */
|
|
1136
|
+
type FormProps<T extends Record<string, any> = any> = Omit<React.FormHTMLAttributes<HTMLFormElement>, 'onSubmit'> & {
|
|
1137
|
+
form?: Form$1<T>;
|
|
1138
|
+
/** Isolated context from `createFormContext()`: its bound hooks see this
|
|
1139
|
+
* form, the module-level ones do not. Defaults to FormContext. */
|
|
1140
|
+
context?: React.Context<Form$1<any> | null>;
|
|
1141
|
+
/** Values baseline — sync object, Promise, or thunk; async sources gate on `isLoading`. */
|
|
1142
|
+
initialValues?: T | Promise<T> | (() => T | Promise<T>);
|
|
1143
|
+
/** Default unmount behavior: `true` tombstones unmounted fields, `false` keeps values. */
|
|
1144
|
+
shouldUnregister?: boolean;
|
|
1145
|
+
/** Validate on mount: each validator kicks once; a field's own prop overrides. */
|
|
1146
|
+
validateOnMount?: boolean;
|
|
1147
|
+
/** Disable every bound field (fields OR with their own option); undefined leaves the flag untouched. */
|
|
1148
|
+
disabled?: boolean;
|
|
1149
|
+
/** Form-level default for `asyncAlways`; a field's own prop overrides. */
|
|
1150
|
+
asyncAlways?: boolean;
|
|
1151
|
+
/** Controlled external values: a new reference syncs via setInitialValues
|
|
1152
|
+
* (draft discarded, touched/errors kept); same reference never clobbers. */
|
|
1153
|
+
values?: T;
|
|
1154
|
+
/** May be async; `isSubmitting` covers the flight. */
|
|
1155
|
+
onSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;
|
|
1156
|
+
/** May be async, same as onSubmit. */
|
|
1157
|
+
onValidSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;
|
|
1158
|
+
/** Server Action target: after validation, schema-coerced values become
|
|
1159
|
+
* FormData and dispatch here. Returning {@link ActionErrorResult} lands
|
|
1160
|
+
* `type: 'server'` per-field errors (unsuccessful submit); a URL string
|
|
1161
|
+
* renders the native `action` for no-JS progressive enhancement. */
|
|
1162
|
+
action?: string | ((formData: FormData) => void | Promise<void | ActionErrorResult>);
|
|
1163
|
+
/** Called when validation fails; errors are {path, type, message} entries
|
|
1164
|
+
* (type: 'custom' | 'native'). */
|
|
1165
|
+
onInvalidSubmit?: (errors: {
|
|
1166
|
+
path: string;
|
|
1167
|
+
type: string;
|
|
1168
|
+
message: string;
|
|
1169
|
+
}[], values: T) => void;
|
|
1170
|
+
/** Focus the first errored field (or first ':invalid' control) after a failed submit. Default true. */
|
|
1171
|
+
shouldFocusError?: boolean;
|
|
1172
|
+
/** Whether native constraint validation gates submission (pass false for
|
|
1173
|
+
* custom-validator-only forms). Seeds the created form's flag and this
|
|
1174
|
+
* form's submit wiring. */
|
|
1175
|
+
shouldUseNativeValidation?: boolean;
|
|
1176
|
+
};
|
|
1177
|
+
declare function Form<T extends Record<string, any> = any>({ form: f1, context, initialValues, values, shouldUnregister, validateOnMount, disabled, asyncAlways, onSubmit, onValidSubmit, onInvalidSubmit, action, shouldFocusError, shouldUseNativeValidation, ...props }: FormProps<T>): React.JSX.Element;
|
|
1178
|
+
|
|
1179
|
+
/** Every {@link UseFieldOptions} option plus a render-prop `children`
|
|
1180
|
+
* receiving the bound field result. */
|
|
1181
|
+
type FormFieldProps<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = UseFieldOptions$1<TValues, TPath> & {
|
|
1182
|
+
children: (field: UseFieldResult<TValues, TPath>) => React.ReactNode;
|
|
1183
|
+
};
|
|
1184
|
+
/** Headless field via a render prop — the non-hook {@link useField} for
|
|
1185
|
+
* class components/callback consumers. The child receives the full
|
|
1186
|
+
* {@link UseFieldResult}; resolves its form from FormContext or the
|
|
1187
|
+
* `form` option. */
|
|
1188
|
+
declare function FormField<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>({ children, ...options }: FormFieldProps<TValues, TPath>): React.ReactNode;
|
|
1189
|
+
|
|
1190
|
+
/** The error-message element id a field's `aria-describedby` points at
|
|
1191
|
+
* (same id `<Field>`'s renderError span carries). A custom error
|
|
1192
|
+
* component completes the accessible-name chain with
|
|
1193
|
+
* `<span id={fieldErrorId(name)} role="alert">`. */
|
|
1194
|
+
declare function fieldErrorId(name: Name): string;
|
|
1195
|
+
|
|
1196
|
+
/** Props shared by Field/Checkbox/Select: the hook options minus the
|
|
1197
|
+
* required `name` (the components type it optional) and `validateDeps`
|
|
1198
|
+
* (the components do not forward it), plus the index signature that lets
|
|
1199
|
+
* DOM props flow through. */
|
|
1200
|
+
type UseFieldOptions<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = Omit<UseFieldOptions$1<TValues, TPath>, 'name' | 'validateDeps'> & {
|
|
1201
|
+
name?: TPath;
|
|
1202
|
+
[key: string]: any;
|
|
1203
|
+
};
|
|
1204
|
+
type FieldProps<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = UseFieldOptions<TValues, TPath> & {
|
|
1205
|
+
as?: React.ComponentType<any>;
|
|
1206
|
+
asProps?: Record<string, any>;
|
|
1207
|
+
valueToProps?: (value: any) => Record<string, any>;
|
|
1208
|
+
/** Error renderer: renders `<span id role="alert">` beside the input;
|
|
1209
|
+
* `aria-describedby` always points at that id (`fieldErrorId`). */
|
|
1210
|
+
renderError?: (error: string, id: string) => React.ReactNode;
|
|
1211
|
+
};
|
|
1212
|
+
/** Callable shape of {@link Field}; a named interface because the inline
|
|
1213
|
+
* `as <TValues,...>() => ...` form trips no-use-before-define. */
|
|
1214
|
+
type FieldComponent = {
|
|
1215
|
+
<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(props: FieldProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
|
|
1216
|
+
};
|
|
1217
|
+
declare const Field: FieldComponent;
|
|
1218
|
+
/** Callable shape of {@link Checkbox}: same form-typed `validate` contract
|
|
1219
|
+
* as {@link FieldComponent}. */
|
|
1220
|
+
type CheckboxComponent = {
|
|
1221
|
+
<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(props: UseFieldOptions<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
|
|
1222
|
+
};
|
|
1223
|
+
declare const Checkbox: CheckboxComponent;
|
|
1224
|
+
type SelectProps<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = UseFieldOptions<TValues, TPath> & {
|
|
1225
|
+
multiple?: boolean;
|
|
1226
|
+
children?: React.ReactNode;
|
|
1227
|
+
};
|
|
1228
|
+
/** Callable shape of {@link Select}: same form-typed `validate` contract
|
|
1229
|
+
* as {@link FieldComponent}. */
|
|
1230
|
+
type SelectComponent = {
|
|
1231
|
+
<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(props: SelectProps<TValues, TPath> & React.RefAttributes<HTMLSelectElement>): React.ReactElement | null;
|
|
1232
|
+
};
|
|
1233
|
+
declare const Select: SelectComponent;
|
|
1234
|
+
|
|
1235
|
+
/** Props for <ErrorSummary>: same form/context resolution <Form> itself
|
|
1236
|
+
* uses — an explicit `form` wins, otherwise the (optionally isolated)
|
|
1237
|
+
* context form. */
|
|
1238
|
+
type ErrorSummaryProps<T extends Record<string, any> = any> = {
|
|
1239
|
+
form?: Form$1<T>;
|
|
1240
|
+
context?: React.Context<Form$1<any> | null>;
|
|
1241
|
+
heading?: string;
|
|
1242
|
+
};
|
|
1243
|
+
/** A GOV.UK-style error summary: one `role='alert'` box listing every
|
|
1244
|
+
* field error, each linking to the field's error element id. Clicking a
|
|
1245
|
+
* link focuses the field through the same `focusError` channel a failed
|
|
1246
|
+
* submit uses; after a failed submit the box itself takes focus (pair it
|
|
1247
|
+
* with `shouldFocusError={false}`, whose field focus lands later and
|
|
1248
|
+
* would otherwise win). {@link FORM_ERROR} entries have no field to focus
|
|
1249
|
+
* and render as plain list items. */
|
|
1250
|
+
declare function ErrorSummary<T extends Record<string, any> = any>({ form: formProp, context, heading }: ErrorSummaryProps<T>): React.ReactElement | null;
|
|
1251
|
+
|
|
1252
|
+
export { AnyPath, Checkbox, CheckboxGroupContext, CheckboxGroupProvider, ErrorSummary, Field, FieldError, FieldErrorEntry, FieldErrors, FieldErrorsTree, FieldPath, FieldRules, Form, FormContext, FormEvents, FormField, Form$1 as FormInstance, FormProvider, Name, Options, Path, PathValueOf, RegisterOptions, RegisterProps, Select, StandardSchemaV1, ValidationMode, Validator, changeValue, changeValueByPath, createFormContext, emitChangeByPath, fieldErrorId, firstMountedDescendantKey, getDirtyFields, getFieldState, getTouchedFields, getValue, getValueByPath, getValues, handleSubmit, hasTouched, hasTouchedByPath, incrementSubmitCount, isDirty, isFieldDirtyByPath, isTouched, registerField, registerFieldMode, removeField, removeFieldByPath, reset, resetField, seedValueByPath, setDisabled, setInitialValues, setIsSubmitting, setStatus, setSubmitSuccessful, setTouched, setTouchedByPath, setValue, setValueByPath, subscribe, unregisterFieldMode, useCanSubmit, useCheckboxGroupContext, useDirtyFields, useError, useErrorByPath, useErrors, useErrorsTree, useField, useFieldArray, useFieldArrayItem, useFieldErrors, useFieldErrorsByPath, useForm, useFormContext, useFormError, useFormErrors, useFormState, useHasErrors, useIsDirty, useIsFieldDirty, useIsFieldDirtyByPath, useIsLoading, useIsSubmitSuccessful, useIsSubmitting, useIsValid, useIsValidating, useStatus, useStore, useSubmitCount, useTouched, useTouchedByPath, useTouchedFields, useTransform, useValue, useValueByPath, useValues, useWatch, useWatchCore, userBlur, userChangeByPath, watch };
|
|
1253
|
+
export type { ActionErrorResult, FieldArrayFocusOptions, FieldState, FormContextBundle, FormState, HandleSubmitOptions, RemoveFieldOptions, ResetFieldOptions, ResetOptions, SetFieldOptions, SubscribeEvent, SubscribeOptions, UseTransformOptions, UseValueOptions, WatchHandle, WatchScope };
|