react-f0rm 1.4.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.
Files changed (84) hide show
  1. package/README.md +17 -4
  2. package/dist/array-Bu7W8BSz.d.ts +54 -0
  3. package/dist/devtools/index.cjs.js +1 -1
  4. package/dist/devtools/index.cjs.js.map +1 -1
  5. package/dist/devtools/index.d.cts +8 -18
  6. package/dist/devtools/index.d.mts +8 -18
  7. package/dist/devtools/index.d.ts +8 -18
  8. package/dist/devtools/index.mjs +1 -1
  9. package/dist/devtools/index.mjs.map +1 -1
  10. package/dist/errors-DA4ReEd9.mjs +2 -0
  11. package/dist/errors-DA4ReEd9.mjs.map +1 -0
  12. package/dist/errors-TzyWwBfw.cjs.js +2 -0
  13. package/dist/errors-TzyWwBfw.cjs.js.map +1 -0
  14. package/dist/index.cjs.js +1 -1
  15. package/dist/index.cjs.js.map +1 -1
  16. package/dist/index.d.cts +347 -927
  17. package/dist/index.d.mts +347 -927
  18. package/dist/index.d.ts +347 -927
  19. package/dist/index.mjs +1 -1
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/index.umd.js +538 -451
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/index.umd.min.js +2 -2
  24. package/dist/index.umd.min.js.map +1 -1
  25. package/dist/persist.cjs.js +1 -1
  26. package/dist/persist.cjs.js.map +1 -1
  27. package/dist/persist.d.cts +9 -30
  28. package/dist/persist.d.mts +9 -30
  29. package/dist/persist.d.ts +9 -30
  30. package/dist/persist.mjs +1 -1
  31. package/dist/persist.mjs.map +1 -1
  32. package/dist/resolvers/standard-schema.cjs.js +1 -1
  33. package/dist/resolvers/standard-schema.d.cts +1 -1
  34. package/dist/resolvers/standard-schema.d.mts +1 -1
  35. package/dist/resolvers/standard-schema.d.ts +1 -1
  36. package/dist/resolvers/standard-schema.mjs +1 -1
  37. package/dist/resolvers/yup.cjs.js +1 -1
  38. package/dist/resolvers/yup.mjs +1 -1
  39. package/dist/resolvers/zod.cjs.js +1 -1
  40. package/dist/resolvers/zod.cjs.js.map +1 -1
  41. package/dist/resolvers/zod.d.cts +30 -2
  42. package/dist/resolvers/zod.d.mts +30 -2
  43. package/dist/resolvers/zod.d.ts +30 -2
  44. package/dist/resolvers/zod.mjs +1 -1
  45. package/dist/resolvers/zod.mjs.map +1 -1
  46. package/dist/server/index.cjs.js +1 -1
  47. package/dist/server/index.cjs.js.map +1 -1
  48. package/dist/server/index.d.cts +24 -92
  49. package/dist/server/index.d.mts +24 -92
  50. package/dist/server/index.d.ts +24 -92
  51. package/dist/server/index.mjs +1 -1
  52. package/dist/server/index.mjs.map +1 -1
  53. package/dist/standard-schema-BAaTmAHh.d.ts +682 -0
  54. package/dist/standardSchema-5WezjHlp.mjs +2 -0
  55. package/dist/standardSchema-5WezjHlp.mjs.map +1 -0
  56. package/dist/standardSchema-DINHlsYR.cjs.js +2 -0
  57. package/dist/standardSchema-DINHlsYR.cjs.js.map +1 -0
  58. package/dist/validate-2pX-N1O6.cjs.js +2 -0
  59. package/dist/validate-2pX-N1O6.cjs.js.map +1 -0
  60. package/dist/validate-C0HOsP9v.mjs +2 -0
  61. package/dist/validate-C0HOsP9v.mjs.map +1 -0
  62. package/dist/values-BbPnLByD.cjs.js +2 -0
  63. package/dist/values-BbPnLByD.cjs.js.map +1 -0
  64. package/dist/values-CHsmcZk4.mjs +2 -0
  65. package/dist/values-CHsmcZk4.mjs.map +1 -0
  66. package/package.json +6 -4
  67. package/dist/array-3hAjl6Bz.d.ts +0 -160
  68. package/dist/errors-8oPux7GR.cjs.js +0 -2
  69. package/dist/errors-8oPux7GR.cjs.js.map +0 -1
  70. package/dist/errors-ClH3eV1R.mjs +0 -2
  71. package/dist/errors-ClH3eV1R.mjs.map +0 -1
  72. package/dist/standard-schema-CYbnugL7.d.ts +0 -1184
  73. package/dist/standardSchema-BpZvg0tZ.mjs +0 -2
  74. package/dist/standardSchema-BpZvg0tZ.mjs.map +0 -1
  75. package/dist/standardSchema-CxV_DhBO.cjs.js +0 -2
  76. package/dist/standardSchema-CxV_DhBO.cjs.js.map +0 -1
  77. package/dist/validate-BEjNsNvd.mjs +0 -2
  78. package/dist/validate-BEjNsNvd.mjs.map +0 -1
  79. package/dist/validate-BvN6hiEG.cjs.js +0 -2
  80. package/dist/validate-BvN6hiEG.cjs.js.map +0 -1
  81. package/dist/values-Bod74Kzu.mjs +0 -2
  82. package/dist/values-Bod74Kzu.mjs.map +0 -1
  83. package/dist/values-DKpOCD5J.cjs.js +0 -2
  84. package/dist/values-DKpOCD5J.cjs.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,126 +1,74 @@
1
- import { f as FieldError, F as Form$1, e as Path, d as FieldPath, P as PathSegments, g as PathValueOf, N as Name, h as ValidationMode, R as RegisterOptions, i as RegisterProps, a as FieldErrorEntry, V as Validator, S as StandardSchemaV1, j as FieldRules, k as FieldErrors, l as FieldErrorsTree, O as Options, m as FormEvents } from './standard-schema-CYbnugL7.js';
2
- export { A as ArrayItemOf, D as DottedPath, n as FORM_ERROR, o as FormValidateFn, p as FormValidateMeta, q as FormValidateMode, r as FormValidationError, I as InferSchemaValues, s as OpaqueTypes, t as PathValue, u as ReValidateMode, v as SetErrorOptions, w as SetFocusOptions, x as SetServerErrorsOptions, y as SyncValidator, T as TriggerOptions, b as VALIDATION_OUTCOME, z as ValidateResult, c as ValidationOutcome, B as ValidatorRegistration, C as clearErrors, E as clearServerErrors, G as createForm, H as dottedKeyToFieldPath, J as ensureValidate, K as fieldPathToDottedKey, L as getError, M as getErrorByPath, Q as getErrors, U as getErrorsRecord, W as getErrorsTree, X as getFieldErrors, Y as getFieldErrorsByPath, Z as getFirstError, _ as hasErrors, $ as registerFieldValidateDeps, a0 as registerValidatorByPath, a1 as revalidateDependentsOnChange, a2 as revalidateFormOnChange, a3 as runFormValidate, a4 as setError, a5 as setErrorByPath, a6 as setFocus, a7 as setServerErrors, a8 as setValidatingByPath, a9 as trigger, aa as unregisterFieldValidateDeps, ab as unsetValidatingByPath, ac as validate } from './standard-schema-CYbnugL7.js';
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
3
  import { EventEmitter } from '@for-fun/event-emitter';
4
4
  export { EventEmitter } from '@for-fun/event-emitter';
5
5
  import * as React from 'react';
6
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-3hAjl6Bz.js';
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
8
 
9
- /**
10
- * Get form values: the values Map layered over parsedValues (when a schema
11
- * validation produced them) layered over initialValues.
12
- *
13
- * Merged with copy-on-write ownership tracking ({@link setOwned}): every
14
- * distinct container on a written path is allocated once and shared by all
15
- * paths through it, instead of re-copying the whole branch for every key.
16
- * One owned set spans the whole merge, so containers borrowed from the
17
- * parsedValues tree are copied before mutation exactly like initialValues
18
- * ones. The result is a freshly merged tree per mutation, with untouched
19
- * branches sharing references with the baseline exactly like chained
20
- * `set` did.
21
- *
22
- * Memoized per form like {@link getDirtyFields}: every value write bumps a
23
- * `version` counter ({@link bumpValuesVersion}) while reads reset it, so
24
- * consecutive reads hand back the same reference (submit, changeValue and
25
- * form-level validate all read the whole tree, often several times per
26
- * interaction). Treat the result as read-only the next read after a
27
- * write returns a fresh tree, but between writes the cached one is shared
28
- * with every other reader.
29
- *
30
- * parsedValues is the schema's complete output tree: once validation
31
- * succeeds it replaces the initialValues baseline (fields the schema
32
- * dropped disappear), while live edits in the values Map still win over
33
- * both. It never affects dirty state — {@link isDirty} and
34
- * {@link getDirtyFields} compare live edits against initialValues only,
35
- * because parsing is not a user edit.
36
- *
37
- * @param form
38
- */
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. */
39
33
  declare function getValues<T extends Record<string, any> = any>(form: Form$1<T>): T;
40
- /**
41
- * Get field value
42
- * @param form
43
- * @param name
44
- */
45
- declare function getValue<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): PathValueOf<T, P>;
46
- /**
47
- * Get field value by path
48
- * @param form
49
- * @param path
50
- */
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. */
51
37
  declare function getValueByPath({ initialValues, parsedValues, values, deleted }: Form$1, path: Path): any;
