react-f0rm 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +573 -33
  2. package/dist/devtools/index.cjs.js +737 -0
  3. package/dist/devtools/index.cjs.js.map +1 -0
  4. package/dist/devtools/index.d.ts +33 -0
  5. package/dist/devtools/index.mjs +717 -0
  6. package/dist/devtools/index.mjs.map +1 -0
  7. package/dist/form-61297bc0.d.ts +578 -0
  8. package/dist/form-94c70b4b.mjs +378 -0
  9. package/dist/form-94c70b4b.mjs.map +1 -0
  10. package/dist/form-b9441d8c.cjs.js +387 -0
  11. package/dist/form-b9441d8c.cjs.js.map +1 -0
  12. package/dist/index.cjs.js +1265 -157
  13. package/dist/index.cjs.js.map +1 -1
  14. package/dist/index.d.ts +419 -59
  15. package/dist/index.mjs +1684 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/index.umd.js +1265 -157
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/index.umd.min.js +2 -2
  20. package/dist/index.umd.min.js.map +1 -1
  21. package/dist/resolvers/standard-schema.cjs.js +90 -0
  22. package/dist/resolvers/standard-schema.cjs.js.map +1 -0
  23. package/dist/resolvers/standard-schema.d.ts +66 -0
  24. package/dist/resolvers/standard-schema.mjs +86 -0
  25. package/dist/resolvers/standard-schema.mjs.map +1 -0
  26. package/dist/resolvers/yup.cjs.js +12 -2
  27. package/dist/resolvers/yup.cjs.js.map +1 -1
  28. package/dist/resolvers/yup.d.ts +2 -2
  29. package/dist/resolvers/yup.mjs +23 -0
  30. package/dist/resolvers/yup.mjs.map +1 -0
  31. package/dist/resolvers/zod.cjs.js +14 -1
  32. package/dist/resolvers/zod.cjs.js.map +1 -1
  33. package/dist/resolvers/zod.d.ts +2 -2
  34. package/dist/resolvers/zod.mjs +23 -0
  35. package/dist/resolvers/zod.mjs.map +1 -0
  36. package/dist/validate-148fe167.d.ts +22 -0
  37. package/package.json +34 -8
  38. package/dist/form-d06e6444.d.ts +0 -201
  39. package/dist/index.esm.js +0 -593
  40. package/dist/index.esm.js.map +0 -1
  41. package/dist/resolvers/yup.esm.js +0 -13
  42. package/dist/resolvers/yup.esm.js.map +0 -1
  43. package/dist/resolvers/zod.esm.js +0 -10
  44. package/dist/resolvers/zod.esm.js.map +0 -1
  45. package/dist/validate-0f17f86a.d.ts +0 -8
