attaform 0.27.5 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abstract.d.mts +5 -4
- package/dist/abstract.mjs +4 -3
- package/dist/chunks/fingerprint.mjs +0 -1
- package/dist/chunks/fingerprint2.mjs +1 -2
- package/dist/dev/abstract.mjs +4 -0
- package/dist/{chunks → dev/chunks}/dev-key-collision-warnings.mjs +0 -1
- package/dist/{chunks → dev/chunks}/devtools.mjs +5 -6
- package/dist/{chunks/fingerprint.cjs → dev/chunks/fingerprint.mjs} +7 -10
- package/dist/{chunks/fingerprint2.cjs → dev/chunks/fingerprint2.mjs} +32 -35
- package/dist/dev/directive.mjs +1 -0
- package/dist/dev/history.mjs +89 -0
- package/dist/dev/index.mjs +5 -0
- package/dist/dev/runtime/plugins/attaform.mjs +40 -0
- package/dist/{shared/attaform.f2zyNh5d.cjs → dev/shared/attaform-dev.6qxD-Yqo.mjs} +187 -43
- package/dist/{shared/attaform.CQN9R62B.cjs → dev/shared/attaform-dev.BJGA_UOS.mjs} +1 -4
- package/dist/{shared/attaform.Dc1mx48r.mjs → dev/shared/attaform-dev.BR8u0YOZ.mjs} +6 -7
- package/dist/dev/shared/attaform-dev.BXE2cr0L.mjs +220 -0
- package/dist/dev/shared/attaform-dev.By4PRjt0.mjs +248 -0
- package/dist/{shared/attaform.Cg_8gFQ7.mjs → dev/shared/attaform-dev.D2I8e_Mm.mjs} +132 -568
- package/dist/dev/shared/attaform-dev.Dr2YzS5B.mjs +197 -0
- package/dist/{shared/attaform.nMaz2C5P.mjs → dev/shared/attaform-dev.P7cseiEG.mjs} +178 -397
- package/dist/{shared/attaform.BypWgXRB.mjs → dev/shared/attaform-dev.WmuhD_CZ.mjs} +3955 -5029
- package/dist/{shared/attaform.Dkjh_F30.mjs → dev/shared/attaform-dev.oYrkP9dj.mjs} +160 -508
- package/dist/dev/zod-v3.mjs +17 -0
- package/dist/dev/zod-v4.mjs +16 -0
- package/dist/dev/zod.mjs +5 -0
- package/dist/directive.d.mts +20 -0
- package/dist/directive.mjs +1 -0
- package/dist/esbuild.mjs +0 -1
- package/dist/history.d.mts +59 -0
- package/dist/history.mjs +89 -0
- package/dist/index.d.mts +11 -5
- package/dist/index.mjs +5 -4
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.mjs +5 -2
- package/dist/rollup.mjs +0 -1
- package/dist/rspack.d.mts +6 -1
- package/dist/rspack.mjs +0 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +9 -8
- package/dist/runtime/plugins/attaform.mjs +1 -2
- package/dist/shared/{attaform.CIBMfxg9.d.ts → attaform.B4VkS43-.d.mts} +2 -2
- package/dist/shared/{attaform.Cg1rUfcF.cjs → attaform.B8k8JrmK.mjs} +3778 -5297
- package/dist/shared/attaform.BJGA_UOS.mjs +0 -1
- package/dist/shared/{attaform.CTiZ9Rrv.mjs → attaform.C09fpdLS.mjs} +172 -16
- package/dist/shared/{attaform.Bh8A6YAc.cjs → attaform.CJP3RkGa.mjs} +141 -590
- package/dist/shared/{attaform.CzL2CZ8U.d.ts → attaform.Cgu-hdSb.d.mts} +328 -78
- package/dist/shared/attaform.Cs2Rbdlo.mjs +0 -1
- package/dist/shared/{attaform.DcFDQVpa.d.ts → attaform.D5V4tZWq.d.mts} +79 -179
- package/dist/shared/{attaform.CF-EnyJn.cjs → attaform.D6DCnnQu.mjs} +11 -16
- package/dist/shared/attaform.DhnPb6nK.mjs +0 -1
- package/dist/shared/attaform.Dq4vWxuG.mjs +197 -0
- package/dist/shared/attaform.JfSWdEcb.d.mts +44 -0
- package/dist/shared/attaform.KvlEedlF.mjs +0 -1
- package/dist/shared/{attaform.Crv0RNiz.cjs → attaform.NLmerepI.mjs} +175 -557
- package/dist/shared/attaform.h0i6LijT.mjs +242 -0
- package/dist/shared/{attaform.Biytrv0-.cjs → attaform.uLbun31C.mjs} +204 -544
- package/dist/shared/attaform.v0fQtWyA.mjs +0 -1
- package/dist/shared/attaform.wfY8XFvm.mjs +197 -0
- package/dist/transforms.mjs +0 -1
- package/dist/vite.d.mts +17 -5
- package/dist/vite.mjs +24 -2
- package/dist/webpack.d.mts +6 -1
- package/dist/webpack.mjs +0 -1
- package/dist/zod-v3.d.mts +11 -6
- package/dist/zod-v3.mjs +17 -4
- package/dist/zod-v4.d.mts +12 -6
- package/dist/zod-v4.mjs +16 -4
- package/dist/zod.d.mts +4 -3
- package/dist/zod.mjs +5 -4
- package/package.json +23 -8
- package/skills/attaform/SKILL.md +2 -1
- package/dist/abstract.cjs +0 -48
- package/dist/abstract.cjs.map +0 -1
- package/dist/abstract.d.cts +0 -42
- package/dist/abstract.d.ts +0 -42
- package/dist/abstract.mjs.map +0 -1
- package/dist/chunks/dev-key-collision-warnings.cjs +0 -25
- package/dist/chunks/dev-key-collision-warnings.cjs.map +0 -1
- package/dist/chunks/dev-key-collision-warnings.mjs.map +0 -1
- package/dist/chunks/devtools.cjs +0 -157
- package/dist/chunks/devtools.cjs.map +0 -1
- package/dist/chunks/devtools.mjs.map +0 -1
- package/dist/chunks/fingerprint.cjs.map +0 -1
- package/dist/chunks/fingerprint.mjs.map +0 -1
- package/dist/chunks/fingerprint2.cjs.map +0 -1
- package/dist/chunks/fingerprint2.mjs.map +0 -1
- package/dist/esbuild.cjs +0 -28
- package/dist/esbuild.cjs.map +0 -1
- package/dist/esbuild.d.cts +0 -56
- package/dist/esbuild.d.ts +0 -56
- package/dist/esbuild.mjs.map +0 -1
- package/dist/index.cjs +0 -51
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -249
- package/dist/index.d.ts +0 -249
- package/dist/index.mjs.map +0 -1
- package/dist/nuxt.cjs +0 -84
- package/dist/nuxt.cjs.map +0 -1
- package/dist/nuxt.d.cts +0 -66
- package/dist/nuxt.d.ts +0 -66
- package/dist/nuxt.mjs.map +0 -1
- package/dist/rollup.cjs +0 -24
- package/dist/rollup.cjs.map +0 -1
- package/dist/rollup.d.cts +0 -35
- package/dist/rollup.d.ts +0 -35
- package/dist/rollup.mjs.map +0 -1
- package/dist/rspack.cjs +0 -10
- package/dist/rspack.cjs.map +0 -1
- package/dist/rspack.d.cts +0 -40
- package/dist/rspack.d.ts +0 -40
- package/dist/rspack.mjs.map +0 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +0 -7
- package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +0 -35
- package/dist/runtime/plugins/attaform.cjs +0 -43
- package/dist/runtime/plugins/attaform.cjs.map +0 -1
- package/dist/runtime/plugins/attaform.d.cts +0 -5
- package/dist/runtime/plugins/attaform.d.ts +0 -5
- package/dist/runtime/plugins/attaform.mjs.map +0 -1
- package/dist/shared/attaform.B3abZaCV.d.cts +0 -2484
- package/dist/shared/attaform.BJGA_UOS.mjs.map +0 -1
- package/dist/shared/attaform.Bh8A6YAc.cjs.map +0 -1
- package/dist/shared/attaform.Biytrv0-.cjs.map +0 -1
- package/dist/shared/attaform.Bn0IzhD_.cjs +0 -800
- package/dist/shared/attaform.Bn0IzhD_.cjs.map +0 -1
- package/dist/shared/attaform.BypWgXRB.mjs.map +0 -1
- package/dist/shared/attaform.C9fPTxjB.d.cts +0 -41
- package/dist/shared/attaform.C9fPTxjB.d.ts +0 -41
- package/dist/shared/attaform.CF-EnyJn.cjs.map +0 -1
- package/dist/shared/attaform.CJ1Z9Mz4.d.mts +0 -2484
- package/dist/shared/attaform.CQN9R62B.cjs.map +0 -1
- package/dist/shared/attaform.CTiZ9Rrv.mjs.map +0 -1
- package/dist/shared/attaform.Cg1rUfcF.cjs.map +0 -1
- package/dist/shared/attaform.Cg_8gFQ7.mjs.map +0 -1
- package/dist/shared/attaform.Crv0RNiz.cjs.map +0 -1
- package/dist/shared/attaform.Cs2Rbdlo.mjs.map +0 -1
- package/dist/shared/attaform.CzL2CZ8U.d.cts +0 -4713
- package/dist/shared/attaform.CzL2CZ8U.d.mts +0 -4713
- package/dist/shared/attaform.DRUT703x.d.cts +0 -56
- package/dist/shared/attaform.DRUT703x.d.ts +0 -56
- package/dist/shared/attaform.DYwyM5Cp.d.cts +0 -232
- package/dist/shared/attaform.Dc1mx48r.mjs.map +0 -1
- package/dist/shared/attaform.DhnPb6nK.mjs.map +0 -1
- package/dist/shared/attaform.Dkjh_F30.mjs.map +0 -1
- package/dist/shared/attaform.DoQm_Vkd.cjs +0 -58
- package/dist/shared/attaform.DoQm_Vkd.cjs.map +0 -1
- package/dist/shared/attaform.DrHOqB-d.d.mts +0 -232
- package/dist/shared/attaform.KvlEedlF.mjs.map +0 -1
- package/dist/shared/attaform.RaTzp1WF.cjs +0 -26
- package/dist/shared/attaform.RaTzp1WF.cjs.map +0 -1
- package/dist/shared/attaform.f2zyNh5d.cjs.map +0 -1
- package/dist/shared/attaform.nMaz2C5P.mjs.map +0 -1
- package/dist/shared/attaform.v0fQtWyA.mjs.map +0 -1
- package/dist/shared/attaform.yUrz7C2z.cjs +0 -29
- package/dist/shared/attaform.yUrz7C2z.cjs.map +0 -1
- package/dist/transforms.cjs +0 -12
- package/dist/transforms.cjs.map +0 -1
- package/dist/transforms.d.cts +0 -73
- package/dist/transforms.d.ts +0 -73
- package/dist/transforms.mjs.map +0 -1
- package/dist/vite.cjs +0 -363
- package/dist/vite.cjs.map +0 -1
- package/dist/vite.d.cts +0 -133
- package/dist/vite.d.ts +0 -133
- package/dist/vite.mjs.map +0 -1
- package/dist/webpack.cjs +0 -10
- package/dist/webpack.cjs.map +0 -1
- package/dist/webpack.d.cts +0 -37
- package/dist/webpack.d.ts +0 -37
- package/dist/webpack.mjs.map +0 -1
- package/dist/zod-v3.cjs +0 -53
- package/dist/zod-v3.cjs.map +0 -1
- package/dist/zod-v3.d.cts +0 -246
- package/dist/zod-v3.d.ts +0 -246
- package/dist/zod-v3.mjs.map +0 -1
- package/dist/zod-v4.cjs +0 -55
- package/dist/zod-v4.cjs.map +0 -1
- package/dist/zod-v4.d.cts +0 -172
- package/dist/zod-v4.d.ts +0 -172
- package/dist/zod-v4.mjs.map +0 -1
- package/dist/zod.cjs +0 -51
- package/dist/zod.cjs.map +0 -1
- package/dist/zod.d.cts +0 -7
- package/dist/zod.d.ts +0 -7
- package/dist/zod.mjs.map +0 -1
|
@@ -164,6 +164,65 @@ declare const ROOT_PATH_KEY: PathKey;
|
|
|
164
164
|
*/
|
|
165
165
|
declare function isPathPrefix(prefix: readonly Segment[], path: readonly Segment[]): boolean;
|
|
166
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Per-path field status. Replaced wholesale (not mutated in place) on
|
|
169
|
+
* every change. Five semantic groups:
|
|
170
|
+
*
|
|
171
|
+
* - `connected` — is a DOM element registered for this path?
|
|
172
|
+
* - `focused` / `blurred` — DOM-state flags. `null` while no element
|
|
173
|
+
* is connected (no DOM means the concepts don't apply); plain
|
|
174
|
+
* booleans once connected, with the invariant `blurred === !focused`
|
|
175
|
+
* enforced by `markFocused`.
|
|
176
|
+
* - `touched` — focus/blur history, not DOM state. Always a plain
|
|
177
|
+
* boolean: `false` at registration, sticky `true` after first blur,
|
|
178
|
+
* cleared only by `form.reset()` / `form.resetField(path)`. Persists
|
|
179
|
+
* across disconnects so v-if'd-away fields don't lose their touched
|
|
180
|
+
* state on rehide (wizard "show review of touched fields" patterns
|
|
181
|
+
* rely on this).
|
|
182
|
+
* - `interacted` — value-mutation history, not DOM state. Plain
|
|
183
|
+
* boolean: `false` at registration, sticky `true` once the user
|
|
184
|
+
* issues a value edit through the directive's input listeners
|
|
185
|
+
* (never on hydration, default seeding, or programmatic setValue);
|
|
186
|
+
* cleared with `touched` by `form.reset()` / `form.resetField(path)`.
|
|
187
|
+
* - `blurredAfterInteraction` — the first blur that follows a value
|
|
188
|
+
* edit (the field has been edited and then left). Plain boolean,
|
|
189
|
+
* sticky `true`. A tab-through blur with no prior edit does NOT set
|
|
190
|
+
* it (`interacted` is still false at that blur). Composes
|
|
191
|
+
* `interacted` with the departure; drives the default display gate.
|
|
192
|
+
*/
|
|
193
|
+
type FieldRecord = {
|
|
194
|
+
readonly path: Path;
|
|
195
|
+
readonly updatedAt: string | null;
|
|
196
|
+
readonly connected: boolean;
|
|
197
|
+
readonly focused: boolean | null;
|
|
198
|
+
readonly blurred: boolean | null;
|
|
199
|
+
readonly touched: boolean;
|
|
200
|
+
readonly interacted: boolean;
|
|
201
|
+
readonly blurredAfterInteraction: boolean;
|
|
202
|
+
};
|
|
203
|
+
/** Per-path DOM element tracking. Client-only. */
|
|
204
|
+
type ElementRecord = {
|
|
205
|
+
/**
|
|
206
|
+
* Original Path captured at first registration. Stored alongside the
|
|
207
|
+
* elements Set so the DOM-order sort cache can recover the structured
|
|
208
|
+
* Path without round-tripping through `JSON.parse(pathKey)`.
|
|
209
|
+
*/
|
|
210
|
+
readonly path: Path;
|
|
211
|
+
readonly elements: Set<HTMLElement>;
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* Per-path record stored in `originals`. Pairing `segments` with the tracked
|
|
215
|
+
* value means `dirty` and `resetField`'s container loop don't have to
|
|
216
|
+
* `JSON.parse(pathKey)` on every iteration — the canonical Path is already
|
|
217
|
+
* sitting next to the value it belongs to. PathKey still keys the Map (the
|
|
218
|
+
* stable string is the only collision-free identifier), but downstream
|
|
219
|
+
* iteration reads `segments` directly.
|
|
220
|
+
*/
|
|
221
|
+
type OriginalsRecord = {
|
|
222
|
+
readonly segments: Path;
|
|
223
|
+
readonly value: unknown;
|
|
224
|
+
};
|
|
225
|
+
|
|
167
226
|
/** Internal brand for the `Unset` type. Never exposed at runtime. */
|
|
168
227
|
declare const _unsetBrand: unique symbol;
|
|
169
228
|
/**
|
|
@@ -722,11 +781,13 @@ interface JsonObject {
|
|
|
722
781
|
* structured array — `['user', 'address', 0, 'line1']` for a nested
|
|
723
782
|
* field, `[]` (the root path) for a form-level error (root `.refine()`
|
|
724
783
|
* messages, `setErrors` entries with no path, hydration failures,
|
|
725
|
-
* server-emitted form banners).
|
|
726
|
-
*
|
|
727
|
-
*
|
|
784
|
+
* server-emitted form banners). Which form produced an error is
|
|
785
|
+
* envelope-level identity: the `ValidationResponse` / submit result
|
|
786
|
+
* that carries the list stamps `formKey` once, and aggregators that
|
|
787
|
+
* merge lists across forms (the wizard) stamp their own envelope. The
|
|
788
|
+
* optional `data` slot carries an arbitrary server payload.
|
|
728
789
|
*
|
|
729
|
-
* Returned by `validate()` / `
|
|
790
|
+
* Returned by `validate()` / `parse()` / `handleSubmit`'s
|
|
730
791
|
* `onError` callback, and accepted (leniently, as `ErrorInput`) by
|
|
731
792
|
* `form.setErrors`.
|
|
732
793
|
*/
|
|
@@ -741,8 +802,6 @@ type ValidationError = {
|
|
|
741
802
|
* literal empty-key field.
|
|
742
803
|
*/
|
|
743
804
|
path: (string | number)[];
|
|
744
|
-
/** Identifies which form produced this error. */
|
|
745
|
-
formKey: FormKey;
|
|
746
805
|
/**
|
|
747
806
|
* Stable machine identifier for the failure, scoped by prefix:
|
|
748
807
|
*
|
|
@@ -764,6 +823,23 @@ type ValidationError = {
|
|
|
764
823
|
*/
|
|
765
824
|
data?: Json | null;
|
|
766
825
|
};
|
|
826
|
+
/**
|
|
827
|
+
* One path's slot in the form's tagged error store. The two sources
|
|
828
|
+
* that can put an error at a path stay segregated inside the cell:
|
|
829
|
+
* `schema` holds the validation pipeline's verdicts, `user` holds
|
|
830
|
+
* `setErrors` entries (and their history / SSR replays). Reads merge
|
|
831
|
+
* schema -> derived-blank -> user; each writer replaces exactly its
|
|
832
|
+
* own side. Cells are immutable — every write replaces the whole cell
|
|
833
|
+
* (or deletes the key when both sides empty), so Vue's per-key Map
|
|
834
|
+
* tracking fires for any side's change. An empty side is the shared
|
|
835
|
+
* frozen `NO_ERRORS` array, never a fresh allocation.
|
|
836
|
+
*
|
|
837
|
+
* @internal
|
|
838
|
+
*/
|
|
839
|
+
type ErrorCell = {
|
|
840
|
+
readonly schema: readonly ValidationError[];
|
|
841
|
+
readonly user: readonly ValidationError[];
|
|
842
|
+
};
|
|
767
843
|
/**
|
|
768
844
|
* The lenient input shape `form.setErrors` accepts: a real `Error`, or
|
|
769
845
|
* a partial `ValidationError` where every field is optional.
|
|
@@ -773,20 +849,17 @@ type ValidationError = {
|
|
|
773
849
|
* the path-scoped `setErrors(path, …)` form, which stamps its own.
|
|
774
850
|
* - `code`: defaults to `atta:user-error`.
|
|
775
851
|
* - `data`: forwarded verbatim onto the produced `ValidationError`.
|
|
776
|
-
* - `formKey`: accepted but ignored — the form always stamps its own.
|
|
777
852
|
*
|
|
778
|
-
* Because every field is optional
|
|
779
|
-
* `
|
|
780
|
-
*
|
|
781
|
-
*
|
|
782
|
-
* friction.
|
|
853
|
+
* Because every field is optional, `ValidationError` is a subtype of
|
|
854
|
+
* `ErrorInput`: a `ValidationError[]` you read back, or a server
|
|
855
|
+
* response that already emits the shape, pipes straight into
|
|
856
|
+
* `form.setErrors` with no adapter.
|
|
783
857
|
*/
|
|
784
858
|
type ErrorInput = Error | {
|
|
785
859
|
message?: string;
|
|
786
860
|
path?: (string | number)[];
|
|
787
861
|
code?: string;
|
|
788
862
|
data?: Json | null;
|
|
789
|
-
formKey?: FormKey;
|
|
790
863
|
};
|
|
791
864
|
/** Settled validation result when the form (or subtree) parsed successfully. */
|
|
792
865
|
type ValidationResponseSuccess<TData> = {
|
|
@@ -831,10 +904,19 @@ type ValidationResponse<TData> = ValidationResponseSuccess<TData> | ValidationRe
|
|
|
831
904
|
type DefaultValuesResponse<TData> = ValidationResponseSuccess<TData> | ValidationResponseErrorWithData<TData>;
|
|
832
905
|
/**
|
|
833
906
|
* Trimmed `ValidationResponse` that omits the `data` payload. Used by
|
|
834
|
-
* `validate()`
|
|
835
|
-
*
|
|
907
|
+
* the reactive `validate()` status, whose consumers only need the
|
|
908
|
+
* success flag and error list.
|
|
836
909
|
*/
|
|
837
910
|
type ValidationResponseWithoutValue<Form> = Omit<ValidationResponse<Form>, 'data'>;
|
|
911
|
+
/**
|
|
912
|
+
* Options bag for `form.parse`. `commit: true` turns the pure read
|
|
913
|
+
* into an authoritative run: the verdict is committed to the error
|
|
914
|
+
* store at the parsed scope and in-flight per-field validation runs
|
|
915
|
+
* are cancelled first. Default `false`.
|
|
916
|
+
*/
|
|
917
|
+
type ParseOptions = {
|
|
918
|
+
readonly commit?: boolean;
|
|
919
|
+
};
|
|
838
920
|
/**
|
|
839
921
|
* Sync-or-async return shape for `AbstractSchema.validateAtPath`. The
|
|
840
922
|
* adapter returns the response inline when the schema and the
|
|
@@ -998,7 +1080,7 @@ type AbstractSchema<Form, GetValueFormType> = {
|
|
|
998
1080
|
* the gate accepts the consumer's raw value verbatim and stops
|
|
999
1081
|
* walking children — storage holds the user's input, and the
|
|
1000
1082
|
* normalizer fires during `safeParse` (handleSubmit / validate /
|
|
1001
|
-
*
|
|
1083
|
+
* parse), not at `setValue` time.
|
|
1002
1084
|
*
|
|
1003
1085
|
* Path-prefix semantic: returns true if ANY ancestor of `path`
|
|
1004
1086
|
* resolves to such a wrapper, so descendants under a preprocess-
|
|
@@ -1010,25 +1092,24 @@ type AbstractSchema<Form, GetValueFormType> = {
|
|
|
1010
1092
|
* Distinguish a tuple (fixed-length, position-typed) from an
|
|
1011
1093
|
* unbounded array at `path`. The runtime calls this on every
|
|
1012
1094
|
* `mergeStructural` / `setAtPathWithSchemaFill` write that descends
|
|
1013
|
-
* into an array branch
|
|
1014
|
-
*
|
|
1015
|
-
* (up to 1024 schema lookups) the runtime previously used.
|
|
1095
|
+
* into an array branch, and the answer is definitive — the runtime
|
|
1096
|
+
* never second-guesses it.
|
|
1016
1097
|
*
|
|
1017
1098
|
* Return values:
|
|
1018
1099
|
* - `number` → tuple of this structural length. The runtime pads
|
|
1019
1100
|
* the consumer to this length and recurses position-by-position.
|
|
1020
|
-
* - `null` →
|
|
1021
|
-
* length and reuses one element default for
|
|
1022
|
-
*
|
|
1023
|
-
*
|
|
1024
|
-
*
|
|
1025
|
-
*
|
|
1101
|
+
* - `null` → not a tuple. Covers the unbounded array (the runtime
|
|
1102
|
+
* uses the consumer's length and reuses one element default for
|
|
1103
|
+
* every position) and every path that doesn't resolve to an
|
|
1104
|
+
* array at all — there `getDefaultAtPath` yields no element
|
|
1105
|
+
* default either, so the consumer's array passes through
|
|
1106
|
+
* unchanged.
|
|
1026
1107
|
*
|
|
1027
1108
|
* Wrappers (optional / nullable / default / readonly / catch /
|
|
1028
1109
|
* pipe / lazy) are peeled transparently before the type check, so
|
|
1029
1110
|
* `optional(z.tuple([...]))` reports its tuple length.
|
|
1030
1111
|
*/
|
|
1031
|
-
arrayShapeAtPath(path: Path): number | null
|
|
1112
|
+
arrayShapeAtPath(path: Path): number | null;
|
|
1032
1113
|
/**
|
|
1033
1114
|
* Whether the schema at `path` is a FIXED object: a closed set of
|
|
1034
1115
|
* declared keys (`z.object`), as opposed to an open or union container
|
|
@@ -1307,6 +1388,19 @@ type AbstractSchema<Form, GetValueFormType> = {
|
|
|
1307
1388
|
* toward returning `true` when in doubt.
|
|
1308
1389
|
*/
|
|
1309
1390
|
hasContainerOrRootRefine?(): boolean;
|
|
1391
|
+
/**
|
|
1392
|
+
* `true` when the schema tree contains at least one discriminated
|
|
1393
|
+
* union at any depth (inside arrays, tuples, records, and lazy
|
|
1394
|
+
* schemas included). The store computes its per-form DU capability
|
|
1395
|
+
* flag from this once at construction: `false` lets every write skip
|
|
1396
|
+
* the cross-variant ancestor guard and the variant-reshape dispatch,
|
|
1397
|
+
* and DU stub correction never runs. Optional: an adapter that omits
|
|
1398
|
+
* it is treated as containing unions, keeping the conservative
|
|
1399
|
+
* per-write probes on. Never return `false` for a schema that DOES
|
|
1400
|
+
* hold a discriminated union — that disables variant reshape and
|
|
1401
|
+
* stub correction for the form.
|
|
1402
|
+
*/
|
|
1403
|
+
hasDiscriminatedUnions?(): boolean;
|
|
1310
1404
|
};
|
|
1311
1405
|
/**
|
|
1312
1406
|
* Adapter-returned info for a discriminated union — its discriminator
|
|
@@ -1422,7 +1516,7 @@ type OnInvalidSubmitPolicy = 'none' | 'focus-first-error' | 'scroll-to-first-err
|
|
|
1422
1516
|
* registered field. No debounce — `debounceMs` is rejected by the
|
|
1423
1517
|
* type.
|
|
1424
1518
|
* - `'submit'`: no live validation. `handleSubmit` and explicit
|
|
1425
|
-
* `validate()` / `
|
|
1519
|
+
* `validate()` / `parse()` calls are the only validation
|
|
1426
1520
|
* surfaces. `debounceMs` is rejected by the type.
|
|
1427
1521
|
*/
|
|
1428
1522
|
type ValidateOn = 'change' | 'blur' | 'submit';
|
|
@@ -1499,8 +1593,8 @@ type WriteMeta = {
|
|
|
1499
1593
|
readonly skipDiscriminatorReshape?: boolean;
|
|
1500
1594
|
/**
|
|
1501
1595
|
* Records an array structural mutation precisely enough to replay the
|
|
1502
|
-
* exact index permutation it produced, set by
|
|
1503
|
-
*
|
|
1596
|
+
* exact index permutation it produced, set by the typed array helpers
|
|
1597
|
+
* in `array-engine.ts`. `setValueAtPath` uses it to surgically clear variant memory
|
|
1504
1598
|
* for the indices the operation invalidated. Without this hint, a raw
|
|
1505
1599
|
* whole-array `setValue(arrayPath, [...])` clears all memory under the
|
|
1506
1600
|
* array (the runtime can't tell which indices stayed put). Internal —
|
|
@@ -1551,19 +1645,68 @@ type WriteMeta = {
|
|
|
1551
1645
|
readonly hydration?: boolean;
|
|
1552
1646
|
};
|
|
1553
1647
|
/**
|
|
1554
|
-
*
|
|
1648
|
+
* The store slice the history runtime binds to. Structural on purpose:
|
|
1649
|
+
* `historyPlugin()` ships from the separate `attaform/history` entry, so
|
|
1650
|
+
* the runtime receives the store through this seam instead of importing
|
|
1651
|
+
* the store module (which would pull the history internals onto every
|
|
1652
|
+
* form's eager path). A FormStore satisfies it as-is.
|
|
1555
1653
|
*
|
|
1556
|
-
*
|
|
1557
|
-
|
|
1654
|
+
* @internal
|
|
1655
|
+
*/
|
|
1656
|
+
type HistoryKernel = {
|
|
1657
|
+
readonly form: Ref<unknown>;
|
|
1658
|
+
readonly blankPaths: Set<PathKey>;
|
|
1659
|
+
readonly errorCells: Map<PathKey, ErrorCell>;
|
|
1660
|
+
onFormChange(listener: (next: unknown, meta?: WriteMeta) => void): () => void;
|
|
1661
|
+
applyFormReplacement(next: unknown): void;
|
|
1662
|
+
restoreErrorCells(entries: ReadonlyArray<readonly [PathKey, ErrorCell]>): void;
|
|
1663
|
+
};
|
|
1664
|
+
/**
|
|
1665
|
+
* The live undo/redo runtime a {@link HistoryPlugin} attaches to one
|
|
1666
|
+
* form. Cached on the FormStore so every `useForm` / `injectForm`
|
|
1667
|
+
* consumer of the same key shares one chain; `buildFormApi` adapts it
|
|
1668
|
+
* into the public `form.history` namespace.
|
|
1558
1669
|
*
|
|
1559
|
-
*
|
|
1670
|
+
* @internal
|
|
1671
|
+
*/
|
|
1672
|
+
type HistoryModule = {
|
|
1673
|
+
undo(): boolean;
|
|
1674
|
+
redo(): boolean;
|
|
1675
|
+
clear(): void;
|
|
1676
|
+
canUndo: Readonly<ComputedRef<boolean>>;
|
|
1677
|
+
canRedo: Readonly<ComputedRef<boolean>>;
|
|
1678
|
+
historySize: Readonly<ComputedRef<number>>;
|
|
1679
|
+
dispose(): void;
|
|
1680
|
+
};
|
|
1681
|
+
/**
|
|
1682
|
+
* Opt-in undo/redo, created by `historyPlugin()` from `attaform/history`
|
|
1683
|
+
* and passed via `useForm({ history })`:
|
|
1684
|
+
*
|
|
1685
|
+
* ```ts
|
|
1686
|
+
* import { historyPlugin } from 'attaform/history'
|
|
1687
|
+
*
|
|
1688
|
+
* const form = useForm({ schema, history: historyPlugin({ max: 200 }) })
|
|
1689
|
+
* ```
|
|
1690
|
+
*
|
|
1691
|
+
* When enabled, every mutation records a position; `form.history.undo()`
|
|
1560
1692
|
* / `form.history.redo()` walk the chain. `reset()` is itself a mutation —
|
|
1561
1693
|
* the pre-reset state stays one undo away. Persistence hydration is the
|
|
1562
1694
|
* floor: after hydrate applies, the chain reseeds with the hydrated value
|
|
1563
1695
|
* and `undo()` cannot reach the transient pre-hydration default.
|
|
1696
|
+
*
|
|
1697
|
+
* One plugin instance is a reusable configuration, not per-form state:
|
|
1698
|
+
* passing the same instance to several forms (or setting it once via
|
|
1699
|
+
* `createAttaform({ defaults: { history } })`) gives each form its own
|
|
1700
|
+
* independent chain.
|
|
1564
1701
|
*/
|
|
1565
|
-
type
|
|
1566
|
-
|
|
1702
|
+
type HistoryPlugin = {
|
|
1703
|
+
/**
|
|
1704
|
+
* Bind a fresh history runtime to one form's store. Called by
|
|
1705
|
+
* `useForm` when the store is first created.
|
|
1706
|
+
*
|
|
1707
|
+
* @internal
|
|
1708
|
+
*/
|
|
1709
|
+
readonly attach: (kernel: HistoryKernel) => HistoryModule;
|
|
1567
1710
|
};
|
|
1568
1711
|
/**
|
|
1569
1712
|
* Consolidated undo/redo namespace at `form.history`. All history-related
|
|
@@ -1781,16 +1924,17 @@ type UseFormConfiguration<Form extends GenericForm, GetValueFormType, Schema ext
|
|
|
1781
1924
|
*/
|
|
1782
1925
|
debounceMs?: number;
|
|
1783
1926
|
/**
|
|
1784
|
-
* Opt-in undo/redo. Off by default. `
|
|
1785
|
-
*
|
|
1927
|
+
* Opt-in undo/redo. Off by default. Pass `historyPlugin()` from
|
|
1928
|
+
* `attaform/history` — a 128-position cap by default,
|
|
1929
|
+
* `historyPlugin({ max: N })` to tune it.
|
|
1786
1930
|
*
|
|
1787
|
-
* Every mutation records a
|
|
1931
|
+
* Every mutation records a position. `form.history.undo()` walks
|
|
1788
1932
|
* one step back; `form.history.redo()` walks one step forward.
|
|
1789
1933
|
* `reset()` is itself a mutation, so the pre-reset state stays one
|
|
1790
1934
|
* undo away. The consolidated `form.history` namespace also exposes
|
|
1791
1935
|
* `clear()`, `canUndo`, `canRedo`, and `size`.
|
|
1792
1936
|
*/
|
|
1793
|
-
history?:
|
|
1937
|
+
history?: HistoryPlugin;
|
|
1794
1938
|
/**
|
|
1795
1939
|
* Whether to remember the typed state of each discriminated-union
|
|
1796
1940
|
* variant across switches. Default `true`.
|
|
@@ -1936,8 +2080,8 @@ type AttaformDefaults = {
|
|
|
1936
2080
|
* `validateOn` resolves to `'change'`. Default `0` (synchronous).
|
|
1937
2081
|
*/
|
|
1938
2082
|
debounceMs?: number;
|
|
1939
|
-
/** Default for `useForm({ history })
|
|
1940
|
-
history?:
|
|
2083
|
+
/** Default for `useForm({ history })` — a `historyPlugin()` instance. */
|
|
2084
|
+
history?: HistoryPlugin;
|
|
1941
2085
|
/** Default for `useForm({ rememberVariants })`. */
|
|
1942
2086
|
rememberVariants?: boolean;
|
|
1943
2087
|
/** Default for `useForm({ disabled })` — freeze the form's data. */
|
|
@@ -2016,7 +2160,7 @@ type AttaformDefaults = {
|
|
|
2016
2160
|
*
|
|
2017
2161
|
* "Permissive fallback" means storage and reads keep working at any
|
|
2018
2162
|
* depth; only the per-write type gate stops checking past the cap.
|
|
2019
|
-
* Full schema validation (`
|
|
2163
|
+
* Full schema validation (`parse`, `handleSubmit`) still runs
|
|
2020
2164
|
* against the real schema, so refinement errors at any depth still
|
|
2021
2165
|
* surface — the cap only affects the *write-time gate*.
|
|
2022
2166
|
*
|
|
@@ -2425,6 +2569,49 @@ type RegisterOptions = {
|
|
|
2425
2569
|
*/
|
|
2426
2570
|
autoAria?: boolean;
|
|
2427
2571
|
};
|
|
2572
|
+
/**
|
|
2573
|
+
* The narrow kernel surface the DOM binding drives. Structurally a
|
|
2574
|
+
* subset of the form store: the field-record connect/disconnect
|
|
2575
|
+
* transitions, focus marking (which owns blur-validation), the record
|
|
2576
|
+
* and merged-error reads the focus walk needs, and the async-transform
|
|
2577
|
+
* abort for a fully-detached path.
|
|
2578
|
+
* @internal
|
|
2579
|
+
*/
|
|
2580
|
+
type DomBindingKernel = {
|
|
2581
|
+
readonly noteDomConnected: (path: Path) => void;
|
|
2582
|
+
readonly noteDomDisconnected: (path: Path) => void;
|
|
2583
|
+
readonly markFocused: (path: Path, focused: boolean, meta?: {
|
|
2584
|
+
readonly instance?: WriteMeta['instance'];
|
|
2585
|
+
}) => void;
|
|
2586
|
+
readonly getFieldRecord: (path: Path) => FieldRecord | undefined;
|
|
2587
|
+
readonly getErrorsForPath: (path: Path) => ValidationError[];
|
|
2588
|
+
readonly cancelTransformsUnder: (prefix: Path) => void;
|
|
2589
|
+
};
|
|
2590
|
+
/**
|
|
2591
|
+
* The form store's DOM slice: the element registry backing
|
|
2592
|
+
* `field.element` / `field.elements`, no-latch host focus anchors, and
|
|
2593
|
+
* first-error focus resolution. Implemented in the directive cluster's
|
|
2594
|
+
* lazy graph and armed into the store's `domBinding` slot on first use
|
|
2595
|
+
* (see `RegisterValue.ensureDomBinding`); a `null` slot means nothing
|
|
2596
|
+
* in the app ever registered an element.
|
|
2597
|
+
* @internal
|
|
2598
|
+
*/
|
|
2599
|
+
type AttaformDomBinding = {
|
|
2600
|
+
readonly elements: Map<PathKey, ElementRecord>;
|
|
2601
|
+
readonly attach: (segments: Path, element: HTMLElement, formInstanceId: string, instanceMeta: WriteMeta['instance'] | undefined) => void;
|
|
2602
|
+
readonly detach: (segments: Path, element: HTMLElement) => void;
|
|
2603
|
+
readonly markHostConnected: (segments: Path, connected: boolean, hostEl: HTMLElement, formInstanceId: string) => void;
|
|
2604
|
+
readonly getFirstErrorElement: (formInstanceId: string) => {
|
|
2605
|
+
path: Path;
|
|
2606
|
+
element: HTMLElement;
|
|
2607
|
+
} | null;
|
|
2608
|
+
};
|
|
2609
|
+
/**
|
|
2610
|
+
* Factory the directive / `useRegister` inject through
|
|
2611
|
+
* `RegisterValue.ensureDomBinding` to arm a store's `domBinding` slot.
|
|
2612
|
+
* @internal
|
|
2613
|
+
*/
|
|
2614
|
+
type DomBindingFactory = (kernel: DomBindingKernel) => AttaformDomBinding;
|
|
2428
2615
|
/**
|
|
2429
2616
|
* The object returned by `form.register(path)`. Pass it to a native
|
|
2430
2617
|
* input via `v-register`:
|
|
@@ -2530,6 +2717,17 @@ type RegisterValue<Value = unknown> = Readonly<{
|
|
|
2530
2717
|
* @internal
|
|
2531
2718
|
*/
|
|
2532
2719
|
hasRegisteredDescendant: (hostElement: HTMLElement) => boolean;
|
|
2720
|
+
/**
|
|
2721
|
+
* Arm this binding's form store with the DOM-binding implementation
|
|
2722
|
+
* (element registry, focus listeners, first-error focus resolution).
|
|
2723
|
+
* The implementation lives in the directive cluster's lazy graph, so
|
|
2724
|
+
* the directive and `useRegister` inject its factory here before any
|
|
2725
|
+
* element call; once armed, the store's `domBinding` slot serves every
|
|
2726
|
+
* later registration. Optional so hand-rolled RegisterValues, which
|
|
2727
|
+
* own their element handling, don't have to declare it.
|
|
2728
|
+
* @internal
|
|
2729
|
+
*/
|
|
2730
|
+
ensureDomBinding?: (factory: DomBindingFactory) => void;
|
|
2533
2731
|
/**
|
|
2534
2732
|
* Canonical, JSON-encoded path key for this binding (e.g.
|
|
2535
2733
|
* `'["items",0,"name"]'`). Useful for stable Map / Set keys, log
|
|
@@ -2958,10 +3156,10 @@ type RegisterModelDynamicCustomDirective = ObjectDirective<HTMLInputElement | HT
|
|
|
2958
3156
|
* See `RegisterTextModifier` / `RegisterSelectModifier` for
|
|
2959
3157
|
* per-modifier semantics.
|
|
2960
3158
|
*
|
|
2961
|
-
*
|
|
2962
|
-
* `attaform/
|
|
2963
|
-
* directive itself — it's exposed for
|
|
2964
|
-
* directives manually.
|
|
3159
|
+
* Delivered by the Vite / Nuxt plugin's compile-time binding, or by
|
|
3160
|
+
* `installVRegister(app)` from `attaform/directive` everywhere else.
|
|
3161
|
+
* Most consumers don't import the directive itself — it's exposed for
|
|
3162
|
+
* integrations that install directives manually.
|
|
2965
3163
|
*/
|
|
2966
3164
|
type RegisterDirective = RegisterTextCustomDirective | RegisterCheckboxCustomDirective | RegisterSelectCustomDirective | RegisterRadioCustomDirective | RegisterModelDynamicCustomDirective;
|
|
2967
3165
|
/**
|
|
@@ -3206,7 +3404,7 @@ type FieldState<Value = unknown> = {
|
|
|
3206
3404
|
* `true` while a per-field validation run is in flight at this path.
|
|
3207
3405
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
3208
3406
|
* cross-field re-validations targeting this path. Whole-form
|
|
3209
|
-
* `validate()` / `
|
|
3407
|
+
* `validate()` / `parse()` calls drive `form.meta.validating`
|
|
3210
3408
|
* only — they don't flip per-field flags.
|
|
3211
3409
|
*
|
|
3212
3410
|
* Per-field analogue of `form.meta.validating`. Use for a tight
|
|
@@ -3637,12 +3835,20 @@ type FieldStateMap<Form extends GenericForm> = LeafWalker<Form, 'field'> & {
|
|
|
3637
3835
|
*/
|
|
3638
3836
|
<P extends string>(path: P): FieldCallResult<Form, P>;
|
|
3639
3837
|
/**
|
|
3640
|
-
* Tuple-segment form.
|
|
3641
|
-
*
|
|
3642
|
-
*
|
|
3643
|
-
*
|
|
3838
|
+
* Tuple-segment form. The segment-array spelling of the string
|
|
3839
|
+
* call-form above, for a path built from variables — the two resolve
|
|
3840
|
+
* to the same proxy, so `form.fields(['users', i, 'email'])` and
|
|
3841
|
+
* `form.fields(\`users.${i}.email\`)` are interchangeable.
|
|
3842
|
+
*
|
|
3843
|
+
* Resolves to that path's `FieldState`, which at a container is its
|
|
3844
|
+
* rolled-up aggregate (`displayState`, `valid`, `dirty`, ... all
|
|
3845
|
+
* exist regardless of the value type), exactly as the string form
|
|
3846
|
+
* does. Note this is the CALL form: it hands back the path's state,
|
|
3847
|
+
* not a drillable sub-proxy. To walk into a container's children use
|
|
3848
|
+
* dot/bracket access (`form.fields.users[i].email`), which is what
|
|
3849
|
+
* descends.
|
|
3644
3850
|
*/
|
|
3645
|
-
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)):
|
|
3851
|
+
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): FieldState<NestedType<Form, JoinSegments<S>>>;
|
|
3646
3852
|
/**
|
|
3647
3853
|
* Dynamic-array fallback for callers passing `Path`-typed (runtime)
|
|
3648
3854
|
* segment arrays — e.g. forwarding `RegisterValue.segments` to
|
|
@@ -4165,19 +4371,6 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4165
4371
|
* settles to results from the most recent call.
|
|
4166
4372
|
*/
|
|
4167
4373
|
validate: (path?: FlatPath<Form>) => Readonly<Ref<ReactiveValidationStatus<Form>>>;
|
|
4168
|
-
/**
|
|
4169
|
-
* Run validation once and return the result. Unlike `validate()`,
|
|
4170
|
-
* this does not subscribe to form reactivity.
|
|
4171
|
-
*
|
|
4172
|
-
* ```ts
|
|
4173
|
-
* const result = await form.validateAsync()
|
|
4174
|
-
* if (!result.success) showErrors(result.errors)
|
|
4175
|
-
* ```
|
|
4176
|
-
*
|
|
4177
|
-
* Pass a path to validate a subtree. `state.validating` flips
|
|
4178
|
-
* `true` while the promise is in flight.
|
|
4179
|
-
*/
|
|
4180
|
-
validateAsync: (path?: FlatPath<Form>) => Promise<ValidationResponseWithoutValue<Form>>;
|
|
4181
4374
|
/**
|
|
4182
4375
|
* Resolve once every in-flight async `register({ transforms })` run
|
|
4183
4376
|
* has settled — globally, or (with `path`) only at-or-under that path.
|
|
@@ -4199,9 +4392,9 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4199
4392
|
*/
|
|
4200
4393
|
settleTransforms: (path?: FlatPath<Form>) => Promise<void>;
|
|
4201
4394
|
/**
|
|
4202
|
-
* Imperative one-shot parse.
|
|
4203
|
-
*
|
|
4204
|
-
*
|
|
4395
|
+
* Imperative one-shot parse. Runs the full pipeline — refinements,
|
|
4396
|
+
* `.transform()`s, blank-required composition — against the current
|
|
4397
|
+
* form snapshot and RETAINS the parsed data.
|
|
4205
4398
|
*
|
|
4206
4399
|
* Storage holds the "honest input view" — values you wrote, with
|
|
4207
4400
|
* preprocess normalization applied but `.transform()` deferred. For
|
|
@@ -4219,16 +4412,31 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4219
4412
|
* }
|
|
4220
4413
|
* ```
|
|
4221
4414
|
*
|
|
4415
|
+
* By default the call is a PURE read: nothing is written to
|
|
4416
|
+
* `form.errors`, and in-flight per-field validation runs are left
|
|
4417
|
+
* alone. Pass `{ commit: true }` to make the run authoritative —
|
|
4418
|
+
* the verdict is committed to the error store at the parsed scope
|
|
4419
|
+
* and any in-flight per-field runs are cancelled first (mirroring
|
|
4420
|
+
* `handleSubmit`), so `await form.parse('email', { commit: true })`
|
|
4421
|
+
* lands a deterministic view of `form.errors.email`:
|
|
4422
|
+
*
|
|
4423
|
+
* ```ts
|
|
4424
|
+
* const result = await form.parse({ commit: true })
|
|
4425
|
+
* if (!result.success) showErrors(result.errors)
|
|
4426
|
+
* ```
|
|
4427
|
+
*
|
|
4222
4428
|
* Always async, and there is no synchronous variant by design: a
|
|
4223
4429
|
* schema can carry async refinements or transforms, so a sync parse
|
|
4224
4430
|
* would silently miss them the moment one is added. One always-
|
|
4225
4431
|
* awaited `parse` closes that category of bug entirely. The returned
|
|
4226
4432
|
* promise never rejects (a thrown adapter lands as a `success: false`
|
|
4227
4433
|
* response). Pass a path to parse a subtree only. `meta.validating`
|
|
4228
|
-
* flips `true` while the promise is in flight
|
|
4229
|
-
* validateAsync).
|
|
4434
|
+
* flips `true` while the promise is in flight.
|
|
4230
4435
|
*/
|
|
4231
|
-
parse:
|
|
4436
|
+
parse: {
|
|
4437
|
+
(path?: FlatPath<Form>, options?: ParseOptions): Promise<ValidationResponse<GetValueFormType>>;
|
|
4438
|
+
(options: ParseOptions): Promise<ValidationResponse<GetValueFormType>>;
|
|
4439
|
+
};
|
|
4232
4440
|
/**
|
|
4233
4441
|
* Bind a path to a native input via `v-register`. Returns a
|
|
4234
4442
|
* `RegisterValue` carrying the live ref and event handlers the
|
|
@@ -4583,11 +4791,8 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4583
4791
|
*/
|
|
4584
4792
|
applyInvalidSubmitPolicy: (policy?: OnInvalidSubmitPolicy) => void;
|
|
4585
4793
|
/**
|
|
4586
|
-
* Programmatically mark fields as touched — the
|
|
4587
|
-
*
|
|
4588
|
-
* the gap when fields are populated without a DOM gesture (post-
|
|
4589
|
-
* import, paste, autofill, server-seeded values you want to
|
|
4590
|
-
* validate immediately).
|
|
4794
|
+
* Programmatically mark fields as `touched` — the descriptive
|
|
4795
|
+
* "this field was visited" flag.
|
|
4591
4796
|
*
|
|
4592
4797
|
* ```ts
|
|
4593
4798
|
* form.touch('email') // one leaf
|
|
@@ -4596,12 +4801,57 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4596
4801
|
* form.touch() // every leaf in the form
|
|
4597
4802
|
* ```
|
|
4598
4803
|
*
|
|
4804
|
+
* **This does not reveal errors under the default display
|
|
4805
|
+
* heuristic.** `touched` also flips on a bare focus → blur with no
|
|
4806
|
+
* edit, so the library-default gate deliberately ignores it and
|
|
4807
|
+
* reads `blurredAfterInteraction` instead — the stricter bit that
|
|
4808
|
+
* only a blur *following* an edit sets. Reach for `touch()` when a
|
|
4809
|
+
* custom `getDisplayState` reducer or your analytics reads
|
|
4810
|
+
* `touched`; reach for {@link UseFormReturnType.interact} to make
|
|
4811
|
+
* seeded or imported values surface their errors.
|
|
4812
|
+
*
|
|
4599
4813
|
* Pure flag write — does not mutate value, focused, blurred, or
|
|
4600
4814
|
* trigger validation. Idempotent: re-calling on an already-touched
|
|
4601
4815
|
* field is a no-op. Touched is sticky-true; pair with
|
|
4602
4816
|
* `form.reset()` / `form.resetField()` to clear.
|
|
4603
4817
|
*/
|
|
4604
4818
|
touch: (path?: FlatPath<Form> | (string | number)[]) => void;
|
|
4819
|
+
/**
|
|
4820
|
+
* Simulate a complete focus → edit → blur over every leaf under
|
|
4821
|
+
* `path` (the whole form when omitted), so values that arrived
|
|
4822
|
+
* without a DOM gesture reveal their errors under the default
|
|
4823
|
+
* display heuristic.
|
|
4824
|
+
*
|
|
4825
|
+
* ```ts
|
|
4826
|
+
* form.interact('profile') // arm one subtree
|
|
4827
|
+
* await form.interact(['members', 2]) // errors committed on resolve
|
|
4828
|
+
* form.interact() // every leaf in the form
|
|
4829
|
+
* ```
|
|
4830
|
+
*
|
|
4831
|
+
* Flips the full interaction ladder (`touched`, `interacted`, and
|
|
4832
|
+
* `blurredAfterInteraction`) and runs the subtree's validation, so
|
|
4833
|
+
* the default gate — `submissionAttempts > 0 ||
|
|
4834
|
+
* blurredAfterInteraction` — opens through its front door. Use it
|
|
4835
|
+
* to arm one region's errors without a form-wide submit, which
|
|
4836
|
+
* would light up every other field on the page: a field-array row
|
|
4837
|
+
* edited in a modal, a server-seeded section, a pasted import.
|
|
4838
|
+
*
|
|
4839
|
+
* Walks schema leaves, so it reaches fields that are currently
|
|
4840
|
+
* `v-if`'d away or were never mounted; the flags are sticky, so
|
|
4841
|
+
* such a subtree stays revealed when it remounts.
|
|
4842
|
+
*
|
|
4843
|
+
* Flags land synchronously — the returned promise resolves once the
|
|
4844
|
+
* subtree's validation has committed, so an awaiting caller can read
|
|
4845
|
+
* `showErrors` / `errors` immediately after. It never rejects, and
|
|
4846
|
+
* ignoring it is fine.
|
|
4847
|
+
*
|
|
4848
|
+
* No-op on a disabled form, matching every other interaction-
|
|
4849
|
+
* lifecycle write. Does not mutate value, `focused`, or `blurred`:
|
|
4850
|
+
* those are DOM-owned, and the display gate reads none of them.
|
|
4851
|
+
* Sticky like `touched`; pair with `form.reset()` /
|
|
4852
|
+
* `form.resetField()` to clear.
|
|
4853
|
+
*/
|
|
4854
|
+
interact: (path?: FlatPath<Form> | (string | number)[]) => Promise<void>;
|
|
4605
4855
|
/**
|
|
4606
4856
|
* Append `value` to the array at `path`.
|
|
4607
4857
|
*
|
|
@@ -4709,5 +4959,5 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4709
4959
|
blankPaths: ComputedRef<BlankPathsView>;
|
|
4710
4960
|
};
|
|
4711
4961
|
|
|
4712
|
-
export { ROOT_PATH as
|
|
4713
|
-
export type {
|
|
4962
|
+
export { ROOT_PATH as Y, ROOT_PATH_KEY as Z, canonicalizePath as am, isPathPrefix as an, isUnset as ao, parseDottedPath as ap, unset as aq };
|
|
4963
|
+
export type { RegisterDirective as $, AbstractSchema as A, NestedType as B, CoercionEntry as C, DefaultValuesInput as D, ErrorInput as E, FormKey as F, GenericForm as G, HandleSubmit as H, IsTuple as I, JoinSegments as J, KeyofUnion as K, LiftedValueShape as L, MetaTrackerValue as M, NestedReadType as N, OnError as O, OnInvalidSubmitPolicy as P, OnSubmit as Q, ParseOptions as R, PartialFlatPath as S, Path as T, UseFormConfiguration as U, PathKey as V, PendingValidationStatus as W, Primitive as X, ReactiveValidationStatus as _, UseFormReturnType as a, RegisterFlatPath as a0, RegisterOptions as a1, RegisterSelectModifier as a2, RegisterTextModifier as a3, RegisterTransform as a4, RegisterValue as a5, Segment as a6, SetValueCallback as a7, SetValuePayload as a8, SettledValidationStatus as a9, SlimPrimitiveKind as aa, SlimRuntimeOf as ab, SubmitHandler as ac, Unset as ad, ValidateOn as ae, ValidateOnConfig as af, ValidationError as ag, ValidationResponse as ah, ValidationResponseWithoutValue as ai, ValueOfUnion as aj, WriteMeta as ak, WriteShape as al, RegisterModelDynamicCustomDirective as ar, AcceptableDefaults as as, SchemaFactoryOptions as at, FieldRecord as au, ErrorCell as av, OriginalsRecord as aw, AttaformDomBinding as ax, TransformAbortHolder as ay, ArrayItem as b, ArrayPath as c, AttaformDefaults as d, CoercionRegistry as e, CoercionResult as f, CustomDirectiveRegisterAssignerFn as g, DeepPartial as h, DefaultValuesResponse as i, DefaultValuesShape as j, DisplayCtx as k, DisplayMachine as l, DisplayState as m, ErrorsProxyShape as n, FieldMetaPayload as o, FieldState as p, FieldStateMap as q, FieldStateMapEntry as r, FlatPath as s, FormErrorRecord as t, FormErrorsSurface as u, FormMeta as v, GetDisplayState as w, HistoryPlugin as x, IsUnion as y, Json as z };
|
|
@@ -791,4 +791,3 @@ function hasPreamble(element) {
|
|
|
791
791
|
}
|
|
792
792
|
|
|
793
793
|
export { vRegisterPreambleTransform as a, componentBridgeTransform as c, inputTextAreaNodeTransform as i, redundantBindingWarnTransform as r, vRegisterHintTransform as v };
|
|
794
|
-
//# sourceMappingURL=attaform.Cs2Rbdlo.mjs.map
|