52
38
  /** Options accepted by {@link setValue} / {@link setValueByPath} / {@link
53
39
  * changeValue} / {@link changeValueByPath}. `shouldValidate`/`shouldTouch`
54
- * default to `false`; omitting the options object entirely keeps the plain
55
- * set-value behavior (no validation, no touched marking, dirty stays
56
- * derived). */
40
+ * default to `false`. */
57
41
  type SetFieldOptions = {
58
- /** Run the field's registered validator (if any) after the value lands,
59
- * same as triggering that single field. Defaults to `false`. */
42
+ /** Run the field's registered validator (if any) after the value lands.
43
+ * Defaults to `false`. */
60
44
  shouldValidate?: boolean;
61
45
  /** Mark the field as touched. Defaults to `false`. */
62
46
  shouldTouch?: boolean;
63
- /** Land the value as a commit instead of an edit: the value becomes the
64
- * field's dirty-comparison baseline, so `getDirtyFields`/`isDirty`/
65
- * `getFieldState().isDirty` read the field as clean, and a later write
66
- * dirties it only by differing from the new baseline. `true` (or
67
- * omitting the flag) keeps the default derived behavior — dirty while
68
- * the live value differs from initialValues. */
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. */
69
51
  shouldDirty?: boolean;
70
52
  };
71
- /**
72
- * Set field value. The value may also be an updater function receiving
73
- * the field's current value and returning the next one (TanStack Form's
74
- * `setFieldValue` contract) handy for increments and array transforms:
75
- * `setValue(form, 'count', c => c + 1)`. The tradeoff: a function can
76
- * never itself be stored as a field value through this function.
77
- * @param form
78
- * @param name
79
- * @param value
80
- * @param options
81
- */
82
- declare function setValue<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P, value: PathValueOf<T, P> | ((prev: PathValueOf<T, P>) => PathValueOf<T, P>), options?: SetFieldOptions): void;
83
- /**
84
- * Set field value. The value may also be an updater function receiving
85
- * the field's current value and returning the next one (TanStack Form's
86
- * `setFieldValue` contract) — note that a function can therefore never
87
- * itself be stored as a field value through this function.
88
- * @param form
89
- * @param path
90
- * @param value
91
- * @param options
92
- */
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}). */
93
59
  declare function setValueByPath(form: Form$1, path: Path, value: any | ((prev: any) => any), options?: SetFieldOptions): void;
94
- /**
95
- * The write of {@link setValueByPath} minus the `'change'` emit: the
96
- * render-time {@link useField} `initialValue` seed. The field's first
97
- * paint (SSR included effects never run on the server) must already
98
- * carry the value, so the write happens during render where emitting is
99
- * illegal; the seeding field announces it from its post-commit effect
100
- * through {@link emitChangeByPath} instead.
101
- *
102
- * Everything else matches a plain write: descendant keys of the seeded
103
- * path are pruned, the branch's tombstones and committed baselines are
104
- * revived/dropped, and both memo caches are invalidated. Like the effect
105
- * seed it replaces, the caller guards it to paths with no value yet.
106
- */
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}. */
107
65
  declare function seedValueByPath(form: Form$1, path: Path, value: any): void;
108
66
  /** Announce a {@link seedValueByPath} that happened during render: the
109
67
  * payload-carrying `'change'` emit {@link setValueByPath} would have
110
- * fired, split out so it can run post-commit where emitting is safe.
111
- * Subscribers that rendered after the seed re-read an unchanged snapshot
112
- * and bail; subscribers from earlier commits resync. */
68
+ * fired, split out so it runs post-commit where emitting is safe. */
113
69
  declare function emitChangeByPath({ emitter }: Form$1, path: Path): void;
114
- /** Per-form registry of mounted fields' validation-mode overrides: path
115
- * key -> the field's `mode` option (undefined = follow {@link Form.mode})
116
- * plus an owner token so competing mounts at one path clean up safely.
117
- * Presence of an entry is the "a field is mounted at this path" signal
118
- * that routes {@link changeValueByPath} into the gated user-change
119
- * pipeline ({@link userChangeByPath}). Held in a WeakMap so the Form
120
- * shape carries only plain state fields. */
121
- /** Snapshot of one field's aggregated state, as {@link getFieldState}
122
- * returns it. `errors` is the stored array shared with the form — treat it
123
- * as read-only, like every {@link getFieldErrors} result. */
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. */
124
72
  type FieldState<T = any> = {
125
73
  value: T;
126
74
  error: FieldError | undefined;
@@ -129,42 +77,18 @@ type FieldState<T = any> = {
129
77
  isTouched: boolean;
130
78
  isValidating: boolean;
131
79
  };
132
- /**
133
- * Get one field's aggregated state: the layered value ({@link getValue}),
134
- * the first error ({@link getError}) and every error ({@link
135
- * getFieldErrors}), dirtiness, the touched flag, and whether a validator
136
- * is in flight. `isDirty` applies the same per-field rule as {@link
137
- * getDirtyFields}: a live value exists and differs from initialValues at
138
- * that path (parsedValues never counts — parsing is not an edit).
139
- *
140
- * @param form
141
- * @param name
142
- */
143
- declare function getFieldState<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): FieldState<PathValueOf<T, P>>;
144
- /**
145
- * Remove a field: by default its live value drops out of reads and
146
- * `getValues()` (the path is tombstoned, so it never falls back to
147
- * initialValues), its dirty baseline, touched flag and errors are cleared.
148
- * The keep-flags preserve slices of that state instead.
149
- *
150
- * @param form
151
- * @param name
152
- */
153
- /**
154
- * Options accepted by {@link removeField}. All flags default to `false` —
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`
155
85
  * the historical remove semantics (value dropped, path tombstoned, dirty
156
- * baseline/touched/errors cleared). Names mirror react-hook-form's
157
- * `unregister` options to ease migration; RHF's `shouldValidate` and
158
- * `keepDefaultValue` have no counterparts (removal never validates, and
159
- * the tombstone is exactly the "do not revive from initialValues" choice).
160
- */
86
+ * baseline/touched/errors cleared). */
161
87
  type RemoveFieldOptions = {
162
88
  /** Keep the field's live value and dirty baseline instead of
163
- * tombstoning: reads and `getValues()` keep returning the value, submit
164
- * includes it, and dirtiness against initialValues is preserved. */
89
+ * tombstoning: reads, `getValues()`, and submit keep the value. */
165
90
  keepValue?: boolean;
166
- /** Keep the field's dirty baseline. Implies `keepValue` — a removed
167
- * value has nothing to be dirty about. */
91
+ /** Keep the field's dirty baseline. Implies `keepValue`. */
168
92
  keepDirty?: boolean;
169
93
  /** Keep the field's touched flag instead of clearing it. */
170
94
  keepTouched?: boolean;
@@ -172,250 +96,116 @@ type RemoveFieldOptions = {
172
96
  keepError?: boolean;
173
97
  };
174
98
  declare function removeField(form: Form$1, name: Name, options?: RemoveFieldOptions): void;
175
- /**
176
- * Remove field
177
- * @param form
178
- * @param path
179
- * @param options keep-flags to preserve slices of state through the removal
180
- */
99
+ /** Remove a field by path; the keep-flags preserve slices of state. */
181
100
  declare function removeFieldByPath(form: Form$1, path: Path, options?: RemoveFieldOptions): void;
182
- /**
183
- * Set form initialValues
184
- *
185
- * Content-based early return: a new reference with equal content (the
186
- * re-rendered inline literal) is a no-op, so committed edits survive, while
187
- * genuinely changed content swaps the baseline and re-seeds — live values
188
- * and tombstones are cleared, touched flags and errors survive.
189
- * @param form
190
- * @param initialValues
191
- */
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. */
192
105
  declare function setInitialValues(form: Form$1, initialValues: any): void;
193
- /** Options accepted by {@link reset}. Every flag defaults to `false`
194
- * omitting the object (or any flag) keeps the plain full-reset behavior.
195
- * Names mirror react-hook-form's reset options to ease migration. */
106
+ /** Options accepted by {@link reset}. Every flag defaults to `false`. */
196
107
  type ResetOptions = {
197
108
  /** Keep the current values of fields that are dirty — differ from the
198
- * pre-reset initialValues (the same rule {@link getDirtyFields} applies).
199
- * Clean fields fall back to the new initialValues as usual. */
109
+ * pre-reset initialValues (the same rule {@link getDirtyFields} applies). */
200
110
  keepDirtyValues?: boolean;
201
111
  /** Keep every field's current live value instead of returning to the
202
- * baseline (react-hook-form's `keepValues` a strict superset of
203
- * `keepDirtyValues`, which only preserves dirty fields' values).
204
- * Dirtiness is recomputed against the post-reset baseline, so kept
205
- * values that differ from a newly provided baseline count as dirty. */
112
+ * baseline (a superset of `keepDirtyValues`). Dirtiness is recomputed
113
+ * against the post-reset baseline. */
206
114
  keepValues?: boolean;
207
- /** Ignore a newly provided `initialValues` argument and keep the current
208
- * baseline — fields still return to it (react-hook-form's
209
- * `keepDefaultValues`). */
115
+ /** Ignore a newly provided `initialValues` and keep the current baseline. */
210
116
  keepDefaultValues?: boolean;
211
117
  /** Keep the touched set instead of clearing it. */
212
118
  keepTouched?: boolean;
213
119
  /** Keep field errors instead of clearing them. */
214
120
  keepErrors?: boolean;
215
- /** Keep the submitted flag (`isSubmitted`) instead of clearing it
216
- * react-hook-form's `keepIsSubmitted`. */
121
+ /** Keep the submitted flag (`isSubmitted`) instead of clearing it. */
217
122
  keepIsSubmitted?: boolean;
218
- /** Keep the last submit's success flag (`isSubmitSuccessful`) instead of
219
- * clearing it. */
123
+ /** Keep the last submit's success flag (`isSubmitSuccessful`). */
220
124
  keepIsSubmitSuccessful?: boolean;
221
125
  /** Keep `submitCount` instead of resetting it to 0. */
222
126
  keepSubmitCount?: boolean;
223
127
  /** Keep `isSubmitting` instead of resetting it to false. */
224
128
  keepIsSubmitting?: boolean;
225
129
  };
226
- /**
227
- * Reset form
228
- * @param form
229
- * @param initialValues new baseline — omitted (or undefined), the form
230
- * keeps its current initialValues and fields simply return to them
231
- * (react-hook-form's reset-without-values semantics)
232
- * @param options keep-flags to preserve slices of state through the reset
233
- */
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). */
234
133
  declare function reset(form: Form$1, initialValues?: any, options?: ResetOptions): void;
