react-f0rm 1.1.0 → 1.2.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 +152 -32
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.cjs.js.map +1 -1
- package/dist/devtools/index.d.ts +2 -2
- package/dist/devtools/index.mjs +1 -1
- package/dist/devtools/index.mjs.map +1 -1
- package/dist/errors-CxSjrWJO.cjs.js +2 -0
- package/dist/errors-CxSjrWJO.cjs.js.map +1 -0
- package/dist/errors-CzWtwjO0.mjs +2 -0
- package/dist/errors-CzWtwjO0.mjs.map +1 -0
- package/dist/form-CvmWHUrd.d.ts +423 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +786 -102
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +801 -354
- 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 +2 -0
- package/dist/persist.cjs.js.map +1 -0
- package/dist/persist.d.ts +49 -0
- package/dist/persist.mjs +2 -0
- package/dist/persist.mjs.map +1 -0
- 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.ts +7 -5
- 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.ts +1 -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.ts +1 -1
- package/dist/resolvers/zod.mjs +1 -1
- package/dist/resolvers/zod.mjs.map +1 -1
- package/dist/server/index.cjs.js +2 -0
- package/dist/server/index.cjs.js.map +1 -0
- package/dist/server/index.d.ts +77 -0
- package/dist/server/index.mjs +2 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/validate-B1Gdjeaq.mjs +2 -0
- package/dist/validate-B1Gdjeaq.mjs.map +1 -0
- package/dist/validate-CUmNZqg6.d.ts +238 -0
- package/dist/validate-DAfz8Nbb.cjs.js +2 -0
- package/dist/validate-DAfz8Nbb.cjs.js.map +1 -0
- package/dist/values-B1IV-6V4.mjs +2 -0
- package/dist/values-B1IV-6V4.mjs.map +1 -0
- package/dist/values-CDNAYEOB.cjs.js +2 -0
- package/dist/values-CDNAYEOB.cjs.js.map +1 -0
- package/package.json +71 -24
- package/dist/form-BGWPwts2.mjs +0 -2
- package/dist/form-BGWPwts2.mjs.map +0 -1
- package/dist/form-BiDaJLjD.d.ts +0 -826
- package/dist/form-DwuY91QB.cjs.js +0 -2
- package/dist/form-DwuY91QB.cjs.js.map +0 -1
- package/dist/validate-2XUilILy.d.ts +0 -22
package/dist/form-BiDaJLjD.d.ts
DELETED
|
@@ -1,826 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from '@for-fun/event-emitter';
|
|
2
|
-
|
|
3
|
-
type PathSegments = (string | number)[];
|
|
4
|
-
type Name = string | PathSegments;
|
|
5
|
-
type Path = {
|
|
6
|
-
value: PathSegments;
|
|
7
|
-
key: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Compile-time field path utilities: `FieldPath<T>` enumerates the valid
|
|
12
|
-
* path strings for a values shape `T` ('a', 'a.b', 'a[0]', 'a[b]', ...),
|
|
13
|
-
* and `PathValue<T, P>` resolves the leaf type a path points at.
|
|
14
|
-
* The grammar mirrors the paths accepted at runtime by `normalizePath`:
|
|
15
|
-
* numeric segments are bracket-only ('a[0]', never 'a.0' — dotted
|
|
16
|
-
* numerics throw a TypeError at runtime).
|
|
17
|
-
*/
|
|
18
|
-
/** `true` only for the `any` type (`0 extends 1 & any`). */
|
|
19
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
20
|
-
type Primitive = null | undefined | string | number | boolean | symbol | bigint;
|
|
21
|
-
/** Depth countdown: Prev[9] = 8 ... Prev[1] = 0, Prev[0] = never stops recursion. */
|
|
22
|
-
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
23
|
-
/** Paths are capped at 10 segments to keep instantiation depth bounded. */
|
|
24
|
-
type MaxDepth = 9;
|
|
25
|
-
/**
|
|
26
|
-
* Valid path continuations after a segment: `.k` / `[k]` / `[0]`,
|
|
27
|
-
* optionally followed by deeper continuations into the child node.
|
|
28
|
-
* Numeric segments are bracket-only (`.0` throws at runtime); object
|
|
29
|
-
* keys that are themselves numeric strings likewise enumerate just the
|
|
30
|
-
* bracket subscript.
|
|
31
|
-
*/
|
|
32
|
-
type Continue<T, D extends number> = [D] extends [never] ? never : IsAny<T> extends true ? string : T extends Primitive | Function ? never : T extends readonly (infer U)[] ? `[${number}]` | `[${number}]${Continue<U, Prev[D]>}` : {
|
|
33
|
-
[K in Extract<keyof T, string>]: (K extends `${number}` ? never : `.${K}`) | `[${K}]` | (K extends `${number}` ? never : `.${K}${Continue<T[K], Prev[D]>}`) | `[${K}]${Continue<T[K], Prev[D]>}`;
|
|
34
|
-
}[Extract<keyof T, string>];
|
|
35
|
-
/**
|
|
36
|
-
* Every valid field path string for a values shape `T`.
|
|
37
|
-
* @example FieldPath<{a: {b: string}}> // 'a' | 'a.b' | 'a[b]'
|
|
38
|
-
*/
|
|
39
|
-
type FieldPath<T> = IsAny<T> extends true ? string : T extends Primitive | Function ? never : T extends readonly (infer U)[] ? `[${number}]` | `[${number}]${Continue<U, MaxDepth>}` : {
|
|
40
|
-
[K in Extract<keyof T, string>]: K extends `${number}` ? never : K | `${K}${Continue<T[K], MaxDepth>}`;
|
|
41
|
-
}[Extract<keyof T, string>];
|
|
42
|
-
/** Resolve `T[K]` for one bare segment: array index -> element, object key -> value. */
|
|
43
|
-
type Lookup<T, K extends string> = K extends `${number}` ? T extends readonly (infer U)[] ? U : never : K extends keyof T ? T[K] : never;
|
|
44
|
-
/** One dot-separated chunk: a bare segment plus any `[k]` / `[0]` suffixes. */
|
|
45
|
-
type ChunkValue<T, C extends string> = C extends `${infer Key}[${infer Tail}` ? ChunkSuffix<Lookup<T, Key>, `[${Tail}`> : Lookup<T, C>;
|
|
46
|
-
type ChunkSuffix<T, S extends string> = S extends `[${infer Key}]${infer Rest}` ? Rest extends '' ? Lookup<T, Key> : PathOf<Lookup<T, Key>, Rest> : never;
|
|
47
|
-
/** Resolve the value type the path string `P` points at inside `T`. */
|
|
48
|
-
type PathOf<T, P extends string> = P extends '' ? never : P extends `[${infer Key}]${infer Rest}` ? Rest extends '' ? Lookup<T, Key> : PathOf<Lookup<T, Key>, Rest> : P extends `.${infer Rest}` ? PathOf<T, Rest> : P extends `${infer Chunk}.${infer Rest}` ? PathOf<ChunkValue<T, Chunk>, Rest> : ChunkValue<T, P>;
|
|
49
|
-
/**
|
|
50
|
-
* The value type at path `P` of a values shape `T`.
|
|
51
|
-
* @example PathValue<{a: {b: string}}, 'a.b'> // string
|
|
52
|
-
*/
|
|
53
|
-
type PathValue<T, P extends FieldPath<T>> = PathOf<T, P & string>;
|
|
54
|
-
/**
|
|
55
|
-
* The value type at path `P` of `T`, or `any` when `P` is not a known
|
|
56
|
-
* field path (plain `string` / segment-array calls keep their old behavior).
|
|
57
|
-
*/
|
|
58
|
-
type PathValueOf<T, P> = P extends FieldPath<T> ? PathValue<T, Extract<P, FieldPath<T>>> : any;
|
|
59
|
-
|
|
60
|
-
/** A field error: `type` identifies the error kind ('custom' for plain
|
|
61
|
-
* string errors), `message` is the display text. */
|
|
62
|
-
interface FieldError {
|
|
63
|
-
type: string;
|
|
64
|
-
message: string;
|
|
65
|
-
}
|
|
66
|
-
/** A flattened entry from {@link getErrors}. */
|
|
67
|
-
type FieldErrorEntry = {
|
|
68
|
-
path: string;
|
|
69
|
-
type: string;
|
|
70
|
-
message: string;
|
|
71
|
-
};
|
|
72
|
-
/** When a field is validated:
|
|
73
|
-
* - `'onSubmit'` (default): only on submit
|
|
74
|
-
* - `'onBlur'`: when the field loses focus
|
|
75
|
-
* - `'onChange'`: on every change
|
|
76
|
-
* - `'onTouched'`: on first blur, then on every change
|
|
77
|
-
* - `'all'`: on both change and blur
|
|
78
|
-
*/
|
|
79
|
-
type ValidationMode = 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all';
|
|
80
|
-
/** When a field is re-validated after it already has an error:
|
|
81
|
-
* - `'onChange'` (default): on every change
|
|
82
|
-
* - `'onBlur'`: when the field loses focus
|
|
83
|
-
* - `'onSubmit'`: only on submit (no live re-validation)
|
|
84
|
-
*/
|
|
85
|
-
type ReValidateMode = 'onChange' | 'onBlur' | 'onSubmit';
|
|
86
|
-
/** Brand marking a form-level validate result as a structured
|
|
87
|
-
* {@link ValidationOutcome} (parsed values and/or errors) rather than a
|
|
88
|
-
* plain nested error record. Symbols cannot collide with user error
|
|
89
|
-
* records, so detection is an exact `VALIDATION_OUTCOME in result`. */
|
|
90
|
-
declare const VALIDATION_OUTCOME: unique symbol;
|
|
91
|
-
/** Structured form-level validate result: `errors` uses the same nested
|
|
92
|
-
* shape a plain error record uses, `values` is the schema's parsed output
|
|
93
|
-
* (coerce/transform results included). Either side may be omitted. */
|
|
94
|
-
type ValidationOutcome<T> = {
|
|
95
|
-
[VALIDATION_OUTCOME]: true;
|
|
96
|
-
errors?: Record<string, any>;
|
|
97
|
-
values?: T;
|
|
98
|
-
};
|
|
99
|
-
/** What a form-level validate function may return: a plain nested error
|
|
100
|
-
* record (flattened into field errors — the long-standing shape), or a
|
|
101
|
-
* branded {@link ValidationOutcome} whose `values` become the form's
|
|
102
|
-
* parsedValues baseline. */
|
|
103
|
-
type ValidateResult<T> = Record<string, any> | ValidationOutcome<T> | Promise<Record<string, any> | ValidationOutcome<T>>;
|
|
104
|
-
/** Context passed to a form-level `validate` function's second argument.
|
|
105
|
-
* `signal` aborts as soon as the round is superseded — a newer round
|
|
106
|
-
* started (which only happens under a positive `validateDebounce`, where
|
|
107
|
-
* kicks merge into windows) — so async validators can cancel their
|
|
108
|
-
* underlying work instead of racing a stale result home. Stale results
|
|
109
|
-
* are dropped independently by the round gate, so validators that ignore
|
|
110
|
-
* the signal stay correct too; the same contract field-level validators
|
|
111
|
-
* get through their own `meta`. */
|
|
112
|
-
type FormValidateMeta<T extends Record<string, any> = any> = {
|
|
113
|
-
form: Form<T>;
|
|
114
|
-
signal: AbortSignal;
|
|
115
|
-
};
|
|
116
|
-
/** Form-level validator: receives all values (plus {@link
|
|
117
|
-
* FormValidateMeta} as an optional second argument) and returns a
|
|
118
|
-
* {@link ValidateResult} — sync or async — or `undefined`/nothing when
|
|
119
|
-
* valid (the runtime skips falsy results, so implicit-return callbacks
|
|
120
|
-
* type-check). */
|
|
121
|
-
type FormValidateFn<T extends Record<string, any> = any> = (values: T, meta: FormValidateMeta<T>) => ValidateResult<T> | undefined;
|
|
122
|
-
interface Form<T extends Record<string, any> = any> {
|
|
123
|
-
emitter: EventEmitter;
|
|
124
|
-
mode: ValidationMode;
|
|
125
|
-
reValidateMode: ReValidateMode;
|
|
126
|
-
initialValues: T;
|
|
127
|
-
values: Map<string, any>;
|
|
128
|
-
/** Tombstones of unregistered field paths (JSON path keys): reading or
|
|
129
|
-
* merging values must not fall back to initialValues for these paths. */
|
|
130
|
-
deleted: Set<string>;
|
|
131
|
-
/** Every error registered for a field, as a non-empty array (the
|
|
132
|
-
* write-side {@link setErrorByPath} normalizes to this invariant, so
|
|
133
|
-
* readers never need to guard against an empty list). Readers wanting
|
|
134
|
-
* the display error take the first entry ({@link getError}); readers
|
|
135
|
-
* wanting all of them use {@link getFieldErrors}. */
|
|
136
|
-
errors: Map<string, FieldError[]>;
|
|
137
|
-
touched: Set<string>;
|
|
138
|
-
validators: Map<string, () => void>;
|
|
139
|
-
/** Change handlers published by mounted fields (`useField`): each is the
|
|
140
|
-
* field's own onChange — the write plus its mode/reValidateMode-gated
|
|
141
|
-
* validation kick. Path-based writes with user-change semantics
|
|
142
|
-
* ({@link changeValueByPath}) route through the registered handler; the
|
|
143
|
-
* effective per-field mode and live-error view live inside the field's
|
|
144
|
-
* closure, so this map is the only channel that can reproduce them.
|
|
145
|
-
* Multiple fields mounted at the same path compete for the slot
|
|
146
|
-
* last-wins — the latest mount's handler answers every user-change
|
|
147
|
-
* write; the unmount guard in `useField` keeps a later owner's
|
|
148
|
-
* registration intact when the earlier field goes away. */
|
|
149
|
-
changeHandlers: Map<string, (value: any) => void>;
|
|
150
|
-
validating: Set<string>;
|
|
151
|
-
/** Parsed values from the last successful schema validation: the
|
|
152
|
-
* schema's complete output tree (coerced/transformed values included).
|
|
153
|
-
* Sits between initialValues and the values Map in {@link getValues}
|
|
154
|
-
* until `reset`/`setInitialValues` clears it. Never affects dirty
|
|
155
|
-
* state — that compares live edits against initialValues only. */
|
|
156
|
-
parsedValues: T | undefined;
|
|
157
|
-
/** Form-level validator, seeded from {@link Options.validate}. May
|
|
158
|
-
* receive a second {@link FormValidateMeta} argument. */
|
|
159
|
-
validate?: FormValidateFn<T>;
|
|
160
|
-
/** Delay in milliseconds before the form-level `validate` runs; seeded
|
|
161
|
-
* from {@link Options.validateDebounce} and fixed at create time. */
|
|
162
|
-
validateDebounce?: number;
|
|
163
|
-
/** Path keys (JSON-stringified segments) of the fields whose user
|
|
164
|
-
* changes re-run the form-level `validate`; normalized from {@link
|
|
165
|
-
* Options.validateDeps} at create time and fixed thereafter. */
|
|
166
|
-
validateDeps?: ReadonlySet<string>;
|
|
167
|
-
isSubmitting: boolean;
|
|
168
|
-
submitCount: number;
|
|
169
|
-
isSubmitSuccessful: boolean | undefined;
|
|
170
|
-
/** Form-level disabled flag, OR-ed into every bound field's `disabled`
|
|
171
|
-
* (form flag || the field's own option). Seeded from
|
|
172
|
-
* {@link Options}.disabled at create time and toggled at runtime with
|
|
173
|
-
* {@link setDisabled}, which emits a payload-less 'disabled' event so
|
|
174
|
-
* subscribed fields re-render. */
|
|
175
|
-
disabled: boolean;
|
|
176
|
-
}
|
|
177
|
-
type Options<T extends Record<string, any> = any> = {
|
|
178
|
-
initialValues?: T;
|
|
179
|
-
/** When fields are validated. Defaults to `'onSubmit'`. See
|
|
180
|
-
* {@link ValidationMode}. */
|
|
181
|
-
mode?: ValidationMode;
|
|
182
|
-
/** When a field is re-validated after it already has an error — it only
|
|
183
|
-
* takes effect once the field has an error. Defaults to `'onChange'`. See
|
|
184
|
-
* {@link ReValidateMode}. */
|
|
185
|
-
reValidateMode?: ReValidateMode;
|
|
186
|
-
/**
|
|
187
|
-
* Form-level validator. Returns a record of errors keyed by field path;
|
|
188
|
-
* nested objects are flattened ('a.b' style) and array values contribute
|
|
189
|
-
* every non-empty string they hold as separate errors (zod `flatten()`
|
|
190
|
-
* formErrors style). Schema adapters instead return a branded
|
|
191
|
-
* {@link ValidationOutcome}: `errors` flattens the same way, `values`
|
|
192
|
-
* (the schema's parsed output) becomes the form's parsedValues baseline
|
|
193
|
-
* that {@link getValues} layers over initialValues.
|
|
194
|
-
*/
|
|
195
|
-
validate?: FormValidateFn<T>;
|
|
196
|
-
/**
|
|
197
|
-
* Milliseconds to debounce the form-level `validate`: kicks from
|
|
198
|
-
* `trigger`/`ensureValidate`/submit inside the window merge into one
|
|
199
|
-
* run, and while the timer is pending the form counts as validating,
|
|
200
|
-
* so `trigger` and submit wait the window out — the same contract the
|
|
201
|
-
* per-field `validateDebounce` gives field validators. The merged run
|
|
202
|
-
* reads the values current when its timer fires. Defaults to `0`
|
|
203
|
-
* (validate runs immediately, exactly as before this option existed).
|
|
204
|
-
*/
|
|
205
|
-
validateDebounce?: number;
|
|
206
|
-
/** Fields whose user changes re-run the form-level `validate` — the
|
|
207
|
-
* cross-field dependency list (password-confirm mismatch and friends).
|
|
208
|
-
* Each entry is a field path ('password', 'user.email', 'items.0.qty');
|
|
209
|
-
* a user change to a listed field re-runs the form-level `validate`
|
|
210
|
-
* under the same mode/`reValidateMode` gating the field's own
|
|
211
|
-
* validator gets. Omit it and the form-level `validate` only runs on
|
|
212
|
-
* `trigger`/submit, exactly as before this option existed.
|
|
213
|
-
*
|
|
214
|
-
* Opting in also changes what a re-run may clear: each round first
|
|
215
|
-
* drops the errors the previous round wrote (paths it flattened onto),
|
|
216
|
-
* so a dep change that fixes the cross-field error makes it disappear.
|
|
217
|
-
* Errors the round never wrote — field validators', `setServerErrors`,
|
|
218
|
-
* manual `setError` — are never touched. TanStack Form's counterpart is
|
|
219
|
-
* `onChangeListenTo` (v1) / validator `triggers` (v2 alpha). */
|
|
220
|
-
validateDeps?: FieldPath<T>[];
|
|
221
|
-
/** Start the form with every bound field disabled — the flag bound
|
|
222
|
-
* fields OR with their own `disabled` option (a field cannot opt out
|
|
223
|
-
* of a disabled form). Toggle later with {@link setDisabled}.
|
|
224
|
-
* Defaults to `false`. */
|
|
225
|
-
disabled?: boolean;
|
|
226
|
-
};
|
|
227
|
-
/**
|
|
228
|
-
* Create form instance
|
|
229
|
-
* @param options
|
|
230
|
-
* @return form instance
|
|
231
|
-
*/
|
|
232
|
-
declare function create<T extends Record<string, any> = any>(options?: Options<T>): Form<T>;
|
|
233
|
-
/**
|
|
234
|
-
* Get form values: the values Map layered over parsedValues (when a schema
|
|
235
|
-
* validation produced them) layered over initialValues.
|
|
236
|
-
*
|
|
237
|
-
* Merged with copy-on-write ownership tracking ({@link setOwned}): every
|
|
238
|
-
* distinct container on a written path is allocated once and shared by all
|
|
239
|
-
* paths through it, instead of re-copying the whole branch for every key.
|
|
240
|
-
* One owned set spans the whole merge, so containers borrowed from the
|
|
241
|
-
* parsedValues tree are copied before mutation exactly like initialValues
|
|
242
|
-
* ones. The result is a freshly merged tree per mutation, with untouched
|
|
243
|
-
* branches sharing references with the baseline exactly like chained
|
|
244
|
-
* `set` did.
|
|
245
|
-
*
|
|
246
|
-
* Memoized per form like {@link getDirtyFields}: every value write bumps a
|
|
247
|
-
* `version` counter ({@link bumpValuesVersion}) while reads reset it, so
|
|
248
|
-
* consecutive reads hand back the same reference (submit, changeValue and
|
|
249
|
-
* form-level validate all read the whole tree, often several times per
|
|
250
|
-
* interaction). Treat the result as read-only — the next read after a
|
|
251
|
-
* write returns a fresh tree, but between writes the cached one is shared
|
|
252
|
-
* with every other reader.
|
|
253
|
-
*
|
|
254
|
-
* parsedValues is the schema's complete output tree: once validation
|
|
255
|
-
* succeeds it replaces the initialValues baseline (fields the schema
|
|
256
|
-
* dropped disappear), while live edits in the values Map still win over
|
|
257
|
-
* both. It never affects dirty state — {@link isDirty} and
|
|
258
|
-
* {@link getDirtyFields} compare live edits against initialValues only,
|
|
259
|
-
* because parsing is not a user edit.
|
|
260
|
-
*
|
|
261
|
-
* @param form
|
|
262
|
-
*/
|
|
263
|
-
declare function getValues<T extends Record<string, any> = any>(form: Form<T>): T;
|
|
264
|
-
/**
|
|
265
|
-
* Get field value
|
|
266
|
-
* @param form
|
|
267
|
-
* @param name
|
|
268
|
-
*/
|
|
269
|
-
declare function getValue<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): PathValueOf<T, P>;
|
|
270
|
-
/**
|
|
271
|
-
* Get field value by path
|
|
272
|
-
* @param form
|
|
273
|
-
* @param path
|
|
274
|
-
*/
|
|
275
|
-
declare function getValueByPath({ initialValues, parsedValues, values, deleted }: Form, path: Path): any;
|
|
276
|
-
/** Options accepted by {@link setValue} / {@link setValueByPath} / {@link
|
|
277
|
-
* changeValue} / {@link changeValueByPath}. `shouldValidate`/`shouldTouch`
|
|
278
|
-
* default to `false`; omitting the options object entirely keeps the plain
|
|
279
|
-
* set-value behavior (no validation, no touched marking, dirty stays
|
|
280
|
-
* derived). */
|
|
281
|
-
interface SetFieldOptions {
|
|
282
|
-
/** Run the field's registered validator (if any) after the value lands,
|
|
283
|
-
* same as triggering that single field. Defaults to `false`. */
|
|
284
|
-
shouldValidate?: boolean;
|
|
285
|
-
/** Mark the field as touched. Defaults to `false`. */
|
|
286
|
-
shouldTouch?: boolean;
|
|
287
|
-
/** Land the value as a commit instead of an edit: the value becomes the
|
|
288
|
-
* field's dirty-comparison baseline, so `getDirtyFields`/`isDirty`/
|
|
289
|
-
* `getFieldState().isDirty` read the field as clean, and a later write
|
|
290
|
-
* dirties it only by differing from the new baseline. `true` (or
|
|
291
|
-
* omitting the flag) keeps the default derived behavior — dirty while
|
|
292
|
-
* the live value differs from initialValues. */
|
|
293
|
-
shouldDirty?: boolean;
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Set field value
|
|
297
|
-
* @param form
|
|
298
|
-
* @param name
|
|
299
|
-
* @param value
|
|
300
|
-
* @param options
|
|
301
|
-
*/
|
|
302
|
-
declare function setValue<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, value: PathValueOf<T, P>, options?: SetFieldOptions): void;
|
|
303
|
-
/**
|
|
304
|
-
* Set field value
|
|
305
|
-
* @param form
|
|
306
|
-
* @param path
|
|
307
|
-
* @param value
|
|
308
|
-
* @param options
|
|
309
|
-
*/
|
|
310
|
-
declare function setValueByPath(form: Form, path: Path, value: any, options?: SetFieldOptions): void;
|
|
311
|
-
/**
|
|
312
|
-
* The write of {@link setValueByPath} minus the `'change'` emit: the
|
|
313
|
-
* render-time {@link useField} `initialValue` seed. The field's first
|
|
314
|
-
* paint (SSR included — effects never run on the server) must already
|
|
315
|
-
* carry the value, so the write happens during render where emitting is
|
|
316
|
-
* illegal; the seeding field announces it from its post-commit effect
|
|
317
|
-
* through {@link emitChangeByPath} instead.
|
|
318
|
-
*
|
|
319
|
-
* Everything else matches a plain write: descendant keys of the seeded
|
|
320
|
-
* path are pruned, the branch's tombstones and committed baselines are
|
|
321
|
-
* revived/dropped, and both memo caches are invalidated. Like the effect
|
|
322
|
-
* seed it replaces, the caller guards it to paths with no value yet.
|
|
323
|
-
*/
|
|
324
|
-
declare function seedValueByPath(form: Form, path: Path, value: any): void;
|
|
325
|
-
/** Announce a {@link seedValueByPath} that happened during render: the
|
|
326
|
-
* payload-carrying `'change'` emit {@link setValueByPath} would have
|
|
327
|
-
* fired, split out so it can run post-commit where emitting is safe.
|
|
328
|
-
* Subscribers that rendered after the seed re-read an unchanged snapshot
|
|
329
|
-
* and bail; subscribers from earlier commits resync. */
|
|
330
|
-
declare function emitChangeByPath({ emitter }: Form, path: Path): void;
|
|
331
|
-
/**
|
|
332
|
-
* Set a field value as a user change.
|
|
333
|
-
*
|
|
334
|
-
* The write routes through the field's own onChange when one is mounted
|
|
335
|
-
* (registered by `useField`), so it fires exactly the validation a user
|
|
336
|
-
* typing into the field would fire: the field's effective `mode`
|
|
337
|
-
* (per-field override included) and the form's `reValidateMode`. With no
|
|
338
|
-
* mounted field on the path it degrades to a plain value set
|
|
339
|
-
* ({@link setValue}).
|
|
340
|
-
*
|
|
341
|
-
* This is the channel for component-library bridges that hand a control a
|
|
342
|
-
* plain setter bound to a field — they cannot rebuild the gating from
|
|
343
|
-
* public form state, because the per-field mode override and the
|
|
344
|
-
* live-error view that gates `reValidateMode` live inside the field's
|
|
345
|
-
* onChange closure.
|
|
346
|
-
*
|
|
347
|
-
* Contrast {@link setValue}: that is the imperative channel — its
|
|
348
|
-
* `shouldValidate` option kicks the field's validator unconditionally,
|
|
349
|
-
* ignoring any mode. Functional updaters are the caller's to evaluate
|
|
350
|
-
* ({@link getValue}).
|
|
351
|
-
*
|
|
352
|
-
* `options` carries the same {@link SetFieldOptions}: on the fallback path
|
|
353
|
-
* (no mounted field) they forward to {@link setValueByPath} wholesale,
|
|
354
|
-
* while on the mounted-field path only `shouldDirty: false` applies — the
|
|
355
|
-
* write lands as a commit while the field's own mode gating keeps driving
|
|
356
|
-
* validation, which is the point of this channel.
|
|
357
|
-
*
|
|
358
|
-
* @param form
|
|
359
|
-
* @param name
|
|
360
|
-
* @param value
|
|
361
|
-
* @param options
|
|
362
|
-
*/
|
|
363
|
-
declare function changeValue<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, value: PathValueOf<T, P>, options?: SetFieldOptions): void;
|
|
364
|
-
/**
|
|
365
|
-
* Set a field value as a user change, by parsed path
|
|
366
|
-
* @param form
|
|
367
|
-
* @param path
|
|
368
|
-
* @param value
|
|
369
|
-
* @param options
|
|
370
|
-
*/
|
|
371
|
-
declare function changeValueByPath(form: Form, path: Path, value: any, options?: SetFieldOptions): void;
|
|
372
|
-
/**
|
|
373
|
-
* Get field error
|
|
374
|
-
* @param form
|
|
375
|
-
* @param name
|
|
376
|
-
* @return FieldError object or undefined
|
|
377
|
-
*/
|
|
378
|
-
declare function getError<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): FieldError | undefined;
|
|
379
|
-
/**
|
|
380
|
-
* Get field error by path
|
|
381
|
-
* @param form
|
|
382
|
-
* @param path
|
|
383
|
-
* @return first FieldError of the field, or undefined
|
|
384
|
-
*/
|
|
385
|
-
declare function getErrorByPath({ errors }: Form, path: Path): FieldError | undefined;
|
|
386
|
-
/**
|
|
387
|
-
* Get all errors of a field
|
|
388
|
-
* @param form
|
|
389
|
-
* @param name
|
|
390
|
-
* @return every error registered for the field (insertion order); an empty
|
|
391
|
-
* array when the field has none
|
|
392
|
-
*/
|
|
393
|
-
declare function getFieldErrors<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): FieldError[];
|
|
394
|
-
/**
|
|
395
|
-
* Get all errors of a field by path
|
|
396
|
-
* @param form
|
|
397
|
-
* @param path
|
|
398
|
-
* @return every error registered for the field (insertion order); an empty
|
|
399
|
-
* array when the field has none
|
|
400
|
-
*/
|
|
401
|
-
declare function getFieldErrorsByPath({ errors }: Form, path: Path): FieldError[];
|
|
402
|
-
/**
|
|
403
|
-
* Get all errors
|
|
404
|
-
* @param form
|
|
405
|
-
* @return array of {path, type, message} entries, in insertion order; path
|
|
406
|
-
* is the user-facing dotted field path ('a.b', 'list.0'), and a
|
|
407
|
-
* field holding several errors contributes one entry per error
|
|
408
|
-
*/
|
|
409
|
-
declare function getErrors({ errors }: Form): FieldErrorEntry[];
|
|
410
|
-
/**
|
|
411
|
-
* Get first error message
|
|
412
|
-
* @param form
|
|
413
|
-
* @return first error's message string, or undefined when there are no errors
|
|
414
|
-
*/
|
|
415
|
-
declare function getFirstError({ errors }: Form): string | undefined;
|
|
416
|
-
/** Snapshot of one field's aggregated state, as {@link getFieldState}
|
|
417
|
-
* returns it. `errors` is the stored array shared with the form — treat it
|
|
418
|
-
* as read-only, like every {@link getFieldErrors} result. */
|
|
419
|
-
interface FieldState<T = any> {
|
|
420
|
-
value: T;
|
|
421
|
-
error: FieldError | undefined;
|
|
422
|
-
errors: FieldError[];
|
|
423
|
-
isDirty: boolean;
|
|
424
|
-
isTouched: boolean;
|
|
425
|
-
isValidating: boolean;
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Get one field's aggregated state: the layered value ({@link getValue}),
|
|
429
|
-
* the first error ({@link getError}) and every error ({@link
|
|
430
|
-
* getFieldErrors}), dirtiness, the touched flag, and whether a validator
|
|
431
|
-
* is in flight. `isDirty` applies the same per-field rule as {@link
|
|
432
|
-
* getDirtyFields}: a live value exists and differs from initialValues at
|
|
433
|
-
* that path (parsedValues never counts — parsing is not an edit).
|
|
434
|
-
*
|
|
435
|
-
* @param form
|
|
436
|
-
* @param name
|
|
437
|
-
*/
|
|
438
|
-
declare function getFieldState<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): FieldState<PathValueOf<T, P>>;
|
|
439
|
-
declare function unsetValidatingByPath({ emitter, validating }: Form, path: Path): void;
|
|
440
|
-
declare function setValidatingByPath({ emitter, validating }: Form, path: Path): void;
|
|
441
|
-
/**
|
|
442
|
-
* Set field error
|
|
443
|
-
* @param form
|
|
444
|
-
* @param name
|
|
445
|
-
* @param error string is normalized to {type: 'custom', message}; a
|
|
446
|
-
* FieldError object is stored as-is; an array holds several errors
|
|
447
|
-
* (falsy items dropped, strings normalized); undefined clears
|
|
448
|
-
*/
|
|
449
|
-
declare function setError<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, error: string | FieldError | (string | FieldError)[] | undefined): void;
|
|
450
|
-
/**
|
|
451
|
-
* Set field error
|
|
452
|
-
* @param form
|
|
453
|
-
* @param path
|
|
454
|
-
* @param error string is normalized to {type: 'custom', message}; a
|
|
455
|
-
* FieldError object is stored as-is; an array holds several errors
|
|
456
|
-
* (falsy items dropped, strings normalized); undefined clears
|
|
457
|
-
*/
|
|
458
|
-
declare function setErrorByPath({ emitter, errors }: Form, path: Path, error: string | FieldError | (string | FieldError)[] | undefined): void;
|
|
459
|
-
/**
|
|
460
|
-
* Clear errors
|
|
461
|
-
* @param form
|
|
462
|
-
* @param name a single path or a list of paths; omit to clear every error
|
|
463
|
-
*/
|
|
464
|
-
declare function clearErrors(form: Form, name?: Name | Name[]): void;
|
|
465
|
-
/** Options accepted by {@link setServerErrors}. */
|
|
466
|
-
interface SetServerErrorsOptions {
|
|
467
|
-
/** Keep existing field errors instead of clearing them first. Defaults
|
|
468
|
-
* to `false`: a fresh server response replaces the prior error state. */
|
|
469
|
-
keepExisting?: boolean;
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* Land a server-side error response on the form: each entry becomes the
|
|
473
|
-
* named field's error(s) with `type: 'server'`, ready for the same
|
|
474
|
-
* renderError/`useError` channel client-side validation uses. Takes the
|
|
475
|
-
* flat `Record<string, string | string[]>` shape REST APIs commonly
|
|
476
|
-
* return (RealWorld: `422 {errors: {email: ['has already been taken']}}`)
|
|
477
|
-
* without a hand-rolled `Object.entries` + `setError` loop.
|
|
478
|
-
*
|
|
479
|
-
* A string value lands as one error, a string array as several (first one
|
|
480
|
-
* is what `getError`/`error` expose); an empty array clears that field's
|
|
481
|
-
* errors. By default every existing error is cleared first — a fresh
|
|
482
|
-
* response describes the current state, not a patch onto stale client
|
|
483
|
-
* errors; pass `keepExisting: true` to layer instead.
|
|
484
|
-
* @param form
|
|
485
|
-
* @param errors field errors keyed by name
|
|
486
|
-
* @param options
|
|
487
|
-
*/
|
|
488
|
-
declare function setServerErrors(form: Form, errors: Record<string, string | string[]>, options?: SetServerErrorsOptions): void;
|
|
489
|
-
/**
|
|
490
|
-
* Set field touched state
|
|
491
|
-
* @param form
|
|
492
|
-
* @param name
|
|
493
|
-
*/
|
|
494
|
-
declare function setTouched(form: Form, name: Name): void;
|
|
495
|
-
/**
|
|
496
|
-
* Set field touched state
|
|
497
|
-
* @param form
|
|
498
|
-
* @param path
|
|
499
|
-
*/
|
|
500
|
-
declare function setTouchedByPath({ emitter, touched }: Form, path: Path): void;
|
|
501
|
-
/**
|
|
502
|
-
* Check if field has been touched
|
|
503
|
-
* @param form
|
|
504
|
-
* @param name
|
|
505
|
-
*/
|
|
506
|
-
declare function hasTouched<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): boolean;
|
|
507
|
-
/**
|
|
508
|
-
* Check if field has been touched
|
|
509
|
-
* @param form
|
|
510
|
-
* @param path
|
|
511
|
-
*/
|
|
512
|
-
declare function hasTouchedByPath({ touched }: Form, path: Path): boolean;
|
|
513
|
-
/**
|
|
514
|
-
* Is dirty -- any value differs from initialValues
|
|
515
|
-
* @param form
|
|
516
|
-
*/
|
|
517
|
-
declare function isDirty(form: Form): boolean;
|
|
518
|
-
/**
|
|
519
|
-
* Get dirty fields -- fields whose current value differs from initialValues.
|
|
520
|
-
* Keys are user-facing dotted paths ('a.b', 'a.0.c'), unlike the JSON array
|
|
521
|
-
* keys stored in the values Map.
|
|
522
|
-
* @param form
|
|
523
|
-
* @return object mapping each dirty field's dotted path to true; the same
|
|
524
|
-
* reference is returned until the dirty set actually changes
|
|
525
|
-
*/
|
|
526
|
-
declare function getDirtyFields(form: Form): Record<string, boolean>;
|
|
527
|
-
/**
|
|
528
|
-
* Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'), unlike
|
|
529
|
-
* the JSON array keys stored in the touched Set.
|
|
530
|
-
* @param form
|
|
531
|
-
* @return array of touched fields' dotted paths
|
|
532
|
-
*/
|
|
533
|
-
declare function getTouchedFields({ touched }: Form): string[];
|
|
534
|
-
/**
|
|
535
|
-
* Is touched -- any field has been touched
|
|
536
|
-
* @param form
|
|
537
|
-
*/
|
|
538
|
-
declare function isTouched({ touched }: Form): boolean;
|
|
539
|
-
/**
|
|
540
|
-
* Remove field
|
|
541
|
-
* @param form
|
|
542
|
-
* @param name
|
|
543
|
-
*/
|
|
544
|
-
declare function removeField(form: Form, name: Name): void;
|
|
545
|
-
/**
|
|
546
|
-
* Remove field
|
|
547
|
-
* @param form
|
|
548
|
-
* @param path
|
|
549
|
-
*/
|
|
550
|
-
declare function removeFieldByPath(form: Form, path: Path): void;
|
|
551
|
-
/**
|
|
552
|
-
* Set form initialValues
|
|
553
|
-
*
|
|
554
|
-
* Content-based early return: a new reference with equal content (the
|
|
555
|
-
* re-rendered inline literal) is a no-op, so committed edits survive, while
|
|
556
|
-
* genuinely changed content swaps the baseline and re-seeds — live values
|
|
557
|
-
* and tombstones are cleared, touched flags and errors survive.
|
|
558
|
-
* @param form
|
|
559
|
-
* @param initialValues
|
|
560
|
-
*/
|
|
561
|
-
declare function setInitialValues(form: Form, initialValues: any): void;
|
|
562
|
-
/** Options accepted by {@link reset}. Every flag defaults to `false` —
|
|
563
|
-
* omitting the object (or any flag) keeps the plain full-reset behavior.
|
|
564
|
-
* Names mirror react-hook-form's reset options to ease migration. */
|
|
565
|
-
interface ResetOptions {
|
|
566
|
-
/** Keep the current values of fields that are dirty — differ from the
|
|
567
|
-
* pre-reset initialValues (the same rule {@link getDirtyFields} applies).
|
|
568
|
-
* Clean fields fall back to the new initialValues as usual. */
|
|
569
|
-
keepDirtyValues?: boolean;
|
|
570
|
-
/** Keep the touched set instead of clearing it. */
|
|
571
|
-
keepTouched?: boolean;
|
|
572
|
-
/** Keep field errors instead of clearing them. */
|
|
573
|
-
keepErrors?: boolean;
|
|
574
|
-
/** Keep the submitted flag (`isSubmitSuccessful`) instead of clearing
|
|
575
|
-
* it. */
|
|
576
|
-
keepIsSubmitted?: boolean;
|
|
577
|
-
/** Keep `submitCount` instead of resetting it to 0. */
|
|
578
|
-
keepSubmitCount?: boolean;
|
|
579
|
-
/** Keep `isSubmitting` instead of resetting it to false. */
|
|
580
|
-
keepIsSubmitting?: boolean;
|
|
581
|
-
}
|
|
582
|
-
/**
|
|
583
|
-
* Reset form
|
|
584
|
-
* @param form
|
|
585
|
-
* @param initialValues
|
|
586
|
-
* @param options keep-flags to preserve slices of state through the reset
|
|
587
|
-
*/
|
|
588
|
-
declare function reset(form: Form, initialValues?: any, options?: ResetOptions): void;
|
|
589
|
-
/** Options accepted by {@link resetField}. The flags default to `false`;
|
|
590
|
-
* `value` has no default — omitted, the field falls back to initialValues;
|
|
591
|
-
* provided, the explicit value becomes the live value with no fallback at
|
|
592
|
-
* all. Mirrors react-hook-form's resetField options (`value` plays their
|
|
593
|
-
* `defaultValue`'s role) to ease migration. */
|
|
594
|
-
interface ResetFieldOptions {
|
|
595
|
-
/** Keep the field's touched flag instead of clearing it. */
|
|
596
|
-
keepTouched?: boolean;
|
|
597
|
-
/** Keep the field's errors instead of clearing them. */
|
|
598
|
-
keepErrors?: boolean;
|
|
599
|
-
/** Explicit post-reset value for the field — never falls back to
|
|
600
|
-
* initialValues. */
|
|
601
|
-
value?: any;
|
|
602
|
-
}
|
|
603
|
-
/**
|
|
604
|
-
* Reset a single field: drop its live value (reads fall back to the
|
|
605
|
-
* baseline — initialValues, or the schema's parsed output when one
|
|
606
|
-
* exists, in which case the path is removed from parsedValues and the
|
|
607
|
-
* initial value pinned back so the field reads initialValues again),
|
|
608
|
-
* clear its touched flag and errors, and revive the path's removal
|
|
609
|
-
* tombstones — the inverse of {@link removeFieldByPath}. Other fields
|
|
610
|
-
* and the submission flags are untouched; see {@link reset} for the
|
|
611
|
-
* form-wide counterpart.
|
|
612
|
-
*
|
|
613
|
-
* @param form
|
|
614
|
-
* @param name
|
|
615
|
-
* @param options
|
|
616
|
-
*/
|
|
617
|
-
declare function resetField<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, options?: ResetFieldOptions): void;
|
|
618
|
-
/**
|
|
619
|
-
* @param form
|
|
620
|
-
*/
|
|
621
|
-
declare function hasErrors({ errors }: Form): boolean;
|
|
622
|
-
/**
|
|
623
|
-
* Trigger field validation.
|
|
624
|
-
*
|
|
625
|
-
* Without `name` every registered field validator runs. A single `name` —
|
|
626
|
-
* dotted string or segments array — runs only that field's validator, and
|
|
627
|
-
* an array of names runs each one in order. An empty array is a no-op, as
|
|
628
|
-
* is any name with no registered validator. An array argument counts as
|
|
629
|
-
* one segments path only when it mixes in numbers (`['items', 0]`); pure
|
|
630
|
-
* string arrays are name lists, so `['a', 'b']` triggers fields `a` and
|
|
631
|
-
* `b`, not the nested path `a.b`.
|
|
632
|
-
*
|
|
633
|
-
* The returned promise waits for the triggered validation to settle —
|
|
634
|
-
* async validators included — so their errors have already landed in
|
|
635
|
-
* `form.errors` when it resolves. It never rejects: landing errors is the
|
|
636
|
-
* expected outcome here, not a failure. Resolves `true` when the triggered
|
|
637
|
-
* scope is error-free, `false` otherwise. Without `name` the scope is all
|
|
638
|
-
* fields plus the form-level `validate` result (which runs after field
|
|
639
|
-
* validators settle, same pipeline as {@link ensureValidate}); with `name`
|
|
640
|
-
* only those fields' own errors count and form-level `validate` is
|
|
641
|
-
* skipped (RHF semantics).
|
|
642
|
-
*
|
|
643
|
-
* Fire-and-forget callers may ignore the promise: the validator kicks
|
|
644
|
-
* still happen synchronously, matching the pre-promise behavior.
|
|
645
|
-
*
|
|
646
|
-
* @param form
|
|
647
|
-
* @param name field name(s) to trigger, or all fields when omitted
|
|
648
|
-
* @return whether the triggered scope is error-free once validation settles
|
|
649
|
-
*/
|
|
650
|
-
declare function trigger(form: Form, name?: Name | Name[]): Promise<boolean>;
|
|
651
|
-
/**
|
|
652
|
-
* Form-level twin of the gated validator kick in `useField`'s onChange:
|
|
653
|
-
* re-run the form-level `validate` after a user change to a field listed
|
|
654
|
-
* in `validateDeps`. Called from the field's own change pipeline (typing
|
|
655
|
-
* and `changeValue` alike — both route through the mounted field's
|
|
656
|
-
* onChange), so programmatic `setValue` writes do not re-run it, exactly
|
|
657
|
-
* like they do not re-run field validators.
|
|
658
|
-
*
|
|
659
|
-
* The gate mirrors the per-field matrix with the *changed field's*
|
|
660
|
-
* effective `mode` (a per-field override governs when its changes may
|
|
661
|
-
* fire validation) and the form-level `reValidateMode` against the last
|
|
662
|
-
* round's error footprint ({@link hasFormValidateErrors} — field
|
|
663
|
-
* validators' errors never arm this kick):
|
|
664
|
-
* - `mode` `'onChange'`/`'all'` — every dep change re-runs;
|
|
665
|
-
* - `mode` `'onTouched'` — dep changes re-run once the field was touched;
|
|
666
|
-
* - otherwise the re-run waits for `reValidateMode: 'onChange'` (the
|
|
667
|
-
* default) while the last round's error is still live — the
|
|
668
|
-
* submit-then-fix flow: the mismatch lands on submit, editing the
|
|
669
|
-
* dependency re-runs the validate and clears it.
|
|
670
|
-
* `reValidateMode: 'onBlur'`/`'onSubmit'` never re-run on a change (a
|
|
671
|
-
* change is not a blur; submit re-runs are the submit pipeline's job).
|
|
672
|
-
*
|
|
673
|
-
* The kick is fire-and-forget: async round rejections are swallowed
|
|
674
|
-
* (nothing in an event handler can await them), while a synchronous
|
|
675
|
-
* throw inside the validate callback propagates to the caller exactly
|
|
676
|
-
* like a field validator's does.
|
|
677
|
-
*
|
|
678
|
-
* A no-op unless the form set `validateDeps` listing `path` — forms
|
|
679
|
-
* without the option pay one property check here.
|
|
680
|
-
*/
|
|
681
|
-
declare function revalidateFormOnChange(form: Form, path: Path, mode: ValidationMode): void;
|
|
682
|
-
/** Register one field's validateDeps declaration: `key` re-validates when
|
|
683
|
-
* any path in `depKeys` takes a user change. Idempotent per (key, dep)
|
|
684
|
-
* pair, so StrictMode's double effect is harmless. */
|
|
685
|
-
declare function registerFieldValidateDeps(form: Form, key: string, depKeys: string[]): void;
|
|
686
|
-
/** Drop one field's validateDeps registration ({@link
|
|
687
|
-
* registerFieldValidateDeps}). Entries nobody lists anymore are removed so
|
|
688
|
-
* the registry never outlives its fields. */
|
|
689
|
-
declare function unregisterFieldValidateDeps(form: Form, key: string, depKeys: string[]): void;
|
|
690
|
-
/**
|
|
691
|
-
* Field-level twin of {@link revalidateFormOnChange}: after a user change
|
|
692
|
-
* to `path`, re-run every field validator that declared `path` in its
|
|
693
|
-
* `validateDeps` (useField option). Same channel, same gate: the kick
|
|
694
|
-
* rides the changed field's own onChange pipeline (typing and
|
|
695
|
-
* `changeValue` alike), so programmatic `setValue` writes never fire it —
|
|
696
|
-
* exactly like field validators and the form-level `validateDeps`.
|
|
697
|
-
*
|
|
698
|
-
* The gate mirrors the form-level matrix with the *changed field's*
|
|
699
|
-
* effective `mode` and the form-level `reValidateMode` against each
|
|
700
|
-
* dependent's live error:
|
|
701
|
-
* - `mode` `'onChange'`/`'all'` — every dep change re-runs the dependent;
|
|
702
|
-
* - `mode` `'onTouched'` — once the changed field was touched;
|
|
703
|
-
* - otherwise the re-run waits for `reValidateMode: 'onChange'` (the
|
|
704
|
-
* default) while the dependent still shows an error — the
|
|
705
|
-
* submit-then-fix flow: the mismatch lands on submit, editing the
|
|
706
|
-
* dependency re-validates the dependent and a passing round clears it
|
|
707
|
-
* (a field validator owns its whole key, so the re-run's result
|
|
708
|
-
* replaces whatever the previous round wrote — the field-level shape
|
|
709
|
-
* of the form-level footprint reclaim).
|
|
710
|
-
*
|
|
711
|
-
* The kick is an ordinary validator kick: the dependent's own
|
|
712
|
-
* `validateDebounce` window applies, and a synchronous throw inside its
|
|
713
|
-
* validate propagates to the caller like any field validator's would.
|
|
714
|
-
*
|
|
715
|
-
* A no-op unless some field declared `path` as a dep — forms without any
|
|
716
|
-
* field-level `validateDeps` pay one property check here.
|
|
717
|
-
*/
|
|
718
|
-
declare function revalidateDependentsOnChange(form: Form, path: Path, mode: ValidationMode): void;
|
|
719
|
-
/** The Error {@link ensureValidate} rejects with: `message` is the first
|
|
720
|
-
* error's display text ({@link getFirstError}) — the long-standing shape
|
|
721
|
-
* — and `.errors` carries the complete flattened error list ({@link
|
|
722
|
-
* getErrors}: `{path, type, message}` entries, dotted display paths) so
|
|
723
|
-
* catchers can branch on types and locate fields without re-reading the
|
|
724
|
-
* form. */
|
|
725
|
-
type FormValidationError = Error & {
|
|
726
|
-
errors: FieldErrorEntry[];
|
|
727
|
-
};
|
|
728
|
-
/**
|
|
729
|
-
* Validate and throw if any field error.
|
|
730
|
-
* @param form
|
|
731
|
-
* @return resolve if no error; reject and stop validate if has an error
|
|
732
|
-
*/
|
|
733
|
-
declare function ensureValidate(form: Form): Promise<void>;
|
|
734
|
-
/**
|
|
735
|
-
* Validate and return if any field error.
|
|
736
|
-
* @param form
|
|
737
|
-
* @return error message string or void
|
|
738
|
-
*/
|
|
739
|
-
declare function validate(form: Form): Promise<void | string>;
|
|
740
|
-
declare function setIsSubmitting(form: Form, value: boolean): void;
|
|
741
|
-
declare function incrementSubmitCount(form: Form): void;
|
|
742
|
-
declare function setSubmitSuccessful(form: Form, value: boolean): void;
|
|
743
|
-
/**
|
|
744
|
-
* Set the form-level disabled flag and emit a payload-less 'disabled'
|
|
745
|
-
* event — subscribed fields (useField and the components built on it)
|
|
746
|
-
* re-render with the merged disabled state: form flag || their own
|
|
747
|
-
* `disabled` option.
|
|
748
|
-
* @param form
|
|
749
|
-
* @param value
|
|
750
|
-
*/
|
|
751
|
-
declare function setDisabled(form: Form, value: boolean): void;
|
|
752
|
-
/** Submit callbacks for {@link handleSubmit}. All optional — a missing
|
|
753
|
-
* callback is simply skipped, matching the <Form> component semantics. */
|
|
754
|
-
interface HandleSubmitOptions<T extends Record<string, any> = any> {
|
|
755
|
-
/** Called after validation passes, before onValidSubmit. */
|
|
756
|
-
onSubmit?: (values: T, e?: any) => void | Promise<void>;
|
|
757
|
-
/** Called after validation passes, following a successful onSubmit. */
|
|
758
|
-
onValidSubmit?: (values: T, e?: any) => void | Promise<void>;
|
|
759
|
-
/**
|
|
760
|
-
* Called when validation fails.
|
|
761
|
-
* @param errors array of {path, type, message} entries in insertion
|
|
762
|
-
* order; path is the dotted field path ('a.b', 'list.0'), type is
|
|
763
|
-
* the error kind ('custom' for plain string errors, 'native' for
|
|
764
|
-
* failed DOM constraint validation), message is the display text
|
|
765
|
-
* @param values current form values
|
|
766
|
-
*/
|
|
767
|
-
onInvalidSubmit?: (errors: FieldErrorEntry[], values: T) => void;
|
|
768
|
-
/**
|
|
769
|
-
* Focus the first error field after a failed submit. Defaults to true —
|
|
770
|
-
* only an explicit `false` disables it. When custom validation fails,
|
|
771
|
-
* a 'focusError' event carrying the first error's path key is emitted
|
|
772
|
-
* on the form (bound fields such as <Field> subscribe and focus their
|
|
773
|
-
* input); when native constraint validation fails, the submitted
|
|
774
|
-
* form's first ':invalid' control is focused directly.
|
|
775
|
-
*/
|
|
776
|
-
shouldFocusError?: boolean;
|
|
777
|
-
}
|
|
778
|
-
/**
|
|
779
|
-
* Create an async submit handler for `form` — the headless counterpart of
|
|
780
|
-
* the <Form> component's onSubmit wiring.
|
|
781
|
-
*
|
|
782
|
-
* Behavior mirrors <Form> exactly: preventDefault when present, then the
|
|
783
|
-
* submit state machine (isSubmitting/submitCount/isSubmitSuccessful) runs
|
|
784
|
-
* around native constraint validation (via `e.currentTarget.checkValidity`,
|
|
785
|
-
* skipped when the target has no checkValidity — e.g. React Native or
|
|
786
|
-
* toolbar-button submits) and custom validators. Failed validation fires
|
|
787
|
-
* onInvalidSubmit with the flattened error entries; a passing submit runs
|
|
788
|
-
* onSubmit then onValidSubmit. Errors thrown by either are swallowed into
|
|
789
|
-
* isSubmitSuccessful=false rather than rejecting the returned promise.
|
|
790
|
-
* Failed validation also focuses the offending field (see
|
|
791
|
-
* {@link HandleSubmitOptions.shouldFocusError}).
|
|
792
|
-
*
|
|
793
|
-
* @param form form instance
|
|
794
|
-
* @param options submit callbacks
|
|
795
|
-
* @return async event handler, callable without an event object
|
|
796
|
-
*/
|
|
797
|
-
declare function handleSubmit<T extends Record<string, any> = any>(form: Form<T>, options?: HandleSubmitOptions<T>): (e?: {
|
|
798
|
-
preventDefault?: () => void;
|
|
799
|
-
currentTarget?: any;
|
|
800
|
-
}) => Promise<void>;
|
|
801
|
-
/** Options accepted by {@link setFocus}. All flags default to `false`. */
|
|
802
|
-
interface SetFocusOptions {
|
|
803
|
-
/** Select the field's text after focusing it. Bound fields call
|
|
804
|
-
* `select()` on their element; elements without one (custom `as`
|
|
805
|
-
* components) just focus. */
|
|
806
|
-
shouldSelect?: boolean;
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* Programmatically focus a bound field's element (e.g. the <Field>'s
|
|
810
|
-
* input).
|
|
811
|
-
*
|
|
812
|
-
* Rides the same 'focusError' event channel a failed handleSubmit uses to
|
|
813
|
-
* focus the first errored field: the payload is the target's path key,
|
|
814
|
-
* with the focus options as a second, backward-compatible argument (older
|
|
815
|
-
* subscribers declared with a single `key` parameter simply ignore it).
|
|
816
|
-
* Being event-driven, it is a silent no-op when the field is unmounted or
|
|
817
|
-
* nothing subscribes — unknown names never throw.
|
|
818
|
-
*
|
|
819
|
-
* @param form form instance
|
|
820
|
-
* @param name field name (dot path or segments path)
|
|
821
|
-
* @param options focus options
|
|
822
|
-
*/
|
|
823
|
-
declare function setFocus(form: Form, name: Name, options?: SetFocusOptions): void;
|
|
824
|
-
|
|
825
|
-
export { resetField as $, getFieldErrors as A, getFieldErrorsByPath as B, getFieldState as C, getFirstError as D, getTouchedFields as E, getValue as G, getValueByPath as I, getValues as J, handleSubmit as K, hasErrors as L, hasTouched as M, hasTouchedByPath as Q, incrementSubmitCount as T, isDirty as U, isTouched as W, registerFieldValidateDeps as X, removeField as Y, removeFieldByPath as Z, reset as _, revalidateDependentsOnChange as a0, revalidateFormOnChange as a1, seedValueByPath as a2, setDisabled as a3, setError as a4, setErrorByPath as a5, setFocus as a6, setInitialValues as a7, setIsSubmitting as a8, setServerErrors as a9, setSubmitSuccessful as aa, setTouched as ab, setTouchedByPath as ac, setValidatingByPath as ad, setValue as ae, setValueByPath as af, trigger as ag, unregisterFieldValidateDeps as ah, unsetValidatingByPath as ai, validate as aj, VALIDATION_OUTCOME as n, changeValue as q, changeValueByPath as r, clearErrors as s, create as t, emitChangeByPath as u, ensureValidate as v, getDirtyFields as w, getError as x, getErrorByPath as y, getErrors as z };
|
|
826
|
-
export type { Form as F, HandleSubmitOptions as H, Name as N, Options as O, PathValueOf as P, ReValidateMode as R, SetFieldOptions as S, ValidationMode as V, FieldPath as a, FieldError as b, Path as c, FieldErrorEntry as d, FieldState as e, FormValidateFn as f, FormValidateMeta as g, FormValidationError as h, PathValue as i, ResetFieldOptions as j, ResetOptions as k, SetFocusOptions as l, SetServerErrorsOptions as m, ValidateResult as o, ValidationOutcome as p };
|