@@ -0,0 +1,578 @@
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.0.b', '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
+ */
16
+ /** `true` only for the `any` type (`0 extends 1 & any`). */
17
+ type IsAny<T> = 0 extends 1 & T ? true : false;
18
+ type Primitive = null | undefined | string | number | boolean | symbol | bigint;
19
+ /** Depth countdown: Prev[9] = 8 ... Prev[1] = 0, Prev[0] = never stops recursion. */
20
+ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
21
+ /** Paths are capped at 10 segments to keep instantiation depth bounded. */
22
+ type MaxDepth = 9;
23
+ /**
24
+ * Valid path continuations after a segment: `.k` / `.0` / `[k]` / `[0]`,
25
+ * optionally followed by deeper continuations into the child node.
26
+ */
27
+ 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}]` | `.${number}${Continue<U, Prev[D]>}` | `[${number}]${Continue<U, Prev[D]>}` : {
28
+ [K in Extract<keyof T, string>]: `.${K}` | `[${K}]` | `.${K}${Continue<T[K], Prev[D]>}` | `[${K}]${Continue<T[K], Prev[D]>}`;
29
+ }[Extract<keyof T, string>];
30
+ /**
31
+ * Every valid field path string for a values shape `T`.
32
+ * @example FieldPath<{a: {b: string}}> // 'a' | 'a.b' | 'a[b]'
33
+ */
34
+ type FieldPath<T> = IsAny<T> extends true ? string : T extends Primitive | Function ? never : T extends readonly (infer U)[] ? `${number}` | `${number}${Continue<U, MaxDepth>}` : {
35
+ [K in Extract<keyof T, string>]: K | `${K}${Continue<T[K], MaxDepth>}`;
36
+ }[Extract<keyof T, string>];
37
+ /** Resolve `T[K]` for one bare segment: array index -> element, object key -> value. */
38
+ type Lookup<T, K extends string> = K extends `${number}` ? T extends readonly (infer U)[] ? U : never : K extends keyof T ? T[K] : never;
39
+ /** One dot-separated chunk: a bare segment plus any `[k]` / `[0]` suffixes. */
40
+ type ChunkValue<T, C extends string> = C extends `${infer Key}[${infer Tail}` ? ChunkSuffix<Lookup<T, Key>, `[${Tail}`> : Lookup<T, C>;
41
+ type ChunkSuffix<T, S extends string> = S extends `[${infer Key}]${infer Rest}` ? Rest extends '' ? Lookup<T, Key> : PathOf<Lookup<T, Key>, Rest> : never;
42
+ /** Resolve the value type the path string `P` points at inside `T`. */
43
+ 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>;
44
+ /**
45
+ * The value type at path `P` of a values shape `T`.
46
+ * @example PathValue<{a: {b: string}}, 'a.b'> // string
47
+ */
48
+ type PathValue<T, P extends FieldPath<T>> = PathOf<T, P & string>;
49
+ /**
50
+ * The value type at path `P` of `T`, or `any` when `P` is not a known
51
+ * field path (plain `string` / segment-array calls keep their old behavior).
52
+ */
53
+ type PathValueOf<T, P> = P extends FieldPath<T> ? PathValue<T, Extract<P, FieldPath<T>>> : any;
54
+
55
+ /** A field error: `type` identifies the error kind ('custom' for plain
56
+ * string errors), `message` is the display text. */
57
+ interface FieldError {
58
+ type: string;
59
+ message: string;
60
+ }
61
+ /** A flattened entry from {@link getErrors}. */
62
+ type FieldErrorEntry = {
63
+ path: string;
64
+ type: string;
65
+ message: string;
66
+ };
67
+ /** When a field is validated:
68
+ * - `'onSubmit'` (default): only on submit
69
+ * - `'onBlur'`: when the field loses focus
70
+ * - `'onChange'`: on every change
71
+ * - `'onTouched'`: on first blur, then on every change
72
+ * - `'all'`: on both change and blur
73
+ */
74
+ type ValidationMode = 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all';
75
+ /** When a field is re-validated after it already has an error:
76
+ * - `'onChange'` (default): on every change
77
+ * - `'onBlur'`: when the field loses focus
78
+ * - `'onSubmit'`: only on submit (no live re-validation)
79
+ */
80
+ type ReValidateMode = 'onChange' | 'onBlur' | 'onSubmit';
81
+ /** Brand marking a form-level validate result as a structured
82
+ * {@link ValidationOutcome} (parsed values and/or errors) rather than a
83
+ * plain nested error record. Symbols cannot collide with user error
84
+ * records, so detection is an exact `VALIDATION_OUTCOME in result`. */
85
+ declare const VALIDATION_OUTCOME: unique symbol;
86
+ /** Structured form-level validate result: `errors` uses the same nested
87
+ * shape a plain error record uses, `values` is the schema's parsed output
88
+ * (coerce/transform results included). Either side may be omitted. */
89
+ type ValidationOutcome<T> = {
90
+ [VALIDATION_OUTCOME]: true;
91
+ errors?: Record<string, any>;
92
+ values?: T;
93
+ };
94
+ /** What a form-level validate function may return: a plain nested error
95
+ * record (flattened into field errors — the long-standing shape), or a
96
+ * branded {@link ValidationOutcome} whose `values` become the form's
97
+ * parsedValues baseline. */
98
+ type ValidateResult<T> = Record<string, any> | ValidationOutcome<T> | Promise<Record<string, any> | ValidationOutcome<T>>;
99
+ interface Form<T extends Record<string, any> = any> {
100
+ emitter: EventEmitter;
101
+ mode: ValidationMode;
102
+ reValidateMode: ReValidateMode;
103
+ initialValues: T;
104
+ values: Map<string, any>;
105
+ /** Tombstones of unregistered field paths (JSON path keys): reading or
106
+ * merging values must not fall back to initialValues for these paths. */
107
+ deleted: Set<string>;
108
+ /** Every error registered for a field, as a non-empty array (the
109
+ * write-side {@link setErrorByPath} normalizes to this invariant, so
110
+ * readers never need to guard against an empty list). Readers wanting
111
+ * the display error take the first entry ({@link getError}); readers
112
+ * wanting all of them use {@link getFieldErrors}. */
113
+ errors: Map<string, FieldError[]>;
114
+ touched: Set<string>;
115
+ validators: Map<string, () => void>;
116
+ validating: Set<string>;
117
+ /** Parsed values from the last successful schema validation: the
118
+ * schema's complete output tree (coerced/transformed values included).
119
+ * Sits between initialValues and the values Map in {@link getValues}
120
+ * until `reset`/`setInitialValues` clears it. Never affects dirty
121
+ * state — that compares live edits against initialValues only. */
122
+ parsedValues: T | undefined;
123
+ validate?: (values: T) => ValidateResult<T>;
124
+ isSubmitting: boolean;
125
+ submitCount: number;
126
+ isSubmitSuccessful: boolean | undefined;
127
+ /** Form-level disabled flag, OR-ed into every bound field's `disabled`
128
+ * (form flag || the field's own option). Seeded from
129
+ * {@link Options}.disabled at create time and toggled at runtime with
130
+ * {@link setDisabled}, which emits a payload-less 'disabled' event so
131
+ * subscribed fields re-render. */
132
+ disabled: boolean;
133
+ }
134
+ type Options<T extends Record<string, any> = any> = {
135
+ initialValues?: T;
136
+ /** When fields are validated. Defaults to `'onSubmit'`. See
137
+ * {@link ValidationMode}. */
138
+ mode?: ValidationMode;
139
+ /** When a field is re-validated after it already has an error — it only
140
+ * takes effect once the field has an error. Defaults to `'onChange'`. See
141
+ * {@link ReValidateMode}. */
142
+ reValidateMode?: ReValidateMode;
143
+ /**
144
+ * Form-level validator. Returns a record of errors keyed by field path;
145
+ * nested objects are flattened ('a.b' style) and array values contribute
146
+ * every non-empty string they hold as separate errors (zod `flatten()`
147
+ * formErrors style). Schema adapters instead return a branded
148
+ * {@link ValidationOutcome}: `errors` flattens the same way, `values`
149
+ * (the schema's parsed output) becomes the form's parsedValues baseline
150
+ * that {@link getValues} layers over initialValues.
151
+ */
152
+ validate?: (values: T) => ValidateResult<T>;
153
+ /** Start the form with every bound field disabled — the flag bound
154
+ * fields OR with their own `disabled` option (a field cannot opt out
155
+ * of a disabled form). Toggle later with {@link setDisabled}.
156
+ * Defaults to `false`. */
157
+ disabled?: boolean;
158
+ };
159
+ /**
160
+ * Create form instance
161
+ * @param options
162
+ * @return form instance
163
+ */
164
+ declare function create<T extends Record<string, any> = any>(options?: Options<T>): Form<T>;
165
+ /**
166
+ * Get form values: the values Map layered over parsedValues (when a schema
167
+ * validation produced them) layered over initialValues.
168
+ *
169
+ * Merged with copy-on-write ownership tracking ({@link setOwned}): every
170
+ * distinct container on a written path is allocated once and shared by all
171
+ * paths through it, instead of re-copying the whole branch for every key.
172
+ * One owned set spans the whole merge, so containers borrowed from the
173
+ * parsedValues tree are copied before mutation exactly like initialValues
174
+ * ones. The result is still a freshly merged tree per call, with untouched
175
+ * branches sharing references with the baseline exactly like chained
176
+ * `set` did -- callers may treat it as their own copy.
177
+ *
178
+ * parsedValues is the schema's complete output tree: once validation
179
+ * succeeds it replaces the initialValues baseline (fields the schema
180
+ * dropped disappear), while live edits in the values Map still win over
181
+ * both. It never affects dirty state — {@link isDirty} and
182
+ * {@link getDirtyFields} compare live edits against initialValues only,
183
+ * because parsing is not a user edit.
184
+ *
185
+ * @param form
186
+ */
187
+ declare function getValues<T extends Record<string, any> = any>(form: Form<T>): T;
188
+ /**
189
+ * Get field value
190
+ * @param form
191
+ * @param name
192
+ */
193
+ declare function getValue<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): PathValueOf<T, P>;
194
+ /**
195
+ * Get field value by path
196
+ * @param form
197
+ * @param path
198
+ */
199
+ declare function getValueByPath({ initialValues, parsedValues, values, deleted }: Form, path: Path): any;
200
+ /** Options accepted by {@link setValue} / {@link setValueByPath}. Every flag
201
+ * defaults to `false`; omitting the options object entirely keeps the plain
202
+ * set-value behavior (no validation, no touched marking). */
203
+ interface SetFieldOptions {
204
+ /** Run the field's registered validator (if any) after the value lands,
205
+ * same as triggering that single field. Defaults to `false`. */
206
+ shouldValidate?: boolean;
207
+ /** Mark the field as touched. Defaults to `false`. */
208
+ shouldTouch?: boolean;
209
+ /** Reserved for a future manual dirty marker. Dirty state is currently
210
+ * derived from comparing values against initialValues, so this flag is
211
+ * accepted but does nothing. Defaults to `false`. */
212
+ shouldDirty?: boolean;
213
+ }
214
+ /**
215
+ * Set field value
216
+ * @param form
217
+ * @param name
218
+ * @param value
219
+ * @param options
220
+ */
221
+ 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;
222
+ /**
223
+ * Set field value
224
+ * @param form
225
+ * @param path
226
+ * @param value
227
+ * @param options
228
+ */
229
+ declare function setValueByPath(form: Form, path: Path, value: any, options?: SetFieldOptions): void;
230
+ /**
231
+ * Get field error
232
+ * @param form
233
+ * @param name
234
+ * @return FieldError object or undefined
235
+ */
236
+ declare function getError<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): FieldError | undefined;
237
+ /**
238
+ * Get field error by path
239
+ * @param form
240
+ * @param path
241
+ * @return first FieldError of the field, or undefined
242
+ */
243
+ declare function getErrorByPath({ errors }: Form, path: Path): FieldError | undefined;
244
+ /**
245
+ * Get all errors of a field
246
+ * @param form
247
+ * @param name
248
+ * @return every error registered for the field (insertion order); an empty
249
+ * array when the field has none
250
+ */
251
+ declare function getFieldErrors<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): FieldError[];
252
+ /**
253
+ * Get all errors of a field by path
254
+ * @param form
255
+ * @param path
256
+ * @return every error registered for the field (insertion order); an empty
257
+ * array when the field has none
258
+ */
259
+ declare function getFieldErrorsByPath({ errors }: Form, path: Path): FieldError[];
260
+ /**
261
+ * Get all errors
262
+ * @param form
263
+ * @return array of {path, type, message} entries, in insertion order; path
264
+ * is the user-facing dotted field path ('a.b', 'list.0'), and a
265
+ * field holding several errors contributes one entry per error
266
+ */
267
+ declare function getErrors({ errors }: Form): FieldErrorEntry[];
268
+ /**
269
+ * Get first error message
270
+ * @param form
271
+ * @return first error's message string, or undefined when there are no errors
272
+ */
273
+ declare function getFirstError({ errors }: Form): string | undefined;
274
+ /** Snapshot of one field's aggregated state, as {@link getFieldState}
275
+ * returns it. `errors` is the stored array shared with the form — treat it
276
+ * as read-only, like every {@link getFieldErrors} result. */
277
+ interface FieldState<T = any> {
278
+ value: T;
279
+ error: FieldError | undefined;
280
+ errors: FieldError[];
281
+ isDirty: boolean;
282
+ isTouched: boolean;
283
+ isValidating: boolean;
284
+ }
285
+ /**
286
+ * Get one field's aggregated state: the layered value ({@link getValue}),
287
+ * the first error ({@link getError}) and every error ({@link
288
+ * getFieldErrors}), dirtiness, the touched flag, and whether a validator
289
+ * is in flight. `isDirty` applies the same per-field rule as {@link
290
+ * getDirtyFields}: a live value exists and differs from initialValues at
291
+ * that path (parsedValues never counts — parsing is not an edit).
292
+ *
293
+ * @param form
294
+ * @param name
295
+ */
296
+ declare function getFieldState<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): FieldState<PathValueOf<T, P>>;
297
+ declare function unsetValidatingByPath({ emitter, validating }: Form, path: Path): void;
298
+ declare function setValidatingByPath({ emitter, validating }: Form, path: Path): void;
299
+ /**
300
+ * Set field error
301
+ * @param form
302
+ * @param name
303
+ * @param error string is normalized to {type: 'custom', message}; a
304
+ * FieldError object is stored as-is; an array holds several errors
305
+ * (falsy items dropped, strings normalized); undefined clears
306
+ */
307
+ 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;
308
+ /**
309
+ * Set field error
310
+ * @param form
311
+ * @param path
312
+ * @param error string is normalized to {type: 'custom', message}; a
313
+ * FieldError object is stored as-is; an array holds several errors
314
+ * (falsy items dropped, strings normalized); undefined clears
315
+ */
316
+ declare function setErrorByPath({ emitter, errors }: Form, path: Path, error: string | FieldError | (string | FieldError)[] | undefined): void;
317
+ /**
318
+ * Clear errors
319
+ * @param form
320
+ * @param name a single path or a list of paths; omit to clear every error
321
+ */
322
+ declare function clearErrors(form: Form, name?: Name | Name[]): void;
323
+ /**
324
+ * Set field touched state
325
+ * @param form
326
+ * @param name
327
+ */
328
+ declare function setTouched(form: Form, name: Name): void;
329
+ /**
330
+ * Set field touched state
331
+ * @param form
332
+ * @param path
333
+ */
334
+ declare function setTouchedByPath({ emitter, touched }: Form, path: Path): void;
335
+ /**
336
+ * Check if field has been touched
337
+ * @param form
338
+ * @param name
339
+ */
340
+ declare function hasTouched<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P): boolean;
341
+ /**
342
+ * Check if field has been touched
343
+ * @param form
344
+ * @param path
345
+ */
346
+ declare function hasTouchedByPath({ touched }: Form, path: Path): boolean;
347
+ /**
348
+ * Is dirty -- any value differs from initialValues
349
+ * @param form
350
+ */
351
+ declare function isDirty(form: Form): boolean;
352
+ /**
353
+ * Get dirty fields -- fields whose current value differs from initialValues.
354
+ * Keys are user-facing dotted paths ('a.b', 'a.0.c'), unlike the JSON array
355
+ * keys stored in the values Map.
356
+ * @param form
357
+ * @return object mapping each dirty field's dotted path to true; the same
358
+ * reference is returned until the dirty set actually changes
359
+ */
360
+ declare function getDirtyFields(form: Form): Record<string, boolean>;
361
+ /**
362
+ * Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'), unlike
363
+ * the JSON array keys stored in the touched Set.
364
+ * @param form
365
+ * @return array of touched fields' dotted paths
366
+ */
367
+ declare function getTouchedFields({ touched }: Form): string[];
368
+ /**
369
+ * Is touched -- any field has been touched
370
+ * @param form
371
+ */
372
+ declare function isTouched({ touched }: Form): boolean;
373
+ /**
374
+ * Remove field
375
+ * @param form
376
+ * @param name
377
+ */
378
+ declare function removeField(form: Form, name: Name): void;
379
+ /**
380
+ * Remove field
381
+ * @param form
382
+ * @param path
383
+ */
384
+ declare function removeFieldByPath(form: Form, { key, value: segments }: Path): void;
385
+ /**
386
+ * Set form initialValues
387
+ * @param form
388
+ * @param initialValues
389
+ */
390
+ declare function setInitialValues(form: Form, initialValues: any): void;
391
+ /** Options accepted by {@link reset}. Every flag defaults to `false` —
392
+ * omitting the object (or any flag) keeps the plain full-reset behavior.
393
+ * Names mirror react-hook-form's reset options to ease migration. */
394
+ interface ResetOptions {
395
+ /** Keep the current values of fields that are dirty — differ from the
396
+ * pre-reset initialValues (the same rule {@link getDirtyFields} applies).
397
+ * Clean fields fall back to the new initialValues as usual. */
398
+ keepDirtyValues?: boolean;
399
+ /** Keep the touched set instead of clearing it. */
400
+ keepTouched?: boolean;
401
+ /** Keep field errors instead of clearing them. */
402
+ keepErrors?: boolean;
403
+ /** Keep the submitted flag (`isSubmitSuccessful`) instead of clearing
404
+ * it. */
405
+ keepIsSubmitted?: boolean;
406
+ /** Keep `submitCount` instead of resetting it to 0. */
407
+ keepSubmitCount?: boolean;
408
+ /** Keep `isSubmitting` instead of resetting it to false. */
409
+ keepIsSubmitting?: boolean;
410
+ }
411
+ /**
412
+ * Reset form
413
+ * @param form
414
+ * @param initialValues
415
+ * @param options keep-flags to preserve slices of state through the reset
416
+ */
417
+ declare function reset(form: Form, initialValues?: any, options?: ResetOptions): void;
418
+ /** Options accepted by {@link resetField}. The flags default to `false`;
419
+ * `value` has no default — omitted, the field falls back to initialValues;
420
+ * provided, the explicit value becomes the live value with no fallback at
421
+ * all. Mirrors react-hook-form's resetField options (`value` plays their
422
+ * `defaultValue`'s role) to ease migration. */
423
+ interface ResetFieldOptions {
424
+ /** Keep the field's touched flag instead of clearing it. */
425
+ keepTouched?: boolean;
426
+ /** Keep the field's errors instead of clearing them. */
427
+ keepErrors?: boolean;
428
+ /** Explicit post-reset value for the field — never falls back to
429
+ * initialValues. */
430
+ value?: any;
431
+ }
432
+ /**
433
+ * Reset a single field: drop its live value (reads fall back to the
434
+ * baseline — initialValues, or the schema's parsed output when one
435
+ * exists, in which case the path is removed from parsedValues and the
436
+ * initial value pinned back so the field reads initialValues again),
437
+ * clear its touched flag and errors, and revive the path's removal
438
+ * tombstones — the inverse of {@link removeFieldByPath}. Other fields
439
+ * and the submission flags are untouched; see {@link reset} for the
440
+ * form-wide counterpart.
441
+ *
442
+ * @param form
443
+ * @param name
444
+ * @param options
445
+ */
446
+ declare function resetField<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, options?: ResetFieldOptions): void;
447
+ /**
448
+ * @param form
449
+ */
450
+ declare function hasErrors({ errors }: Form): boolean;
451
+ /**
452
+ * Trigger field validation.
453
+ *
454
+ * Without `name` every registered field validator runs. A single `name` —
455
+ * dotted string or segments array — runs only that field's validator, and
456
+ * an array of names runs each one in order. An empty array is a no-op, as
457
+ * is any name with no registered validator. An array argument counts as
458
+ * one segments path only when it mixes in numbers (`['items', 0]`); pure
459
+ * string arrays are name lists, so `['a', 'b']` triggers fields `a` and
460
+ * `b`, not the nested path `a.b`.
461
+ *
462
+ * The returned promise waits for the triggered validation to settle —
463
+ * async validators included — so their errors have already landed in
464
+ * `form.errors` when it resolves. It never rejects: landing errors is the
465
+ * expected outcome here, not a failure. Resolves `true` when the triggered
466
+ * scope is error-free, `false` otherwise. Without `name` the scope is all
467
+ * fields plus the form-level `validate` result (which runs after field
468
+ * validators settle, same pipeline as {@link ensureValidate}); with `name`
469
+ * only those fields' own errors count and form-level `validate` is
470
+ * skipped (RHF semantics).
471
+ *
472
+ * Fire-and-forget callers may ignore the promise: the validator kicks
473
+ * still happen synchronously, matching the pre-promise behavior.
474
+ *
475
+ * @param form
476
+ * @param name field name(s) to trigger, or all fields when omitted
477
+ * @return whether the triggered scope is error-free once validation settles
478
+ */
479
+ declare function trigger(form: Form, name?: Name | Name[]): Promise<boolean>;
480
+ /**
481
+ * Validate and throw if any field error.
482
+ * @param form
483
+ * @return resolve if no error; reject and stop validate if has an error
484
+ */
485
+ declare function ensureValidate(form: Form): Promise<void>;
486
+ /**
487
+ * Validate and return if any field error.
488
+ * @param form
489
+ * @return error message string or void
490
+ */
491
+ declare function validate(form: Form): Promise<void | string>;
492
+ declare function setIsSubmitting(form: Form, value: boolean): void;
493
+ declare function incrementSubmitCount(form: Form): void;
494
+ declare function setSubmitSuccessful(form: Form, value: boolean): void;
495
+ /**
496
+ * Set the form-level disabled flag and emit a payload-less 'disabled'
497
+ * event — subscribed fields (useField and the components built on it)
498
+ * re-render with the merged disabled state: form flag || their own
499
+ * `disabled` option.
500
+ * @param form
501
+ * @param value
502
+ */
503
+ declare function setDisabled(form: Form, value: boolean): void;
504
+ /** Submit callbacks for {@link handleSubmit}. All optional — a missing
505
+ * callback is simply skipped, matching the <Form> component semantics. */
506
+ interface HandleSubmitOptions<T extends Record<string, any> = any> {
507
+ /** Called after validation passes, before onValidSubmit. */
508
+ onSubmit?: (values: T, e?: any) => void | Promise<void>;
509
+ /** Called after validation passes, following a successful onSubmit. */
510
+ onValidSubmit?: (values: T, e?: any) => void | Promise<void>;
511
+ /**
512
+ * Called when validation fails.
513
+ * @param errors array of {path, type, message} entries in insertion
514
+ * order; path is the dotted field path ('a.b', 'list.0'), type is
515
+ * the error kind ('custom' for plain string errors, 'native' for
516
+ * failed DOM constraint validation), message is the display text
517
+ * @param values current form values
518
+ */
519
+ onInvalidSubmit?: (errors: FieldErrorEntry[], values: T) => void;
520
+ /**
521
+ * Focus the first error field after a failed submit. Defaults to true —
522
+ * only an explicit `false` disables it. When custom validation fails,
523
+ * a 'focusError' event carrying the first error's path key is emitted
524
+ * on the form (bound fields such as <Field> subscribe and focus their
525
+ * input); when native constraint validation fails, the submitted
526
+ * form's first ':invalid' control is focused directly.
527
+ */
528
+ shouldFocusError?: boolean;
529
+ }
530
+ /**
531
+ * Create an async submit handler for `form` — the headless counterpart of
532
+ * the <Form> component's onSubmit wiring.
533
+ *
534
+ * Behavior mirrors <Form> exactly: preventDefault when present, then the
535
+ * submit state machine (isSubmitting/submitCount/isSubmitSuccessful) runs
536
+ * around native constraint validation (via `e.currentTarget.checkValidity`,
537
+ * skipped when the target has no checkValidity — e.g. React Native or
538
+ * toolbar-button submits) and custom validators. Failed validation fires
539
+ * onInvalidSubmit with the flattened error entries; a passing submit runs
540
+ * onSubmit then onValidSubmit. Errors thrown by either are swallowed into
541
+ * isSubmitSuccessful=false rather than rejecting the returned promise.
542
+ * Failed validation also focuses the offending field (see
543
+ * {@link HandleSubmitOptions.shouldFocusError}).
544
+ *
545
+ * @param form form instance
546
+ * @param options submit callbacks
547
+ * @return async event handler, callable without an event object
548
+ */
549
+ declare function handleSubmit<T extends Record<string, any> = any>(form: Form<T>, options?: HandleSubmitOptions<T>): (e?: {
550
+ preventDefault?: () => void;
551
+ currentTarget?: any;
552
+ }) => Promise<void>;
553
+ /** Options accepted by {@link setFocus}. All flags default to `false`. */
554
+ interface SetFocusOptions {
555
+ /** Select the field's text after focusing it. Bound fields call
556
+ * `select()` on their element; elements without one (custom `as`
557
+ * components) just focus. */
558
+ shouldSelect?: boolean;
559
+ }
560
+ /**
561
+ * Programmatically focus a bound field's element (e.g. the <Field>'s
562
+ * input).
563
+ *
564
+ * Rides the same 'focusError' event channel a failed handleSubmit uses to
565
+ * focus the first errored field: the payload is the target's path key,
566
+ * with the focus options as a second, backward-compatible argument (older
567
+ * subscribers declared with a single `key` parameter simply ignore it).
568
+ * Being event-driven, it is a silent no-op when the field is unmounted or
569
+ * nothing subscribes — unknown names never throw.
570
+ *
571
+ * @param form form instance
572
+ * @param name field name (dot path or segments path)
573
+ * @param options focus options
574
+ */
575
+ declare function setFocus(form: Form, name: Name, options?: SetFocusOptions): void;
576
+
577
+ export { setIsSubmitting as $, clearErrors as A, setTouched as B, setTouchedByPath as C, hasTouched as D, hasTouchedByPath as E, isDirty as G, getDirtyFields as H, getTouchedFields as I, isTouched as J, removeField as K, removeFieldByPath as L, setInitialValues as M, reset as T, resetField as W, hasErrors as X, trigger as Y, ensureValidate as Z, validate as _, incrementSubmitCount as a0, setSubmitSuccessful as a1, setDisabled as a2, handleSubmit as a4, setFocus as a6, create as d, VALIDATION_OUTCOME as g, getValues as j, getValue as k, getValueByPath as l, setValueByPath as m, getError as n, getErrorByPath as o, getFieldErrors as p, getFieldErrorsByPath as q, getErrors as r, setValue as s, getFirstError as t, getFieldState as v, unsetValidatingByPath as w, setValidatingByPath as x, setError as y, setErrorByPath as z };
578
+ export type { FieldPath as F, Name as N, Options as O, PathValueOf as P, ResetOptions as Q, ReValidateMode as R, SetFieldOptions as S, ResetFieldOptions as U, ValidationMode as V, Form as a, HandleSubmitOptions as a3, SetFocusOptions as a5, FieldError as b, Path as c, PathValue as e, FieldErrorEntry as f, ValidationOutcome as h, ValidateResult as i, FieldState as u };