235
- /** Options accepted by {@link resetField}. The flags default to `false`;
236
- * `value` has no default — omitted, the field falls back to initialValues;
237
- * provided, the explicit value becomes the live value with no fallback at
238
- * all. Mirrors react-hook-form's resetField options (`value` plays their
239
- * `defaultValue`'s role) to ease migration. */
134
+ /** Options accepted by {@link resetField}. Flags default to `false`;
135
+ * `value` has no default — omitted, the field falls back to initialValues. */
240
136
  type ResetFieldOptions = {
241
137
  /** Keep the field's touched flag instead of clearing it. */
242
138
  keepTouched?: boolean;
243
139
  /** Keep the field's errors instead of clearing them. */
244
140
  keepErrors?: boolean;
245
- /** Explicit post-reset value for the field — never falls back to
246
- * initialValues. */
141
+ /** Explicit post-reset value — never falls back to initialValues. */
247
142
  value?: any;
248
143
  };
249
- /**
250
- * Reset a single field: drop its live value (reads fall back to the
251
- * baseline initialValues, or the schema's parsed output when one
252
- * exists, in which case the path is removed from parsedValues and the
253
- * initial value pinned back so the field reads initialValues again),
254
- * clear its touched flag and errors, and revive the path's removal
255
- * tombstones — the inverse of {@link removeFieldByPath}. Other fields
256
- * and the submission flags are untouched; see {@link reset} for the
257
- * form-wide counterpart.
258
- *
259
- * @param form
260
- * @param name
261
- * @param options
262
- */
263
- declare function resetField<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P, options?: ResetFieldOptions): void;
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;
264
148
 
265
- /**
266
- * Set field touched state
267
- * @param form
268
- * @param name
269
- */
149
+ /** Set a field's touched state. */
270
150
  declare function setTouched(form: Form$1, name: Name): void;
271
- /**
272
- * Set field touched state
273
- * @param form
274
- * @param path
275
- */
151
+ /** Set a field's touched state by path. */
276
152
  declare function setTouchedByPath({ emitter, touched }: Form$1, path: Path): void;
277
- /**
278
- * Check if field has been touched
279
- * @param form
280
- * @param name
281
- */
282
- declare function hasTouched<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): boolean;
283
- /**
284
- * Check if field has been touched
285
- * @param form
286
- * @param path
287
- */
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. */
288
156
  declare function hasTouchedByPath({ touched }: Form$1, path: Path): boolean;
289
- /**
290
- * Is dirty -- any value differs from initialValues
291
- * @param form
292
- */
293
- /**
294
- * Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'), unlike
295
- * the JSON array keys stored in the touched Set.
296
- * @param form
297
- * @return array of touched fields' dotted paths
298
- */
157
+ /** Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'). */
299
158
  declare function getTouchedFields({ touched }: Form$1): string[];
300
- /**
301
- * Is touched -- any field has been touched
302
- * @param form
303
- */
159
+ /** Is touched — any field has been touched. */
304
160
  declare function isTouched({ touched }: Form$1): boolean;
305
161
 
306
- /**
307
- * Is one field dirty the per-field rule behind `getFieldState`'s
308
- * `isDirty` and {@link useIsFieldDirty}: a live value exists at the path
309
- * and differs from the field's effective baseline (committed
310
- * `shouldDirty: false` baselines included). A leaf under a wholesale
311
- * ancestor write reports clean — dirtiness belongs to the branch that
312
- * actually diverged, the same attribution {@link getDirtyFields} applies.
313
- */
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. */
314
167
  declare function isFieldDirtyByPath(form: Form$1, path: Path): boolean;
315
- /**
316
- * Is dirty -- any value differs from initialValues
317
- * @param form
318
- */
168
+ /** Is dirty — any value differs from initialValues. */
319
169
  declare function isDirty(form: Form$1): boolean;
320
- /**
321
- * Get dirty fields -- fields whose current value differs from initialValues.
322
- * Keys are user-facing dotted paths ('a.b', 'a.0.c'), unlike the JSON array
323
- * keys stored in the values Map.
324
- * @param form
325
- * @return object mapping each dirty field's dotted path to true; the same
326
- * reference is returned until the dirty set actually changes
327
- */
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. */
328
173
  declare function getDirtyFields(form: Form$1): Record<string, boolean>;
329
174
 
330
- /**
331
- * Set a field value as a user change.
332
- *
333
- * The write rides the same gated user-change pipeline a user typing into
334
- * the field would fire when a field is mounted on the path (registered
335
- * through {@link registerFieldMode} `useField` registers on mount): the
336
- * field's effective `mode` (per-field override included) and the form's
337
- * `reValidateMode` drive validation exactly as in {@link
338
- * userChangeByPath}. With no mounted field on the path it degrades to a
339
- * plain value set ({@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 in the field
345
- * registration, not in public state.
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> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<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
- */
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. */
371
183
  declare function changeValueByPath(form: Form$1, path: Path, value: any, options?: SetFieldOptions): void;
372
- /**
373
- * Register a mounted field's `mode` override at `path` for user-change
374
- * gating ({@link userChangeByPath} / {@link userBlur}). Returns the
375
- * registration token for {@link unregisterFieldMode} plus whether the
376
- * slot was already occupied — two fields mounted at one path is almost
377
- * always a bug: the latest mount's mode governs every user-change write
378
- * there, which the React layer warns about in DEV.
379
- *
380
- * @param form
381
- * @param path
382
- * @param mode the field's `mode` option, or undefined to follow
383
- * {@link Form.mode}
384
- * @return `token` to hand to {@link unregisterFieldMode}; `displaced`
385
- * true when a previous registration at the same path still owned
386
- * the slot
387
- */
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). */
388
188
  declare function registerFieldMode(form: Form$1, path: Path, mode: ValidationMode | undefined): {
389
189
  token: object;
390
190
  displaced: boolean;
391
191
  };
392
- /** Drop a {@link registerFieldMode} registration. A later mount at the
393
- * same path keeps its slot: only the entry owned by `token` is removed. */
192
+ /** Drop a {@link registerFieldMode} registration; only the entry owned by
193
+ * `token` is removed, so a later mount keeps its slot. */
394
194
  declare function unregisterFieldMode(form: Form$1, path: Path, token: object): void;
395
- /**
396
- * Write a bound field's user change by path: the write plus the
397
- * mode/reValidateMode-gated validation pipeline what a bound field's
398
- * onChange does when the user types. Reads the effective mode from the
399
- * field-mode registry (the latest mount's override governs), so a plain
400
- * write happens when no field is registered at `path`. Framework
401
- * adapters (React's `useField`, a Solid binding) forward their field
402
- * change events here.
403
- *
404
- * @param form
405
- * @param path
406
- * @param value
407
- */
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. */
408
205
  declare function userChangeByPath(form: Form$1, path: Path, value: any): void;
409
- /**
410
- * A bound field's blur: mark the path touched, then kick its validator
411
- * under the blur-side gate (`mode` `'onBlur'`/`'onTouched'`/`'all'`, or
412
- * `reValidateMode: 'onBlur'` while the field carries a live error). The
413
- * touched marking is unconditional — a field counts as touched on blur
414
- * regardless of mode. Framework adapters forward field blur events here.
415
- *
416
- * @param form
417
- * @param path
418
- */
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. */
419
209
  declare function userBlur(form: Form$1, path: Path): void;
420
210
 
421
211
  /**
@@ -460,107 +250,59 @@ declare function registerField(form: Form$1, name: Name, options?: RegisterOptio
460
250
  declare function setIsSubmitting(form: Form$1, value: boolean): void;
461
251
  declare function incrementSubmitCount(form: Form$1): void;
462
252
  declare function setSubmitSuccessful(form: Form$1, value: boolean): void;
463
- /**
464
- * Set the form-level disabled flag and emit a payload-less 'disabled'
465
- * event subscribed fields (useField and the components built on it)
466
- * re-render with the merged disabled state: form flag || their own
467
- * `disabled` option.
468
- * @param form
469
- * @param value
470
- */
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). */
471
256
  declare function setDisabled(form: Form$1, value: boolean): void;
472
- /**
473
- * Set the form's user-owned metadata slot (Formik's `status` role): the
474
- * payload-less 'status' event wakes {@link useStatus} and any imperative
475
- * `subscribe(form, {event: 'status'})` listeners. Nothing else reads or
476
- * interprets the value — server session flags, step state, non-field
477
- * errors of any shape are all fair game. Starts `undefined`.
478
- * @param form
479
- * @param value
480
- */
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. */
481
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>;
482
263
  /** Submit callbacks for {@link handleSubmit}. All optional — a missing
483
264
  * callback is simply skipped, matching the <Form> component semantics. */
484
265
  type HandleSubmitOptions<T extends Record<string, any> = any> = {
485
266
  /** Called after validation passes, before onValidSubmit. */
486
- onSubmit?: (values: T, e?: any) => void | Promise<void>;
267
+ onSubmit?: SubmitCallback<T>;
487
268
  /** Called after validation passes, following a successful onSubmit. */
488
- onValidSubmit?: (values: T, e?: any) => void | Promise<void>;
489
- /**
490
- * Called when validation fails.
491
- * @param errors array of {path, type, message} entries in insertion
492
- * order; path is the dotted field path ('a.b', 'list.0'), type is
493
- * the error kind ('custom' for plain string errors, 'native' for
494
- * failed DOM constraint validation), message is the display text
495
- * @param values current form values
496
- */
269
+ onValidSubmit?: SubmitCallback<T>;
270
+ /** Called when validation fails, with the flattened error entries and
271
+ * current values. */
497
272
  onInvalidSubmit?: (errors: FieldErrorEntry[], values: T) => void;
498
- /**
499
- * Called after validation passes and the submit callbacks ran, with the
500
- * final (schema-coerced) values the slot <Form>'s `action` prop uses
501
- * to dispatch React 19 server actions with FormData. Runs inside the
502
- * same isSubmitting window and is awaited like onSubmit/onValidSubmit.
503
- *
504
- * The callback may return an {@link ActionErrorResult}: its `errors`
505
- * record (field path → message or messages) lands on the form through
506
- * {@link setServerErrors} (`type: 'server'`, cleared existing server
507
- * errors replaced), and the submit counts as unsuccessful — a rejected
508
- * server round trip is an invalid submit, exactly like failed client
509
- * validation. Any other return value (including `undefined`) means the
510
- * submit succeeded.
511
- */
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. */
512
278
  onAction?: (values: T, e?: any) => void | Promise<void | ActionErrorResult>;
513
- /**
514
- * Focus the first error field after a failed submit. Defaults to true —
515
- * only an explicit `false` disables it. When custom validation fails,
516
- * a 'focusError' event carrying the first error's path key is emitted
517
- * on the form (bound fields such as <Field> subscribe and focus their
518
- * input); when native constraint validation fails, the submitted
519
- * form's first ':invalid' control is focused directly.
520
- */
279
+ /** Focus the first error field after a failed submit. Defaults to true. */
521
280
  shouldFocusError?: boolean;
522
- /**
523
- * Whether native constraint validation (the submitted element's
524
- * checkValidity) gates this attempt. Defaults to the form's
525
- * {@link Form.shouldUseNativeValidation} flag — pass `false` to skip
526
- * the native gate for one submit (a save-draft button, say) while
527
- * custom validators still run; pass `true` to reinstate it on a form
528
- * that disabled it. Targets without checkValidity never gate.
529
- */
281
+ /** Whether native constraint validation gates this attempt. Defaults to
282
+ * the form's {@link Form.shouldUseNativeValidation} flag. Targets
283
+ * without checkValidity never gate. */
530
284
  shouldUseNativeValidation?: boolean;
531
285
  };
532
286
  /** What a server action / onAction callback returns when the server
533
- * rejected the payload: a field-path → message(s) record, landed on the
534
- * form as `type: 'server'` errors. Undefined (or anything else) means
535
- * success. */
287
+ * rejected the payload: a field-path → message(s) record, landed as
288
+ * `type: 'server'` errors. Undefined (or anything else) means success. */
536
289
  type ActionErrorResult = {
537
290
  errors?: Record<string, string | string[]>;
538
291
  };
539
- /**
540
- * Create an async submit handler for `form` — the headless counterpart of
541
- * the <Form> component's onSubmit wiring.
542
- *
543
- * Behavior mirrors <Form> exactly: preventDefault when present, then the
544
- * submit state machine (isSubmitting/submitCount/isSubmitSuccessful) runs
545
- * around native constraint validation (via `e.currentTarget.checkValidity`,
546
- * skipped when the target has no checkValidity e.g. React Native or
547
- * toolbar-button submits) and custom validators. Failed validation fires
548
- * onInvalidSubmit with the flattened error entries; a passing submit runs
549
- * onSubmit then onValidSubmit. Errors thrown by either are swallowed into
550
- * isSubmitSuccessful=false rather than rejecting the returned promise.
551
- * Failed validation also focuses the offending field (see
552
- * {@link HandleSubmitOptions.shouldFocusError}).
553
- *
554
- * @param form form instance
555
- * @param options submit callbacks
556
- * @return async event handler, callable without an event object
557
- */
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. */
558
300
  declare function handleSubmit<T extends Record<string, any> = any>(form: Form$1<T>, options?: HandleSubmitOptions<T>): (e?: {
559
301
  preventDefault?: () => void;
560
302
  currentTarget?: any;
561
303
  }) => Promise<void>;
562
304
 
563
- type UseFieldOptions$1<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = {
305
+ type UseFieldOptions$1<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = {
564
306
  form?: Form$1<TValues>;
565
307
  name: TPath;
566
308
  initialValue?: any;
@@ -722,7 +464,7 @@ type UseFieldOptions$1<TValues extends Record<string, any> = any, TPath extends
722
464
  * signature, so a typo'd property access (`field.vlaue`) is a type error
723
465
  * instead of silently reading `undefined`.
724
466
  */
725
- type UseFieldResult<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = {
467
+ type UseFieldResult<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = {
726
468
  /** The form instance this field is bound to (explicit prop or context) —
727
469
  * handy for consumers that need direct access to the headless API. */
728
470
  form: Form$1<TValues>;
@@ -803,7 +545,7 @@ type UseFieldInputProps = {
803
545
  'aria-invalid'?: boolean;
804
546
  'aria-describedby'?: string;
805
547
  };
806
- declare function useField<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments>(options: UseFieldOptions$1<TValues, TPath>): UseFieldResult<TValues, TPath>;
548
+ declare function useField<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(options: UseFieldOptions$1<TValues, TPath>): UseFieldResult<TValues, TPath>;
807
549
 
808
550
  type FieldArrayItem<K extends string> = {
809
551
  id: string;
@@ -811,7 +553,7 @@ type FieldArrayItem<K extends string> = {
811
553
  } & Record<K, string>;
812
554
  /** Options accepted by {@link useFieldArray} and the per-instance hook
813
555
  * returned by `createFormContext()`. */
814
- type UseFieldArrayOptions<K extends string = 'id'> = {
556
+ type UseFieldArrayOptions<K extends string = 'id'> = Pick<FieldOptionBase, 'rules' | 'shouldUnregister'> & {
815
557
  name: Name;
816
558
  form?: Form$1;
817
559
  /**
@@ -821,28 +563,21 @@ type UseFieldArrayOptions<K extends string = 'id'> = {
821
563
  * same name. The underlying id is unchanged.
822
564
  */
823
565
  keyName?: K;
824
- /**
825
- * Declarative rules validated against the whole array value
826
- * (react-hook-form's `useFieldArray` `rules`): `required` fails on an
827
- * empty array, `minLength`/`maxLength` read the array's length. Checked
828
- * on submit and `trigger`, like every registered validator.
829
- */
830
- rules?: FieldRules;
831
- /**
832
- * Whether unmounting this array removes its branch. Defaults to the
833
- * form-level `shouldUnregister` — tombstone (drop values) like a bound
834
- * field's unmount; pass `false` to keep the values.
835
- */
836
- shouldUnregister?: boolean;
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;
837
572
  };
838
573
  type UseFieldArrayResult<TItem = any, K extends string = 'id'> = {
839
574
  fields: FieldArrayItem<K>[];
840
575
  /** Append one row. With the item type declared —
841
576
  * `useFieldArray<Item>({name: 'items'})` — the value is checked
842
577
  * against the array's element type. */
843
- append: (value: TItem) => void;
844
- prepend: (value: TItem) => void;
845
- insert: (index: number, value: TItem) => void;
578
+ append: (value: TItem, options?: FieldArrayFocusOptions) => void;
579
+ prepend: (value: TItem, options?: FieldArrayFocusOptions) => void;
580
+ insert: (index: number, value: TItem, options?: FieldArrayFocusOptions) => void;
846
581
  /** Remove one row, or several in a single write (`remove([0, 2])` —
847
582
  * order-insensitive, duplicates ignored, out-of-range indices are
848
583
  * silent no-ops). */
@@ -878,6 +613,14 @@ type UseFieldArrayItemResult<TValue = any> = {
878
613
  index: number;
879
614
  form: Form$1;
880
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
+ };
881
624
  /**
882
625
  * Subscribe to a single row of a {@link useFieldArray} field — the
883
626
  * per-item counterpart `useFieldArray` alone cannot offer. `useFieldArray`
@@ -903,24 +646,33 @@ type UseFieldArrayItemResult<TValue = any> = {
903
646
  * the same path — it publishes the id table), the row's `id` from
904
647
  * `fields[i].id`, and optionally an explicit `form`
905
648
  */
906
- declare function useFieldArrayItem<TValue = any>(options: {
907
- name: Name;
908
- id: string;
909
- form?: Form$1;
910
- }): UseFieldArrayItemResult<TValue>;
649
+ declare function useFieldArrayItem<TValue = any>(options: UseFieldArrayItemOptions): UseFieldArrayItemResult<TValue>;
911
650
 
912
651
  declare const FormContext: Context<Form$1<any> | null>;
913
652
  declare const FormProvider: Provider<Form$1<any> | null>;
914
653
  /**
915
- * Read the form from the module-level {@link FormContext}. Pass the values
916
- * shape `useFormContext<Values>()` to get a fully typed `Form<Values>`
917
- * headless API; the `any` default keeps untyped call sites compiling.
918
- *
919
- * For multiple forms in one subtree use {@link createFormContext} instead.
920
- *
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.
921
657
  * @throws when no `<FormProvider>` is mounted above the call site.
922
658
  */
923
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
+ };
924
676
  /** The bundle {@link createFormContext} returns: a private React context
925
677
  * plus the hooks pre-bound to it, all typed against `TValues`. */
926
678
  type FormContextBundle<TValues extends Record<string, any> = any> = {
@@ -933,161 +685,75 @@ type FormContextBundle<TValues extends Record<string, any> = any> = {
933
685
  children: ReactNode;
934
686
  }) => ReactNode;
935
687
  useFormContext: () => Form$1<TValues>;
936
- useField: <TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments>(options: {
937
- name: TPath;
938
- } & Omit<UseFieldOptions$1<TValues, TPath>, 'form'>) => UseFieldResult<TValues, TPath>;
939
- useFieldArray: <TItem = any, K extends string = 'id'>(options: {
940
- name: FieldPath<TValues> | Name;
941
- keyName?: K;
942
- rules?: FieldRules;
943
- shouldUnregister?: boolean;
944
- }) => UseFieldArrayResult<TItem, K>;
945
- useFieldArrayItem: <TValue = any>(options: {
946
- name: FieldPath<TValues> | Name;
947
- id: string;
948
- }) => UseFieldArrayItemResult<TValue>;
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>;
949
691
  };
950
692
  /**
951
693
  * Create an isolated bundle of form-context bindings: its own React context
952
- * plus `useField` / `useFieldArray` / `useFieldArrayItem` /
953
- * `useFormContext` hooks that resolve their form from it.
954
- *
955
- * Why: the module-level {@link FormContext} works fine for a single form per
956
- * subtree, but nesting two forms (or reusing a component inside a different
957
- * form) makes them fight over one context. Calling this factory once per app
958
- * area — `const Ctx = createFormContext<Values>()` — fixes the value shape
959
- * (`Ctx.useField({name: 'user.name'})` gets its `name` constrained by
960
- * `FieldPath<Values>` and its `value` typed accordingly), so call sites stop
961
- * hand-writing generics, and each instance's Provider scopes a strictly
962
- * separate form. The bundle also carries its raw React context
963
- * (`Ctx.context`) so `<Form context={Ctx.context}>` can provide into it.
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.
964
698
  */
965
699
  declare function createFormContext<TValues extends Record<string, any> = any>(): FormContextBundle<TValues>;
966
700
  declare const CheckboxGroupContext: Context<any>;
967
701
  declare const CheckboxGroupProvider: Provider<any>;
968
702
  declare function useCheckboxGroupContext(): any;
969
703
 
970
- /** Subscription granularity for {@link onPathEvent}.
971
- * - `'leaf'`: the subscriber reads exactly one key ({@link
972
- * useValueByPath}); only writes at that key or above it can change what
973
- * it reads.
974
- * - `'branch'`: the subscriber aggregates a whole subtree below a key
975
- * ({@link useFieldArray}); descendant writes matter too. */
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). */
976
707
  type WatchScope = 'leaf' | 'branch';
977
- /** Events {@link subscribe} can watch. `'errors'` and `'touched'` are
978
- * stored per exact key, so they match exact keys ({@link onKeyEvent});
979
- * `'change'`, `'validating'`, `'submitting'`, `'submitCount'`,
980
- * `'disabled'`, `'status'` and `'submitSuccessful'` go through
981
- * {@link onPathEvent}. `'validating'` carries paths (one per async
982
- * validator round) and matches by path exactly like `'change'`;
983
- * `'submitting'`, `'submitCount'`, `'disabled'`, `'status'` and
984
- * `'submitSuccessful'` are payload-less broadcasts, so `name` never
985
- * narrows them — every subscriber hears every emission. */
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. */
986
712
  type SubscribeEvent = 'change' | 'errors' | 'touched' | 'validating' | 'submitting' | 'submitCount' | 'submitSuccessful' | 'disabled' | 'status' | 'loading';
987
- /** Options accepted by {@link subscribe}. */
988
713
  type SubscribeOptions = {
989
- /** Path (or list of paths) to watch. Omit to receive every emission of
990
- * `event`, payload-less broadcasts included. A single segments path
991
- * (`['tags', 0]`) and a list of names (`['tags', 'user.name']`) are told
992
- * apart by the same rule `trigger` uses: only a segments path can hold
993
- * a number. */
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. */
994
717
  name?: Name | Name[];
995
718
  /** Event to watch. Defaults to `'change'`. */
996
719
  event?: SubscribeEvent;
997
- /** Which writes around `name` are relevant `'leaf'` or `'branch'`.
998
- * Only meaningful for the path-carrying events `'change'` and
999
- * `'validating'`: `'errors'`/`'touched'` match exact keys and
1000
- * `'submitting'`/`'submitCount'`/`'disabled'`/`'status'`/
1001
- * `'submitSuccessful'` are payload-less. Defaults to `'branch'` — the
1002
- * intuitive linkage semantics, where subscribing to `'tags'` means the
1003
- * whole branch. */
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). */
1004
723
  scope?: WatchScope;
1005
- /** Invoked with no arguments after each matching emission. Read fresh
1006
- * state through the `get*` readers inside it. */
724
+ /** Invoked after each matching emission; read fresh state through the
725
+ * `get*` readers inside it. */
1007
726
  callback: () => void;
1008
727
  };
1009
728
  /**
1010
729
  * Subscribe to form events imperatively — the non-render counterpart of
1011
- * the `use*` hooks: linkages and side effects (province changed → clear
1012
- * city, autosave, analytics) run without mounting a watching component.
1013
- *
1014
- * Without `name`, `callback` fires on every `event` emission, payload-less
1015
- * broadcasts (reset, setInitialValues) included. With `name`, matching
1016
- * follows the event's shape: `'errors'`/`'touched'` match the exact key
1017
- * ({@link onKeyEvent}) — another field's error never wakes this
1018
- * subscriber — while `'change'`/`'validating'`/`'submitting'`/
1019
- * `'submitCount'`/`'disabled'`/`'submitSuccessful'` go through
1020
- * {@link onPathEvent}, so the default `'branch'` scope wakes a `'tags'`
1021
- * subscriber when any `tags.*` descendant is written. `'validating'`
1022
- * carries a path per validator round and narrows by path like
1023
- * `'change'`; `'disabled'`/`'submitSuccessful'` (like `'submitting'`)
1024
- * are payload-less broadcasts that every named subscriber receives. A
1025
- * `name` array builds one subscription per path and the returned
1026
- * function unsubscribes them all.
1027
- *
1028
- * @param form the form to watch
1029
- * @param options event, name(s), scope and callback
1030
- * @return unsubscribe function
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.
1031
734
  */
1032
735
  declare function subscribe(form: Form$1, options: SubscribeOptions): () => void;
1033
736
  /** The handle {@link watch} returns: a subscribe/getSnapshot pair any
1034
- * reactive runtime can bind to React's `useSyncExternalStore(subscribe,
1035
- * getSnapshot)`, a Solid signal, a Vue ref, a Svelte store. The handle
1036
- * keeps one internal listener alive from creation, so `getSnapshot()` is
1037
- * always fresh (a read never returns a pre-write value even with no
1038
- * consumer subscribed); `subscribe` adds a consumer callback and returns
1039
- * its own unsubscribe. Call {@link WatchHandle.dispose} when the handle's
1040
- * lifetime ends (adapter teardown, effect cleanup). */
737
+ * reactive runtime can bind to. One internal listener stays alive from
738
+ * creation, so `getSnapshot()` is always fresh; `dispose` ends it. */
1041
739
  type WatchHandle<T> = {
1042
- /** Read the current snapshot. Recomputed on every heard event (and on
1043
- * first read), cached in between repeated reads share one reference
1044
- * until the watched state actually changes. */
740
+ /** Read the current snapshot, cached between events; repeated reads
741
+ * share one reference until state changes. */
1045
742
  getSnapshot: () => T;
1046
- /** Register a change listener; returns the unsubscribe function. The
1047
- * listener fires only when the projection observably changed: with an
1048
- * `isEqual` comparator the getter is re-run per event and an equal
1049
- * verdict skips the callback entirely (TanStack's `useSelector`
1050
- * contract); without one, every heard event wakes the listener. */
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. */
1051
746
  subscribe: (invalidate: () => void) => () => void;
1052
- /** Remove the internal listener and every consumer callback. The handle
1053
- * is dead afterwards — reads return the last cached value and no
1054
- * callback ever fires again. */
747
+ /** Remove the internal listener and every consumer callback; the handle
748
+ * is dead afterwards. */
1055
749
  dispose: () => void;
1056
750
  };
1057
751
  /**
1058
752
  * Watch a projection of form state without React — the framework-free
1059
- * counterpart of {@link useWatch} (same signature, same `isEqual`
1060
- * bailout), exported as a named top-level function so it is tree-shaken
1061
- * when unused. Headless adapters (Solid/Vue/Svelte bridges, imperative
1062
- * autosave/analytics code) consume the returned
1063
- * {@link WatchHandle}: read the current snapshot through `getSnapshot()`
1064
- * and re-read (or re-render) whenever `subscribe`'s listener fires.
1065
- *
1066
- * The handle subscribes eagerly at creation, so `getSnapshot()` never
1067
- * returns a stale value — including reads with no consumer subscribed.
1068
- * `getter` and `isEqual` are captured when `watch` is called: call it at
1069
- * setup time, like a subscription, and {@link WatchHandle.dispose} it at
1070
- * teardown. Every emission of `event` wakes the listener (payload-less
1071
- * broadcasts included) — the wide surface `useWatch` uses; path-scoped
1072
- * variants are the `useValue`-family hooks on the React side and
1073
- * {@link subscribe} with a `name` on this side.
1074
- *
1075
- * ```js
1076
- * const handle = watch(form, 'change', () => getValue(form, 'email'));
1077
- * // imperative consumer:
1078
- * const off = handle.subscribe(() => save(handle.getSnapshot()));
1079
- * // React adapter (useWatch is this composition):
1080
- * useSyncExternalStore(handle.subscribe, handle.getSnapshot, handle.getSnapshot);
1081
- * handle.dispose(); // teardown
1082
- * ```
1083
- *
1084
- * @param form the form to watch
1085
- * @param event the event whose emissions invalidate the snapshot
1086
- * @param getter the projection — read fresh state through the `get*`
1087
- * readers inside it
1088
- * @param isEqual optional equality check; an equal verdict after an event
1089
- * skips the listeners entirely (wide getters returning fresh
1090
- * references per call stop churning subscribers)
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.
1091
757
  */
1092
758
  declare function watch<T>(form: Form$1, event: SubscribeEvent, getter: () => T, isEqual?: (prev: T, next: T) => boolean): WatchHandle<T>;
1093
759
 
@@ -1101,11 +767,19 @@ declare function watch<T>(form: Form$1, event: SubscribeEvent, getter: () => T,
1101
767
  * while touched flags and errors survive. Change detection is
1102
768
  * reference-first with a structural fallback, so re-renders that pass an
1103
769
  * inline literal with equal content never re-sync -- the user's
1104
- * in-progress typing is never clobbered.
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.
1105
775
  */
1106
776
  declare function useForm<T extends Record<string, any> = any>(options?: Options<T> & {
1107
777
  values?: T;
778
+ resetOptions?: ResetOptions;
1108
779
  }): Form$1<T>;
780
+ /** Snapshot equality comparator — the `isEqual` contract {@link
781
+ * useWatchCore} documents. */
782
+ type SnapshotComparator<T> = (prev: T, next: T) => boolean;
1109
783
  /**
1110
784
  * Shared core of {@link useWatch} and the path-scoped hooks: a
1111
785
  * useSyncExternalStore binding over a custom event subscription.
@@ -1122,7 +796,7 @@ declare function useForm<T extends Record<string, any> = any>(options?: Options<
1122
796
  * snapshot and notifies. Omitted, the historical drop-and-notify pipeline
1123
797
  * runs byte-for-byte unchanged.
1124
798
  */
1125
- declare function useWatchCore<T>(subscribeFactory: (invalidate: () => void) => () => void, getter: () => T, isEqual?: (prev: T, next: T) => boolean): T;
799
+ declare function useWatchCore<T>(subscribeFactory: (invalidate: () => void) => () => void, getter: () => T, isEqual?: SnapshotComparator<T>): T;
1126
800
  /**
1127
801
  * Subscribe to a form event and keep the component's snapshot of `getter()`
1128
802
  * in sync with the form state.
@@ -1153,9 +827,9 @@ declare function useWatchCore<T>(subscribeFactory: (invalidate: () => void) => (
1153
827
  * stores the new snapshot and re-renders. Same contract as TanStack's
1154
828
  * `useSelector` compare. Omitted, behavior is unchanged.
1155
829
  */
1156
- declare function useWatch<T>(formOrEmitter: Form$1 | EventEmitter<FormEvents>, event: SubscribeEvent, getter: () => T, isEqual?: (prev: T, next: T) => boolean): T;
830
+ declare function useWatch<T>(formOrEmitter: Form$1 | EventEmitter<FormEvents>, event: SubscribeEvent, getter: () => T, isEqual?: SnapshotComparator<T>): T;
1157
831
  /** Options for {@link useValue} and {@link useValueByPath}. */
1158
- type UseValueOptions<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments> = {
832
+ type UseValueOptions<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>> = {
1159
833
  /** Value to return while the field reads undefined — react-hook-form's
1160
834
  * `useWatch` `defaultValue`: an untouched, never-seeded field reads
1161
835
  * this instead of `undefined`. */
@@ -1171,7 +845,7 @@ type UseValueOptions<T extends Record<string, any> = any, P extends FieldPath<T>
1171
845
  /**
1172
846
  * Get field value state
1173
847
  */
1174
- declare function useValue<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P, options?: UseValueOptions<T, P>): PathValueOf<T, P>;
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>;
1175
849
  /**
1176
850
  * Get field value state by path
1177
851
  */
@@ -1194,7 +868,7 @@ declare function useValues<T extends Record<string, any> = any>(form: Form$1<T>)
1194
868
  /**
1195
869
  * Get field touched state
1196
870
  */
1197
- declare function useTouched<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): boolean;
871
+ declare function useTouched<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): boolean;
1198
872
  /**
1199
873
  * Get field touched state by path
1200
874
  */
@@ -1203,7 +877,7 @@ declare function useTouchedByPath(form: Form$1, path: Path): boolean;
1203
877
  * Get field error message state
1204
878
  * @return current error's message string (display text), or undefined
1205
879
  */
1206
- declare function useError<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): string | undefined;
880
+ declare function useError<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): string | undefined;
1207
881
  /**
1208
882
  * Get field error state by path
1209
883
  * @return current FieldError object ({type, message}), or undefined
@@ -1214,7 +888,7 @@ declare function useErrorByPath(form: Form$1, path: Path): FieldError | undefine
1214
888
  * @return every error registered for the field (insertion order); an empty
1215
889
  * array when the field has none
1216
890
  */
1217
- declare function useFieldErrors<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): FieldError[];
891
+ declare function useFieldErrors<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): FieldError[];
1218
892
  /**
1219
893
  * Get all field errors by path
1220
894
  * @return every error registered for the field (insertion order); an empty
@@ -1231,7 +905,7 @@ declare function useIsDirty(form: Form$1): boolean;
1231
905
  * the flag, payload-less broadcasts (reset, setInitialValues) always
1232
906
  * sync, and writes elsewhere never re-render it.
1233
907
  */
1234
- declare function useIsFieldDirty<T extends Record<string, any> = any, P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments>(form: Form$1<T>, name: P): boolean;
908
+ declare function useIsFieldDirty<T extends Record<string, any> = any, P extends AnyPath<T> = AnyPath<T>>(form: Form$1<T>, name: P): boolean;
1235
909
  /**
1236
910
  * Get whether one field is dirty, by parsed path. See {@link
1237
911
  * useIsFieldDirty}.
@@ -1320,7 +994,7 @@ declare function useFormState<T extends Record<string, any> = any>(form: Form$1<
1320
994
  * yours and spans state events — e.g. `form.validating.size > 0 &&
1321
995
  * form.isSubmitting` as one flag.
1322
996
  */
1323
- declare function useStore<T>(form: Form$1, selector: () => T, isEqual?: (prev: T, next: T) => boolean): T;
997
+ declare function useStore<T>(form: Form$1, selector: () => T, isEqual?: SnapshotComparator<T>): T;
1324
998
  declare function useHasErrors(form: Form$1): boolean;
1325
999
  /**
1326
1000
  * Get every error as one record keyed by user-facing dotted path
@@ -1424,410 +1098,156 @@ declare function useFormError(form: Form$1): string | undefined;
1424
1098
  */
1425
1099
  declare function useFormErrors(form: Form$1): FieldError[];
1426
1100
 
1427
- /**
1428
- * Options accepted by {@link useTransform}.
1429
- */
1430
- type UseTransformOptions<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments, TDisplay = PathValueOf<TValues, TPath>> = {
1431
- /**
1432
- * Map the form's stored (raw) value to the display value the control
1433
- * renders — the read direction. Omitted: the raw value is displayed
1434
- * as-is (identity).
1435
- */
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. */
1436
1104
  toDisplay?: (raw: PathValueOf<TValues, TPath>) => TDisplay;
1437
- /**
1438
- * Map a display value back to the raw value written into the form
1439
- * the write direction. Omitted: the display value is written as-is
1440
- * (identity). May return a Promise: the resolved raw value commits
1441
- * when it settles (async transforms, e.g. server-side formatting),
1442
- * with stale resolutions dropped — only the latest write commits.
1443
- * The round trip should be an identity
1444
- * (`toDisplay(fromDisplay(x)) === x`); a store value the transform
1445
- * cannot invert (e.g. `undefined` for a not-yet-edited field) must be
1446
- * handled by `toDisplay`, since it runs first.
1447
- */
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. */
1448
1110
  fromDisplay?: (display: TDisplay) => PathValueOf<TValues, TPath> | Promise<PathValueOf<TValues, TPath>>;
1449
- /**
1450
- * Debounce the display→raw commit: a write inside the window supersedes
1451
- * the pending one, and only the last write commits when the window
1452
- * elapses — the async-transforms counterpart of the field validator's
1453
- * `validateDebounce` (TanStack Form's `asyncDebounceMs`). `0`/omitted
1454
- * commits immediately (an async `fromDisplay` still resolves before
1455
- * the commit lands). The store value stays unchanged until the commit:
1456
- * `value` keeps deriving from it, and validation fires at commit time
1457
- * through the user-change pipeline.
1458
- */
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. */
1459
1115
  asyncDebounceMs?: number;
1460
1116
  };
1461
1117
  /**
1462
- * Bind a control to a field whose stored value and display value differ
1463
- * TanStack Form's `useTransform` counterpart, with the round trip made
1464
- * explicit: `toDisplay` maps the store value to what the control shows,
1465
- * `fromDisplay` maps the control's display value back to what the store
1466
- * holds. The store always carries the raw typed value, so
1467
- * `getValues`/submit/validation never see display representations.
1468
- *
1469
- * ```jsx
1470
- * const age = useTransform(form, 'age', {
1471
- * toDisplay: (raw: number) => String(raw),
1472
- * fromDisplay: (display: string) => Number(display)
1473
- * });
1474
- * <input value={age.value} onChange={e => age.onChange(e.target.value)} />
1475
- * ```
1476
- *
1477
- * `value` subscribes to 'change' at leaf scope exactly like a controlled
1478
- * `useField` value — typing, programmatic `setValue` and ancestor writes
1479
- * all re-derive it, writes elsewhere never re-render it. `onChange`
1480
- * writes through `userChangeByPath` (the user-change channel): with a
1481
- * field mounted at the same path the mode/reValidateMode-gated
1482
- * validation fires exactly as if the user typed into a bound field; with
1483
- * no mounted field it degrades to a plain value write. Touched marking
1484
- * stays a blur concern — pair this with `useField` at the same path, or
1485
- * call `setTouched`, when blur semantics matter.
1486
- *
1487
- * The transform functions are read fresh on every render (inline
1488
- * closures work), and `value` is recomputed per render — keep display
1489
- * values primitive (string/number) so React's equal-state bailout holds.
1490
- *
1491
- * @param form the form instance (explicit; the hook is headless — no
1492
- * context read, no provider required)
1493
- * @param name the field's path (dotted string or segments)
1494
- * @param options the two mapping directions; both optional (identity)
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.
1495
1124
  */
1496
- declare function useTransform<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments, TDisplay = PathValueOf<TValues, TPath>>(form: Form$1<TValues>, name: TPath, options?: UseTransformOptions<TValues, TPath, TDisplay>): {
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>): {
1497
1126
  value: TDisplay;
1498
1127
  onChange: (display: TDisplay) => void;
1499
1128
  };
1500
1129
 
1501
- /**
1502
- * Props for <Form>.
1503
- *
1504
- * Native validation behavior: the rendered <form> always sets noValidate,
1505
- * which suppresses the browser's built-in blocked-submit UI. However, native
1506
- * constraint validation still gates submission the form element's
1507
- * checkValidity() runs before custom validators, and when it fails,
1508
- * reportValidity() surfaces the offending constraints as native bubbles and
1509
- * submission stops (onInvalidSubmit fires). onSubmit/onValidSubmit only run
1510
- * once every native constraint (required, type=email, minLength, ...) passes.
1511
- * Pass `shouldUseNativeValidation={false}` (or `createForm({shouldUseNativeValidation:
1512
- * false})`) to skip the native gate entirely for custom-validator-only
1513
- * forms — targets without checkValidity (React Native, toolbar buttons)
1514
- * are always exempt.
1515
- *
1516
- * The submit flow itself lives in the headless `handleSubmit` (see form.ts);
1517
- * this component is a thin wrapper that binds it to the rendered <form>.
1518
- */
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>. */
1519
1136
  type FormProps<T extends Record<string, any> = any> = Omit<React.FormHTMLAttributes<HTMLFormElement>, 'onSubmit'> & {
1520
1137
  form?: Form$1<T>;
1521
- /**
1522
- * Provide into an isolated context from `createFormContext()` instead of
1523
- * the module-level one — `<Form context={ProfileForm.context}>` keeps the
1524
- * component's full submit machinery while the factory's bound hooks
1525
- * (`ProfileForm.useField`, `ProfileForm.useFormContext`, ...) resolve this
1526
- * form from their private context. The module-level `useFormContext()` /
1527
- * `useField` do not see it; that is the point of the isolation. Omitted,
1528
- * the form lands in the module-level FormContext as before.
1529
- */
1138
+ /** Isolated context from `createFormContext()`: its bound hooks see this
1139
+ * form, the module-level ones do not. Defaults to FormContext. */
1530
1140
  context?: React.Context<Form$1<any> | null>;
1531
- /**
1532
- * The values baseline — a sync object, a Promise, or a thunk returning
1533
- * either ({@link Options.initialValues}). Async sources render the form
1534
- * empty and gate on `form.isLoading` until they resolve.
1535
- */
1141
+ /** Values baseline — sync object, Promise, or thunk; async sources gate on `isLoading`. */
1536
1142
  initialValues?: T | Promise<T> | (() => T | Promise<T>);
1537
- /**
1538
- * Form-level default for a bound field's unmount behavior
1539
- * ({@link Options.shouldUnregister}): `true` (the default) tombstones
1540
- * unmounted fields, `false` keeps their values.
1541
- */
1143
+ /** Default unmount behavior: `true` tombstones unmounted fields, `false` keeps values. */
1542
1144
  shouldUnregister?: boolean;
1543
- /**
1544
- * Validate on mount (see {@link Options.validateOnMount}): every
1545
- * mounted field with a validator kicks once after mount and the
1546
- * form-level `validate` (if any) runs once. A field's own
1547
- * `validateOnMount` prop overrides this flag.
1548
- */
1145
+ /** Validate on mount: each validator kicks once; a field's own prop overrides. */
1549
1146
  validateOnMount?: boolean;
1550
- /**
1551
- * Disable every bound field: the form-level flag fields OR with their
1552
- * own `disabled` option (a field cannot opt out). Seeded at create and
1553
- * kept in sync while this prop changes (undefined leaves the current
1554
- * flag untouched — toggle at runtime with `setDisabled`).
1555
- */
1147
+ /** Disable every bound field (fields OR with their own option); undefined leaves the flag untouched. */
1556
1148
  disabled?: boolean;
1557
- /**
1558
- * Form-level default for field validation's `asyncAlways`: a field
1559
- * whose `required` gate failed still runs its debounced validator, its
1560
- * result landing per-source alongside the gate's errors. A field's own
1561
- * `asyncAlways` prop overrides this flag.
1562
- */
1149
+ /** Form-level default for `asyncAlways`; a field's own prop overrides. */
1563
1150
  asyncAlways?: boolean;
1564
- /**
1565
- * Controlled external values. When the `values` reference changes, the
1566
- * new object is synced into the form (via setInitialValues semantics):
1567
- * uncommitted user edits are discarded -- master-detail semantics, where
1568
- * selecting another record replaces the draft -- while touched flags and
1569
- * errors are kept. Sync is reference-based: re-renders that pass the same
1570
- * `values` reference never clobber what the user is typing.
1571
- */
1151
+ /** Controlled external values: a new reference syncs via setInitialValues
1152
+ * (draft discarded, touched/errors kept); same reference never clobbers. */
1572
1153
  values?: T;
1573
- /** May be async the submit flow awaits it, so form.isSubmitting
1574
- * covers the entire flight. */
1154
+ /** May be async; `isSubmitting` covers the flight. */
1575
1155
  onSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;
1576
1156
  /** May be async, same as onSubmit. */
1577
1157
  onValidSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;
1578
- /**
1579
- * React 19 Server Action target: after validation passes (and after
1580
- * onSubmit/onValidSubmit), the validated, schema-coerced values are
1581
- * converted to FormData ({@link formDataFromValues} files, arrays and
1582
- * nested objects included) and dispatched to this callback, e.g.
1583
- * `action={createUser}` for a server action or
1584
- * `action={formData => startTransition(() => dispatch(formData))}` in a
1585
- * useActionState bridge. `isSubmitting` covers the whole flight.
1586
- *
1587
- * The callback may return an {@link ActionErrorResult}: its `errors`
1588
- * record lands on the form as per-field `type: 'server'` errors and the
1589
- * submit counts as unsuccessful — a server action rejecting the payload
1590
- * (422-style) hydrates the fields exactly like failed client
1591
- * validation. Return anything else to report success.
1592
- *
1593
- * Alternatively pass a URL string: it renders as the form's native
1594
- * `action` attribute, giving progressive enhancement — without
1595
- * JavaScript the browser posts the raw FormData to it (native
1596
- * constraint attributes from declarative `rules` still gate invalid
1597
- * submits), and with JavaScript the validated pipeline runs instead
1598
- * (pair the URL with `method="post"` and perform the network call in
1599
- * `onValidSubmit`; `handleSubmit` preventDefaults the native post).
1600
- */
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. */
1601
1162
  action?: string | ((formData: FormData) => void | Promise<void | ActionErrorResult>);
1602
- /**
1603
- * Called when validation fails.
1604
- * @param errors array of {path, type, message} entries in insertion
1605
- * order; path is the dotted field path ('a.b', 'list.0'), type is
1606
- * the error kind ('custom' for plain string errors, 'native' for
1607
- * failed DOM constraint validation), message is the display text
1608
- * @param values current form values
1609
- */
1163
+ /** Called when validation fails; errors are {path, type, message} entries
1164
+ * (type: 'custom' | 'native'). */
1610
1165
  onInvalidSubmit?: (errors: {
1611
1166
  path: string;
1612
1167
  type: string;
1613
1168
  message: string;
1614
1169
  }[], values: T) => void;
1615
- /**
1616
- * Focus the first field with an error after a failed submit: custom
1617
- * validation failures focus the first errored field, native constraint
1618
- * failures focus the first ':invalid' control. Defaults to true; pass
1619
- * false to disable.
1620
- */
1170
+ /** Focus the first errored field (or first ':invalid' control) after a failed submit. Default true. */
1621
1171
  shouldFocusError?: boolean;
1622
- /**
1623
- * Whether native constraint validation gates submission pass false
1624
- * for custom-validator-only forms (react-hook-form's
1625
- * `shouldUseNativeValidation`). Seeds the internally created form's
1626
- * flag (`useForm` create-time option) and overrides it for this form's
1627
- * submit wiring; with an external `form` prop only the submit wiring is
1628
- * affected. Defaults to the form's flag (`true`).
1629
- */
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. */
1630
1175
  shouldUseNativeValidation?: boolean;
1631
1176
  };
1632
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;
1633
1178
 
1634
- /**
1635
- * Props for {@link FormField}: every {@link UseFieldOptions} option plus a
1636
- * render-prop `children` receiving the bound field result.
1637
- */
1638
- type FormFieldProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = UseFieldOptions$1<TValues, TPath> & {
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> & {
1639
1182
  children: (field: UseFieldResult<TValues, TPath>) => React.ReactNode;
1640
1183
  };
1641
- /**
1642
- * Headless field bound through a render prop — the non-hook counterpart of
1643
- * {@link useField} for class components, callback-style consumers and
1644
- * library bridges where a hook cannot be called (Formik `<Field>` /
1645
- * TanStack `form.Field` shape).
1646
- *
1647
- * The child function receives the full {@link UseFieldResult} — value,
1648
- * error(s), onChange/onBlur, `disabled`, `focusRef`, the bound `form` —
1649
- * and renders whatever UI it wants; nothing is rendered when it returns
1650
- * null/undefined, so it can also gate conditional layout. Resolves its
1651
- * form from the module-level `FormContext` or the explicit `form` option
1652
- * (per-instance contexts from `createFormContext()` keep using their own
1653
- * `useField` hook).
1654
- */
1655
- declare function FormField<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments>({ children, ...options }: FormFieldProps<TValues, TPath>): React.ReactNode;
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;
1656
1189
 
1657
- /**
1658
- * The error-message element id a field's `aria-describedby` points at
1659
- * `fieldErrorId('a[0].b')` is `'a-0-b'`, the same id `<Field>`'s built-in
1660
- * `renderError` span carries. This is the library-level wiring convention:
1661
- * whenever a bound field (Field/Checkbox/Select, `useField`'s `inputProps`)
1662
- * has an error it sets `aria-invalid` and describes the element with this
1663
- * id, so a custom error component only needs
1664
- * `<span id={fieldErrorId(name)} role="alert">` to complete the
1665
- * accessible-name chain for screen readers.
1666
- * @param name the same field name passed to the bound component
1667
- */
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">`. */
1668
1194
  declare function fieldErrorId(name: Name): string;
1669
1195
 
1670
- /**
1671
- * Props shared by Field/Checkbox/Select. Generic so a typed form flows into
1672
- * the `validate` callback: with `form` (a `Form<Values>`) and `name`
1673
- * (a `FieldPath<Values>`) provided, `validate` receives the value at that
1674
- * path — `PathValueOf<Values, P>` instead of `any`. The defaults keep the
1675
- * bare `<Field name="x" />` (context-resolved, untyped) call sites exactly
1676
- * as permissive as before.
1677
- */
1678
- type UseFieldOptions<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = {
1679
- form?: Form$1<TValues>;
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'> & {
1680
1201
  name?: TPath;
1681
- initialValue?: any;
1682
- shouldUnregister?: boolean;
1683
- /**
1684
- * Field-level validator. The value argument is typed when the field is
1685
- * tied to a typed form (via the `form` prop); the return shape mirrors
1686
- * {@link Validator} — an error (string / FieldError / mixed array) or
1687
- * undefined when valid, possibly a Promise for async validation. The
1688
- * second argument carries the validation context (`meta.signal` aborts
1689
- * when the round is superseded).
1690
- */
1691
- validate?: ((value: PathValueOf<TValues, TPath>, meta: {
1692
- form: Form$1;
1693
- path: Path;
1694
- signal: AbortSignal;
1695
- }) => ReturnType<Validator>) | StandardSchemaV1<PathValueOf<TValues, TPath>>;
1696
- /**
1697
- * Declarative rules (required/min/max/minLength/maxLength/pattern,
1698
- * plus custom `validate` callbacks), compiled into a validator that
1699
- * runs before `validate`; failures land in the form's error state.
1700
- * The declarative subset is also rendered as native constraint
1701
- * attributes (`required`, `minLength`, `pattern`, …) onto the element
1702
- * for browser/AT hints — `:invalid` styling, screen-reader
1703
- * announcements — while the store pipeline stays the source of truth
1704
- * for messages (`renderError`/`aria-invalid` keep working; a user-passed
1705
- * `required`/`pattern`/… prop overrides the derived attribute). Passed
1706
- * through to useField — like validateDebounce it is never spread onto
1707
- * the DOM element.
1708
- */
1709
- rules?: FieldRules;
1710
- /**
1711
- * Milliseconds to debounce this field's validation kicks. Defaults to 0
1712
- * (validate immediately); only the last kick inside the window runs the
1713
- * validator, and `trigger` waits the window out. Passed through to
1714
- * useField/useValidate.
1715
- */
1716
- validateDebounce?: number;
1717
- /**
1718
- * Run this field's debounced validator even when its `required` gate
1719
- * failed (TanStack Form's `asyncAlways`): the gate's errors land
1720
- * immediately, the validator's own result lands alongside them
1721
- * per-source. Falls back to the form-level `createForm({asyncAlways})`.
1722
- * Passed through to useField.
1723
- */
1724
- asyncAlways?: boolean;
1725
- /**
1726
- * Validate this field once on mount (see {@link
1727
- * UseFieldOptions}' `validateOnMount`): overrides the form-level
1728
- * `createForm({validateOnMount})` / `<Form validateOnMount>` flag in
1729
- * either direction. Passed through to useField.
1730
- */
1731
- validateOnMount?: boolean;
1732
- /**
1733
- * Disable this field's control: OR-ed with the form-level flag
1734
- * (`createForm({disabled})` / `setDisabled`) — a field cannot opt out
1735
- * of a disabled form. Passed through to useField, like every option,
1736
- * never spread onto the DOM element from props.
1737
- */
1738
- disabled?: boolean;
1739
- /**
1740
- * Milliseconds to delay showing a newly appearing error (render layer
1741
- * only — `aria-invalid`/`renderError` wait out the window while the
1742
- * form's error state stays immediate for trigger/submit). An error
1743
- * that clears inside the window never shows; once visible, error
1744
- * changes apply immediately. Passed through to useField.
1745
- */
1746
- delayError?: number;
1747
- /**
1748
- * Field-level validation mode override: this field validates on its own
1749
- * schedule instead of the form's `mode` (other fields are unaffected);
1750
- * the form's `reValidateMode` still governs re-validation once the
1751
- * field has an error. Passed through to useField, never spread onto
1752
- * the DOM element.
1753
- */
1754
- mode?: ValidationMode;
1755
- /**
1756
- * Uncontrolled mode: render the element with `defaultValue` instead of
1757
- * `value` — typing re-renders nothing (the store still carries every
1758
- * write; errors/touched/disabled still re-render the field). The
1759
- * snapshot is pinned at mount; bulk operations (reset/setInitialValues)
1760
- * sync the DOM element directly without a render — RHF-register
1761
- * behavior (read live values with useValue/getValues). Passed through
1762
- * to useField, never spread onto the DOM element.
1763
- */
1764
- uncontrolled?: boolean;
1765
1202
  [key: string]: any;
1766
1203
  };
1767
- type FieldProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = UseFieldOptions<TValues, TPath> & {
1204
+ type FieldProps<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = UseFieldOptions<TValues, TPath> & {
1768
1205
  as?: React.ComponentType<any>;
1769
1206
  asProps?: Record<string, any>;
1770
- eventToValue?: (e: any) => any;
1771
1207
  valueToProps?: (value: any) => Record<string, any>;
1772
- /**
1773
- * Optional error renderer. When provided and the field has an error,
1774
- * Field renders `<span id={id} role="alert">{renderError(error, id)}</span>`
1775
- * next to the input. The input's aria-describedby points at that span's
1776
- * id (the same `fieldErrorId(name)` derivation) whenever the field has
1777
- * an error — with or without renderError — so custom error components
1778
- * that render the element themselves (using `fieldErrorId`) get the
1779
- * wiring for free.
1780
- */
1208
+ /** Error renderer: renders `<span id role="alert">` beside the input;
1209
+ * `aria-describedby` always points at that id (`fieldErrorId`). */
1781
1210
  renderError?: (error: string, id: string) => React.ReactNode;
1782
- /**
1783
- * Store `e.target.valueAsNumber` instead of the string value —
1784
- * react-hook-form's `register({valueAsNumber})` counterpart for number
1785
- * inputs (`<input type="number">`). `NaN` passes through as-is when the
1786
- * input cannot be parsed, matching RHF. An explicit `eventToValue`
1787
- * takes precedence.
1788
- */
1789
- valueAsNumber?: boolean;
1790
- /**
1791
- * Store `e.target.valueAsDate` instead of the string value — RHF's
1792
- * `register({valueAsDate})` counterpart for date/time inputs. `null`
1793
- * passes through when the input cannot be parsed. An explicit
1794
- * `eventToValue` takes precedence; combining with `valueAsNumber` is a
1795
- * TypeError.
1796
- */
1797
- valueAsDate?: boolean;
1798
1211
  };
1799
- /**
1800
- * The callable shape of {@link Field}: `form` + `name` flow their generics
1801
- * into `validate`'s value argument (`PathValueOf<TValues, TPath>`). A named
1802
- * interface rather than an inline `as <TValues, ...>() => ...` signature —
1803
- * same types, and the inline form trips no-use-before-define on the type
1804
- * parameters.
1805
- */
1212
+ /** Callable shape of {@link Field}; a named interface because the inline
1213
+ * `as <TValues,...>() => ...` form trips no-use-before-define. */
1806
1214
  type FieldComponent = {
1807
- <TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments>(props: FieldProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
1215
+ <TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(props: FieldProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
1808
1216
  };
1809
1217
  declare const Field: FieldComponent;
1810
- type CheckboxProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = UseFieldOptions<TValues, TPath>;
1811
- /**
1812
- * Callable shape of {@link Checkbox}: the same form-typed `validate`
1813
- * inference contract as {@link FieldComponent}.
1814
- */
1218
+ /** Callable shape of {@link Checkbox}: same form-typed `validate` contract
1219
+ * as {@link FieldComponent}. */
1815
1220
  type CheckboxComponent = {
1816
- <TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments>(props: CheckboxProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
1221
+ <TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(props: UseFieldOptions<TValues, TPath> & React.RefAttributes<HTMLInputElement>): React.ReactElement | null;
1817
1222
  };
1818
1223
  declare const Checkbox: CheckboxComponent;
1819
- type SelectProps<TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments> = UseFieldOptions<TValues, TPath> & {
1224
+ type SelectProps<TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>> = UseFieldOptions<TValues, TPath> & {
1820
1225
  multiple?: boolean;
1821
1226
  children?: React.ReactNode;
1822
1227
  };
1823
- /**
1824
- * Callable shape of {@link Select}: the same form-typed `validate`
1825
- * inference contract as {@link FieldComponent}.
1826
- */
1228
+ /** Callable shape of {@link Select}: same form-typed `validate` contract
1229
+ * as {@link FieldComponent}. */
1827
1230
  type SelectComponent = {
1828
- <TValues extends Record<string, any> = any, TPath extends FieldPath<TValues> | PathSegments = FieldPath<TValues> | PathSegments>(props: SelectProps<TValues, TPath> & React.RefAttributes<HTMLSelectElement>): React.ReactElement | null;
1231
+ <TValues extends Record<string, any> = any, TPath extends AnyPath<TValues> = AnyPath<TValues>>(props: SelectProps<TValues, TPath> & React.RefAttributes<HTMLSelectElement>): React.ReactElement | null;
1829
1232
  };
1830
1233
  declare const Select: SelectComponent;
1831
1234
 
1832
- export { Checkbox, CheckboxGroupContext, CheckboxGroupProvider, Field, FieldError, FieldErrorEntry, FieldErrors, FieldErrorsTree, FieldPath, FieldRules, Form, FormContext, FormEvents, FormField, Form$1 as FormInstance, FormProvider, Name, Options, Path, PathSegments, PathValueOf, RegisterOptions, RegisterProps, Select, StandardSchemaV1, ValidationMode, Validator, changeValue, changeValueByPath, createFormContext, emitChangeByPath, fieldErrorId, 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 };
1833
- export type { ActionErrorResult, FieldState, FormContextBundle, FormState, HandleSubmitOptions, RemoveFieldOptions, ResetFieldOptions, ResetOptions, SetFieldOptions, SubscribeEvent, SubscribeOptions, UseTransformOptions, UseValueOptions, WatchHandle, WatchScope };
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 };