attaform 0.27.0 → 0.27.2
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/bin/attaform.mjs +55 -8
- package/dist/abstract.cjs +3 -2
- package/dist/abstract.cjs.map +1 -1
- package/dist/abstract.d.cts +4 -4
- package/dist/abstract.d.mts +4 -4
- package/dist/abstract.d.ts +4 -4
- package/dist/abstract.mjs +2 -2
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/fingerprint2.cjs +1 -1
- package/dist/chunks/fingerprint2.mjs +1 -1
- package/dist/index.cjs +4 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +3 -3
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/runtime/plugins/attaform.cjs +1 -1
- package/dist/runtime/plugins/attaform.mjs +1 -1
- package/dist/shared/{attaform.DkD0DR7R.mjs → attaform.6IZBjA1Q.mjs} +5 -5
- package/dist/shared/{attaform.DkD0DR7R.mjs.map → attaform.6IZBjA1Q.mjs.map} +1 -1
- package/dist/shared/{attaform.D99pd7JG.d.cts → attaform.B2d0FszH.d.ts} +169 -24
- package/dist/shared/{attaform.DDAmSFnl.mjs → attaform.BAlfXoAx.mjs} +3 -3
- package/dist/shared/{attaform.DDAmSFnl.mjs.map → attaform.BAlfXoAx.mjs.map} +1 -1
- package/dist/shared/{attaform.Co5LNRnv.cjs → attaform.BBaMFa-k.cjs} +31 -5
- package/dist/shared/attaform.BBaMFa-k.cjs.map +1 -0
- package/dist/shared/{attaform.DhVgG2jh.cjs → attaform.BF1mYHru.cjs} +4 -4
- package/dist/shared/{attaform.DhVgG2jh.cjs.map → attaform.BF1mYHru.cjs.map} +1 -1
- package/dist/shared/{attaform.C3WnCDXz.d.cts → attaform.BIPSHY5U.d.cts} +55 -1
- package/dist/shared/{attaform.C3WnCDXz.d.mts → attaform.BIPSHY5U.d.mts} +55 -1
- package/dist/shared/{attaform.C3WnCDXz.d.ts → attaform.BIPSHY5U.d.ts} +55 -1
- package/dist/shared/{attaform.8tFZu1Ub.cjs → attaform.Bn0IzhD_.cjs} +50 -2
- package/dist/shared/attaform.Bn0IzhD_.cjs.map +1 -0
- package/dist/shared/{attaform.K6Thc6By.cjs → attaform.C1SJy524.cjs} +5 -5
- package/dist/shared/{attaform.K6Thc6By.cjs.map → attaform.C1SJy524.cjs.map} +1 -1
- package/dist/shared/{attaform.CC_y1_Ej.d.ts → attaform.C8zVmank.d.ts} +1 -1
- package/dist/shared/{attaform.CpXHK60W.d.cts → attaform.C925L0WA.d.mts} +1 -1
- package/dist/shared/{attaform.Drsi43GG.cjs → attaform.CIPwCQe8.cjs} +3 -3
- package/dist/shared/{attaform.Drsi43GG.cjs.map → attaform.CIPwCQe8.cjs.map} +1 -1
- package/dist/shared/{attaform.DQT7_-FO.cjs → attaform.CXHebpij.cjs} +324 -82
- package/dist/shared/attaform.CXHebpij.cjs.map +1 -0
- package/dist/shared/{attaform.Da8EdI2t.mjs → attaform.CgsQZdy1.mjs} +31 -5
- package/dist/shared/attaform.CgsQZdy1.mjs.map +1 -0
- package/dist/shared/{attaform.CvVYOvZF.d.mts → attaform.CnvbLiIO.d.cts} +1 -1
- package/dist/shared/{attaform.BERt5YMU.mjs → attaform.Cs2Rbdlo.mjs} +50 -2
- package/dist/shared/attaform.Cs2Rbdlo.mjs.map +1 -0
- package/dist/shared/{attaform.C__F01CE.cjs → attaform.CvaPYOZu.cjs} +4 -4
- package/dist/shared/{attaform.C__F01CE.cjs.map → attaform.CvaPYOZu.cjs.map} +1 -1
- package/dist/shared/{attaform.CyQxTOdX.mjs → attaform.DGCijpZT.mjs} +325 -84
- package/dist/shared/attaform.DGCijpZT.mjs.map +1 -0
- package/dist/shared/{attaform.kBkYlKP_.d.mts → attaform.DIJTp_Kv.d.cts} +169 -24
- package/dist/shared/{attaform.CEXUlUkc.d.ts → attaform.Dcj-OS43.d.mts} +169 -24
- package/dist/shared/{attaform.DlSu08F5.mjs → attaform.gyed1fGh.mjs} +4 -4
- package/dist/shared/{attaform.DlSu08F5.mjs.map → attaform.gyed1fGh.mjs.map} +1 -1
- package/dist/shared/{attaform.BceJrhQ7.mjs → attaform.yOE3udL1.mjs} +4 -4
- package/dist/shared/{attaform.BceJrhQ7.mjs.map → attaform.yOE3udL1.mjs.map} +1 -1
- package/dist/transforms.cjs +1 -1
- package/dist/transforms.mjs +1 -1
- package/dist/vite.cjs +3 -2
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +3 -2
- package/dist/vite.mjs.map +1 -1
- package/dist/zod-v3.cjs +4 -3
- package/dist/zod-v3.cjs.map +1 -1
- package/dist/zod-v3.d.cts +3 -3
- package/dist/zod-v3.d.mts +3 -3
- package/dist/zod-v3.d.ts +3 -3
- package/dist/zod-v3.mjs +3 -3
- package/dist/zod-v4.cjs +4 -3
- package/dist/zod-v4.cjs.map +1 -1
- package/dist/zod-v4.d.cts +6 -6
- package/dist/zod-v4.d.mts +6 -6
- package/dist/zod-v4.d.ts +6 -6
- package/dist/zod-v4.mjs +3 -3
- package/dist/zod.cjs +4 -3
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +3 -3
- package/dist/zod.d.mts +3 -3
- package/dist/zod.d.ts +3 -3
- package/dist/zod.mjs +3 -3
- package/package.json +3 -2
- package/dist/shared/attaform.8tFZu1Ub.cjs.map +0 -1
- package/dist/shared/attaform.BERt5YMU.mjs.map +0 -1
- package/dist/shared/attaform.Co5LNRnv.cjs.map +0 -1
- package/dist/shared/attaform.CyQxTOdX.mjs.map +0 -1
- package/dist/shared/attaform.DQT7_-FO.cjs.map +0 -1
- package/dist/shared/attaform.Da8EdI2t.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GenericForm, F as FormKey, a as UseFormReturnType, a4 as RegisterValue, T as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, S as Path, a9 as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, af as ValidationError, A as AbstractSchema, aj as WriteMeta, h as DeepPartial, ak as WriteShape, as as TransformAbortHolder, ad as ValidateOn, d as AttaformDefaults, at as RegisterModelDynamicCustomDirective } from './attaform.
|
|
1
|
+
import { G as GenericForm, F as FormKey, a as UseFormReturnType, a4 as RegisterValue, T as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, S as Path, a9 as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, af as ValidationError, A as AbstractSchema, aj as WriteMeta, h as DeepPartial, ak as WriteShape, as as TransformAbortHolder, ad as ValidateOn, d as AttaformDefaults, at as RegisterModelDynamicCustomDirective } from './attaform.BIPSHY5U.cjs';
|
|
2
2
|
import { Ref, ComputedRef, App, InjectionKey, Plugin } from 'vue';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -441,6 +441,20 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
441
441
|
readonly submitted: Ref<boolean>;
|
|
442
442
|
readonly submitError: Ref<Error | null>;
|
|
443
443
|
readonly departAttempts: Ref<number>;
|
|
444
|
+
/**
|
|
445
|
+
* Effective data-freeze state: `true` when either the form's own
|
|
446
|
+
* `disabled` config resolves truthy or `externalLock` is set. Read at
|
|
447
|
+
* the write chokepoint (`setValueAtPath`), the register value's
|
|
448
|
+
* `disabled`, and the field display predicate.
|
|
449
|
+
*/
|
|
450
|
+
readonly effectiveDisabled: ComputedRef<boolean>;
|
|
451
|
+
/**
|
|
452
|
+
* Wizard-driven freeze channel. `useWizard` sets this `true` for a
|
|
453
|
+
* locked step's member form; ORed into `effectiveDisabled` so the
|
|
454
|
+
* wizard lock is authoritative and a member form cannot escape it by
|
|
455
|
+
* passing `disabled: false`. Default `false`.
|
|
456
|
+
*/
|
|
457
|
+
readonly externalLock: Ref<boolean>;
|
|
444
458
|
/**
|
|
445
459
|
* `true` while a function-form `defaultValues` factory is in flight.
|
|
446
460
|
* Stays `false` for plain-value `defaultValues`. Shared across every
|
|
@@ -1012,16 +1026,28 @@ type AnyForm = {
|
|
|
1012
1026
|
* `submissionAttempts > 0` is the "user has tried" signal.
|
|
1013
1027
|
* - `errorCount` — `form.meta.errorCount`. Count of active validation
|
|
1014
1028
|
* errors (zero when valid).
|
|
1029
|
+
* - `locked`: `true` when this step sits after an uncleared `gate()`
|
|
1030
|
+
* (see `gate`). Its member form is frozen (data writes no-op) and
|
|
1031
|
+
* navigation to it is refused, so a stepper can render it as an
|
|
1032
|
+
* unreachable gate. `false` when no gate seals it.
|
|
1015
1033
|
*
|
|
1016
1034
|
* Noop forms generated for string slots surface as default-valid
|
|
1017
|
-
* (`{ valid: true, dirty: false, submitted: false, errorCount: 0 }`).
|
|
1035
|
+
* (`{ valid: true, dirty: false, submitted: false, errorCount: 0, locked: false }`).
|
|
1018
1036
|
*/
|
|
1019
1037
|
type FormStatus = {
|
|
1020
1038
|
readonly valid: boolean;
|
|
1021
1039
|
readonly dirty: boolean;
|
|
1022
1040
|
readonly submitted: boolean;
|
|
1023
1041
|
readonly errorCount: number;
|
|
1042
|
+
readonly locked: boolean;
|
|
1024
1043
|
};
|
|
1044
|
+
/**
|
|
1045
|
+
* Seed shape accepted by `useWizard({ defaultStatuses })`. Mirrors
|
|
1046
|
+
* `FormStatus` minus `locked`: the lock flag is computed live from the
|
|
1047
|
+
* wizard's gates and overlaid on every status read, so a seed never
|
|
1048
|
+
* carries it (a seeded value would be ignored).
|
|
1049
|
+
*/
|
|
1050
|
+
type FormStatusSeed = Omit<FormStatus, 'locked'>;
|
|
1025
1051
|
/**
|
|
1026
1052
|
* Flat error shape returned per form by `wizard.allErrors[key]`. Each
|
|
1027
1053
|
* entry carries the formKey + path tuple so consumers can route to the
|
|
@@ -1082,6 +1108,13 @@ type WizardCtx = {
|
|
|
1082
1108
|
readonly forms: Readonly<Record<FormKey, WizardCtxForm>>;
|
|
1083
1109
|
readonly currentKey: FormKey | undefined;
|
|
1084
1110
|
};
|
|
1111
|
+
/**
|
|
1112
|
+
* What a function slot or a `lazy()` / `gate()` resolver may yield: a
|
|
1113
|
+
* participating form, a bare affordance key, a nested `lazy()` / `gate()`
|
|
1114
|
+
* wrapper (so the two compose in either order), or `null` / `undefined`
|
|
1115
|
+
* to drop the position from the compiled list.
|
|
1116
|
+
*/
|
|
1117
|
+
type SlotResolution<Ctx = WizardCtx> = AnyForm | string | null | undefined | LazyMarker<Ctx> | GateMarker;
|
|
1085
1118
|
/**
|
|
1086
1119
|
* Internal phantom brand for `LazyMarker`. The runtime brand symbol
|
|
1087
1120
|
* lives in `core/wizard-lazy.ts`; this declaration keeps the marker
|
|
@@ -1103,8 +1136,46 @@ declare const _lazyBrand: unique symbol;
|
|
|
1103
1136
|
*/
|
|
1104
1137
|
type LazyMarker<Ctx = WizardCtx> = {
|
|
1105
1138
|
readonly [_lazyBrand]: true;
|
|
1106
|
-
readonly resolve: (ctx: Ctx) =>
|
|
1139
|
+
readonly resolve: (ctx: Ctx) => SlotResolution<Ctx>;
|
|
1107
1140
|
};
|
|
1141
|
+
/**
|
|
1142
|
+
* Internal phantom brand for `GateMarker`. The runtime brand symbol
|
|
1143
|
+
* lives in `core/wizard-gate.ts`; this declaration keeps the marker
|
|
1144
|
+
* type unforgeable without circular module imports.
|
|
1145
|
+
*/
|
|
1146
|
+
declare const _gateBrand: unique symbol;
|
|
1147
|
+
/**
|
|
1148
|
+
* Brand-typed marker returned by `gate(step)`. Wrapping a slot in
|
|
1149
|
+
* `gate()` makes it a hard prerequisite: an uncleared gate seals every
|
|
1150
|
+
* step positioned after it, and the gate's own form is the only way
|
|
1151
|
+
* past. A gate clears on a member form's clean submit (confirmation),
|
|
1152
|
+
* never on a value merely going valid (intent), and its form freezes
|
|
1153
|
+
* once cleared so a back-navigation is a read-only review.
|
|
1154
|
+
*
|
|
1155
|
+
* `Inner` carries the wrapped slot's static type so `gate` stays
|
|
1156
|
+
* transparent to the type machinery: `gate(form)` still contributes the
|
|
1157
|
+
* form's key to `wizard.forms` and still counts as a guaranteed step,
|
|
1158
|
+
* while `gate(lazy(fn))` stays maybe-absent exactly like the lazy slot
|
|
1159
|
+
* it wraps. See {@link UnwrapGate}.
|
|
1160
|
+
*
|
|
1161
|
+
* Construct via the `gate()` helper exported from the same entry as
|
|
1162
|
+
* `useWizard`. The marker is opaque at the type level; consumers do not
|
|
1163
|
+
* assemble it directly.
|
|
1164
|
+
*/
|
|
1165
|
+
type GateMarker<Inner = unknown> = {
|
|
1166
|
+
readonly [_gateBrand]: true;
|
|
1167
|
+
readonly inner: Inner;
|
|
1168
|
+
};
|
|
1169
|
+
/**
|
|
1170
|
+
* Strip every `gate()` wrapper off a slot type, exposing the inner
|
|
1171
|
+
* slot's static shape. A gate is identity-on-shape — it changes runtime
|
|
1172
|
+
* reachability, never the compiled type — so the forms map and the
|
|
1173
|
+
* non-empty-tuple predicate both unwrap it before inspecting a slot.
|
|
1174
|
+
* Recursive, so a doubly-wrapped `gate(gate(form))` still resolves to
|
|
1175
|
+
* `form`. This is what makes `gate(lazy(s))` and `lazy((ctx) => gate(s))`
|
|
1176
|
+
* agree at the type level as well as at runtime.
|
|
1177
|
+
*/
|
|
1178
|
+
type UnwrapGate<T> = T extends GateMarker<infer Inner> ? UnwrapGate<Inner> : T;
|
|
1108
1179
|
/**
|
|
1109
1180
|
* One position in the source `useWizard({ steps })` array. Each slot
|
|
1110
1181
|
* resolves to a compiled `{ key, form }` step, or drops out:
|
|
@@ -1118,12 +1189,15 @@ type LazyMarker<Ctx = WizardCtx> = {
|
|
|
1118
1189
|
* list. Lets a conditional step read inline as
|
|
1119
1190
|
* `cond ? form : null` without pre-filtering the
|
|
1120
1191
|
* array.
|
|
1121
|
-
* - function — eager slot, re-evaluates reactively. Returns
|
|
1122
|
-
*
|
|
1192
|
+
* - function — eager slot, re-evaluates reactively. Returns a
|
|
1193
|
+
* `SlotResolution`, or `null` / `undefined` to
|
|
1123
1194
|
* drop the slot from the compiled list.
|
|
1124
1195
|
* - `LazyMarker` — memoized function slot (see `lazy`).
|
|
1196
|
+
* - `GateMarker` — hard-prerequisite wrapper (see `gate`). Wraps
|
|
1197
|
+
* any of the above; transparent to the compiled
|
|
1198
|
+
* step's type, opaque to reachability.
|
|
1125
1199
|
*/
|
|
1126
|
-
type StepSlot<Ctx = WizardCtx> = AnyForm | string | null | undefined | ((ctx: Ctx) =>
|
|
1200
|
+
type StepSlot<Ctx = WizardCtx> = AnyForm | string | null | undefined | ((ctx: Ctx) => SlotResolution<Ctx>) | LazyMarker<Ctx> | GateMarker;
|
|
1127
1201
|
/**
|
|
1128
1202
|
* Shape returned by the `restore` callback. Carries the active step's
|
|
1129
1203
|
* key; intentionally open-ended (object form) so future additions land
|
|
@@ -1231,10 +1305,14 @@ type WizardOptions = {
|
|
|
1231
1305
|
* 3. else seed value for this key → frozen seed
|
|
1232
1306
|
* 4. else → pending sentinel
|
|
1233
1307
|
*
|
|
1308
|
+
* The `locked` flag is never seeded: it is computed live from the
|
|
1309
|
+
* wizard's gates and overlaid on every status read, so the seed shape
|
|
1310
|
+
* is `FormStatus` minus `locked`.
|
|
1311
|
+
*
|
|
1234
1312
|
* Unknown keys in the seed object dev-warn so a stale resume payload
|
|
1235
1313
|
* surfaces at construction.
|
|
1236
1314
|
*/
|
|
1237
|
-
readonly defaultStatuses?: Record<string,
|
|
1315
|
+
readonly defaultStatuses?: Record<string, FormStatusSeed> | (() => Record<string, FormStatusSeed>) | (() => Promise<Record<string, FormStatusSeed>>);
|
|
1238
1316
|
/**
|
|
1239
1317
|
* Optional progress override. When omitted, the wizard exposes
|
|
1240
1318
|
* `progress` as `valid_step_count / count` (normalised to `[0, 1]`).
|
|
@@ -1277,7 +1355,7 @@ type WizardOptions = {
|
|
|
1277
1355
|
* nullish nor a (maybe-absent) function / `lazy()` slot. One of these
|
|
1278
1356
|
* anywhere in the tuple proves the compiled list is non-empty.
|
|
1279
1357
|
*/
|
|
1280
|
-
type IsGuaranteedStep<T
|
|
1358
|
+
type IsGuaranteedStep<T, U = UnwrapGate<T>> = [null] extends [U] ? false : [undefined] extends [U] ? false : U extends LazyMarker | ((...args: unknown[]) => unknown) ? false : U extends string ? true : U extends {
|
|
1281
1359
|
readonly key: string;
|
|
1282
1360
|
} ? true : false;
|
|
1283
1361
|
/**
|
|
@@ -1307,13 +1385,16 @@ type CurrentStepOf<S> = StaticallyNonEmpty<S> extends true ? FormKey : FormKey |
|
|
|
1307
1385
|
*/
|
|
1308
1386
|
type ActiveFormOf<S> = StaticallyNonEmpty<S> extends true ? UseFormReturnType<GenericForm> : UseFormReturnType<GenericForm> | undefined;
|
|
1309
1387
|
/**
|
|
1310
|
-
* Per-slot contribution to {@link FormsRecordOf}.
|
|
1388
|
+
* Per-slot contribution to {@link FormsRecordOf}. Unwraps a `gate()`
|
|
1389
|
+
* wrapper (transparent to the compiled type) and strips a `null` /
|
|
1311
1390
|
* `undefined` (a literal absence or a `cond ? form : null` union) off the
|
|
1312
|
-
* slot first, so a conditionally-present form
|
|
1313
|
-
*
|
|
1314
|
-
* contributes nothing.
|
|
1391
|
+
* slot first, so both a conditionally-present form and a `gate(form)`
|
|
1392
|
+
* still map to their key and stay concretely typed on `wizard.forms`; a
|
|
1393
|
+
* purely nullish slot contributes nothing.
|
|
1315
1394
|
*/
|
|
1316
|
-
type SlotRecord<First, F = Exclude<
|
|
1395
|
+
type SlotRecord<First, U = UnwrapGate<First>, F = Exclude<U, null | undefined>> = [F] extends [
|
|
1396
|
+
never
|
|
1397
|
+
] ? unknown : F extends string ? {
|
|
1317
1398
|
readonly [P in F]: AnyForm;
|
|
1318
1399
|
} : F extends {
|
|
1319
1400
|
readonly key: infer K extends string;
|
|
@@ -1337,6 +1418,9 @@ type SlotRecord<First, F = Exclude<First, null | undefined>> = [F] extends [neve
|
|
|
1337
1418
|
* - **Function / `lazy()` slot**: contributes nothing to the static
|
|
1338
1419
|
* map. Runtime-resolved forms are still reachable via the
|
|
1339
1420
|
* catch-all index signature on `WizardForms` (typed as `AnyForm`).
|
|
1421
|
+
* - **`gate()` slot**: transparent — unwrapped to the slot it wraps, so
|
|
1422
|
+
* `gate(form)` contributes the form's key and `gate(lazy(fn))`
|
|
1423
|
+
* contributes nothing, exactly like the wrapped slot on its own.
|
|
1340
1424
|
*
|
|
1341
1425
|
* Recursion is bounded by the tuple length; real-world wizards land
|
|
1342
1426
|
* well below the TS instantiation budget.
|
|
@@ -1442,14 +1526,15 @@ type WizardForms<S> = FormsRecordOf<S> & Readonly<Record<FormKey, AnyForm>>;
|
|
|
1442
1526
|
* `back()` does not pop; the trail is the audit
|
|
1443
1527
|
* log, not the back-stack.
|
|
1444
1528
|
* - `next/back/goTo` — pure navigation. Refuses while `submitting`.
|
|
1445
|
-
* - `tryNext()` —
|
|
1446
|
-
*
|
|
1447
|
-
* form's standard error reveal (first
|
|
1448
|
-
* display state advanced). The
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1452
|
-
*
|
|
1529
|
+
* - `tryNext()` — submit the active step, and once that submit
|
|
1530
|
+
* resolves clean, advance; invalid input keeps the pin
|
|
1531
|
+
* put under the form's standard error reveal (first
|
|
1532
|
+
* error focused, display state advanced). The advance
|
|
1533
|
+
* runs after the submit settles, so a `gate()` on the
|
|
1534
|
+
* active step clears in a single call. Inline-bindable
|
|
1535
|
+
* (`@click="wizard.tryNext()"`); resolves to whether
|
|
1536
|
+
* the pin moved. No-ops to `false` on a degenerate or
|
|
1537
|
+
* final-step wizard (finish via `handleSubmit`).
|
|
1453
1538
|
* - `handleSubmit(onSubmit, onError?)` — always validates the entire
|
|
1454
1539
|
* step list, from any step, and never advances the
|
|
1455
1540
|
* pin: on success it latches `done`; on any error it
|
|
@@ -1809,11 +1894,61 @@ declare function injectWizard(input?: string | InjectWizardInput): UseWizardRetu
|
|
|
1809
1894
|
* resolves from scratch.
|
|
1810
1895
|
* - Resolving to `null` or `undefined` drops the slot from the compiled
|
|
1811
1896
|
* list until the resolver next re-fires.
|
|
1897
|
+
* - The resolver may return a `gate()` wrapper, so a lazy slot can gate
|
|
1898
|
+
* what it resolves to; `lazy((ctx) => gate(s))` and `gate(lazy(s))`
|
|
1899
|
+
* resolve identically.
|
|
1812
1900
|
*
|
|
1813
1901
|
* The runtime brand returned by `lazy()` is opaque. Use
|
|
1814
1902
|
* {@link isLazyMarker} to detect it.
|
|
1815
1903
|
*/
|
|
1816
|
-
declare function lazy<Ctx = WizardCtx>(resolve: (ctx: Ctx) =>
|
|
1904
|
+
declare function lazy<Ctx = WizardCtx>(resolve: (ctx: Ctx) => SlotResolution<Ctx>): LazyMarker<Ctx>;
|
|
1905
|
+
|
|
1906
|
+
/**
|
|
1907
|
+
* Wrap a step slot in `gate()` to make it a hard prerequisite: while the
|
|
1908
|
+
* gate is uncleared, every step positioned after it is inaccessible, and
|
|
1909
|
+
* the gate's own form is the only way past.
|
|
1910
|
+
*
|
|
1911
|
+
* A gate is safe by construction. It does not hand the consumer a
|
|
1912
|
+
* predicate to key on; it bakes the correct semantics in:
|
|
1913
|
+
*
|
|
1914
|
+
* - **Confirmation, not intent.** The gate clears only when a member
|
|
1915
|
+
* form submits clean, never when a value merely goes valid. Checking
|
|
1916
|
+
* the box does nothing; submitting the consent step is what opens the
|
|
1917
|
+
* rail. This is the whole reason `gate()` exists: a leading value
|
|
1918
|
+
* signal lets a downstream step collect data before the prerequisite
|
|
1919
|
+
* is confirmed.
|
|
1920
|
+
* - **Linear-forward.** An uncleared gate seals every step after it.
|
|
1921
|
+
* Order places it: put `gate(step)` immediately before what it
|
|
1922
|
+
* guards. Everything downstream is both un-navigable and, through the
|
|
1923
|
+
* `disabled` data freeze, un-fillable, so a deep link, the browser
|
|
1924
|
+
* back button, or a stray `goTo` all redirect to the gate.
|
|
1925
|
+
* - **Freeze-after-clear.** A cleared gate's own form freezes, so
|
|
1926
|
+
* navigating back to it is a read-only review with no withdrawal
|
|
1927
|
+
* path. There is no re-lock dance.
|
|
1928
|
+
*
|
|
1929
|
+
* Wrap any slot kind:
|
|
1930
|
+
*
|
|
1931
|
+
* const wizard = useWizard({ steps: [gate(consent), shipping, payment] })
|
|
1932
|
+
*
|
|
1933
|
+
* A **form** gate (`gate(consentForm)`) clears when its form submits
|
|
1934
|
+
* clean, and is treated as pre-cleared on reload when its member form
|
|
1935
|
+
* rehydrates already valid (a persisted consent), so a seeded-valid gate
|
|
1936
|
+
* SSR-renders open. A bare-string **affordance** gate (`gate('terms')`)
|
|
1937
|
+
* clears on acknowledgment (advancing past it), and re-prompts each
|
|
1938
|
+
* session because that acknowledgment is ephemeral.
|
|
1939
|
+
*
|
|
1940
|
+
* Conditional gates come from composition, not an options bag:
|
|
1941
|
+
*
|
|
1942
|
+
* () => (transfer.values.amount > 10_000 ? gate(kyc) : kyc)
|
|
1943
|
+
*
|
|
1944
|
+
* `gate()` composes with `lazy()` in either order:
|
|
1945
|
+
* `gate(lazy(fn))` and `lazy((ctx) => gate(fn(ctx)))` resolve
|
|
1946
|
+
* identically.
|
|
1947
|
+
*
|
|
1948
|
+
* The runtime brand returned by `gate()` is opaque. Use
|
|
1949
|
+
* {@link isGateMarker} to detect it.
|
|
1950
|
+
*/
|
|
1951
|
+
declare function gate<const Inner extends StepSlot>(step: Inner): GateMarker<Inner>;
|
|
1817
1952
|
|
|
1818
1953
|
/**
|
|
1819
1954
|
* Stable identifiers for library-emitted `ValidationError` codes.
|
|
@@ -1891,6 +2026,16 @@ declare const AttaformErrorCode: {
|
|
|
1891
2026
|
* form-level path `[]`.
|
|
1892
2027
|
*/
|
|
1893
2028
|
readonly SubmitError: "atta:submit-error";
|
|
2029
|
+
/**
|
|
2030
|
+
* Synthesized by `wizard.handleSubmit` when the whole-wizard submit
|
|
2031
|
+
* would otherwise succeed but a `gate()` step is still uncleared. A
|
|
2032
|
+
* gate clears only on its member form's clean submit (confirmation), so
|
|
2033
|
+
* a downstream step that happens to be valid-by-default must not let the
|
|
2034
|
+
* wizard finish past an unconfirmed prerequisite. Emitted at the gate
|
|
2035
|
+
* form's key (path `[]`) so the aggregate error pipeline routes focus to
|
|
2036
|
+
* the gate, and `done` never latches.
|
|
2037
|
+
*/
|
|
2038
|
+
readonly GateNotCleared: "atta:gate-not-cleared";
|
|
1894
2039
|
};
|
|
1895
2040
|
type AttaformErrorCode = (typeof AttaformErrorCode)[keyof typeof AttaformErrorCode];
|
|
1896
2041
|
|
|
@@ -2281,5 +2426,5 @@ declare function makeDefaultDisplayState({ showDelay, minVisible, }: DisplayTimi
|
|
|
2281
2426
|
*/
|
|
2282
2427
|
declare const defaultDisplayState: GetDisplayState;
|
|
2283
2428
|
|
|
2284
|
-
export {
|
|
2285
|
-
export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S, UseRegisterReturn as U, WizardAggregateError as W, AnyForm as a, AttaformDevtoolsBridge as b, AttaformPluginOptions as e, DisplayTimings as g, SerializedFormData as
|
|
2429
|
+
export { renderAttaformState as $, createAttaform as B, DEFAULT_TIMINGS as D, createRegistry as E, defaultCoercionRules as H, defaultDisplayState as J, defineCoercion as K, escapeForInlineScript as M, gate as N, OutsideSetupError as O, getRegistryFromApp as P, hydrateAttaformState as Q, RegistryNotInstalledError as R, injectForm as T, injectWizard as V, isRegisterValue as X, kAttaformRegistry as Y, lazy as Z, makeDefaultDisplayState as _, useRegister as a0, useRegistry as a1, useWizard as a2, vRegister as a3, AttaformError as c, AttaformErrorCode as d, DEVTOOLS_WINDOW_KEY as f, InvalidPathError as i, InvalidUseFormConfigError as j, ReservedFormKeyError as k, SubmitErrorHandlerError as n, assignKey as z };
|
|
2430
|
+
export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, GateMarker as G, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S, UseRegisterReturn as U, WizardAggregateError as W, AnyForm as a, AttaformDevtoolsBridge as b, AttaformPluginOptions as e, DisplayTimings as g, FormStatusSeed as h, SerializedFormData as l, StepSlot as m, UseWizardReturnType as o, WizardCtx as p, WizardCtxForm as q, WizardOnError as r, WizardOnSubmit as s, WizardOptions as t, WizardPersistFn as u, WizardRestoreFn as v, WizardRestoreState as w, WizardStatusesProxy as x, WizardSubmitContext as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GenericForm, F as FormKey, a as UseFormReturnType, a4 as RegisterValue, T as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, S as Path, a9 as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, af as ValidationError, A as AbstractSchema, aj as WriteMeta, h as DeepPartial, ak as WriteShape, as as TransformAbortHolder, ad as ValidateOn, d as AttaformDefaults, at as RegisterModelDynamicCustomDirective } from './attaform.
|
|
1
|
+
import { G as GenericForm, F as FormKey, a as UseFormReturnType, a4 as RegisterValue, T as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, S as Path, a9 as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, af as ValidationError, A as AbstractSchema, aj as WriteMeta, h as DeepPartial, ak as WriteShape, as as TransformAbortHolder, ad as ValidateOn, d as AttaformDefaults, at as RegisterModelDynamicCustomDirective } from './attaform.BIPSHY5U.mjs';
|
|
2
2
|
import { Ref, ComputedRef, App, InjectionKey, Plugin } from 'vue';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -441,6 +441,20 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
441
441
|
readonly submitted: Ref<boolean>;
|
|
442
442
|
readonly submitError: Ref<Error | null>;
|
|
443
443
|
readonly departAttempts: Ref<number>;
|
|
444
|
+
/**
|
|
445
|
+
* Effective data-freeze state: `true` when either the form's own
|
|
446
|
+
* `disabled` config resolves truthy or `externalLock` is set. Read at
|
|
447
|
+
* the write chokepoint (`setValueAtPath`), the register value's
|
|
448
|
+
* `disabled`, and the field display predicate.
|
|
449
|
+
*/
|
|
450
|
+
readonly effectiveDisabled: ComputedRef<boolean>;
|
|
451
|
+
/**
|
|
452
|
+
* Wizard-driven freeze channel. `useWizard` sets this `true` for a
|
|
453
|
+
* locked step's member form; ORed into `effectiveDisabled` so the
|
|
454
|
+
* wizard lock is authoritative and a member form cannot escape it by
|
|
455
|
+
* passing `disabled: false`. Default `false`.
|
|
456
|
+
*/
|
|
457
|
+
readonly externalLock: Ref<boolean>;
|
|
444
458
|
/**
|
|
445
459
|
* `true` while a function-form `defaultValues` factory is in flight.
|
|
446
460
|
* Stays `false` for plain-value `defaultValues`. Shared across every
|
|
@@ -1012,16 +1026,28 @@ type AnyForm = {
|
|
|
1012
1026
|
* `submissionAttempts > 0` is the "user has tried" signal.
|
|
1013
1027
|
* - `errorCount` — `form.meta.errorCount`. Count of active validation
|
|
1014
1028
|
* errors (zero when valid).
|
|
1029
|
+
* - `locked`: `true` when this step sits after an uncleared `gate()`
|
|
1030
|
+
* (see `gate`). Its member form is frozen (data writes no-op) and
|
|
1031
|
+
* navigation to it is refused, so a stepper can render it as an
|
|
1032
|
+
* unreachable gate. `false` when no gate seals it.
|
|
1015
1033
|
*
|
|
1016
1034
|
* Noop forms generated for string slots surface as default-valid
|
|
1017
|
-
* (`{ valid: true, dirty: false, submitted: false, errorCount: 0 }`).
|
|
1035
|
+
* (`{ valid: true, dirty: false, submitted: false, errorCount: 0, locked: false }`).
|
|
1018
1036
|
*/
|
|
1019
1037
|
type FormStatus = {
|
|
1020
1038
|
readonly valid: boolean;
|
|
1021
1039
|
readonly dirty: boolean;
|
|
1022
1040
|
readonly submitted: boolean;
|
|
1023
1041
|
readonly errorCount: number;
|
|
1042
|
+
readonly locked: boolean;
|
|
1024
1043
|
};
|
|
1044
|
+
/**
|
|
1045
|
+
* Seed shape accepted by `useWizard({ defaultStatuses })`. Mirrors
|
|
1046
|
+
* `FormStatus` minus `locked`: the lock flag is computed live from the
|
|
1047
|
+
* wizard's gates and overlaid on every status read, so a seed never
|
|
1048
|
+
* carries it (a seeded value would be ignored).
|
|
1049
|
+
*/
|
|
1050
|
+
type FormStatusSeed = Omit<FormStatus, 'locked'>;
|
|
1025
1051
|
/**
|
|
1026
1052
|
* Flat error shape returned per form by `wizard.allErrors[key]`. Each
|
|
1027
1053
|
* entry carries the formKey + path tuple so consumers can route to the
|
|
@@ -1082,6 +1108,13 @@ type WizardCtx = {
|
|
|
1082
1108
|
readonly forms: Readonly<Record<FormKey, WizardCtxForm>>;
|
|
1083
1109
|
readonly currentKey: FormKey | undefined;
|
|
1084
1110
|
};
|
|
1111
|
+
/**
|
|
1112
|
+
* What a function slot or a `lazy()` / `gate()` resolver may yield: a
|
|
1113
|
+
* participating form, a bare affordance key, a nested `lazy()` / `gate()`
|
|
1114
|
+
* wrapper (so the two compose in either order), or `null` / `undefined`
|
|
1115
|
+
* to drop the position from the compiled list.
|
|
1116
|
+
*/
|
|
1117
|
+
type SlotResolution<Ctx = WizardCtx> = AnyForm | string | null | undefined | LazyMarker<Ctx> | GateMarker;
|
|
1085
1118
|
/**
|
|
1086
1119
|
* Internal phantom brand for `LazyMarker`. The runtime brand symbol
|
|
1087
1120
|
* lives in `core/wizard-lazy.ts`; this declaration keeps the marker
|
|
@@ -1103,8 +1136,46 @@ declare const _lazyBrand: unique symbol;
|
|
|
1103
1136
|
*/
|
|
1104
1137
|
type LazyMarker<Ctx = WizardCtx> = {
|
|
1105
1138
|
readonly [_lazyBrand]: true;
|
|
1106
|
-
readonly resolve: (ctx: Ctx) =>
|
|
1139
|
+
readonly resolve: (ctx: Ctx) => SlotResolution<Ctx>;
|
|
1107
1140
|
};
|
|
1141
|
+
/**
|
|
1142
|
+
* Internal phantom brand for `GateMarker`. The runtime brand symbol
|
|
1143
|
+
* lives in `core/wizard-gate.ts`; this declaration keeps the marker
|
|
1144
|
+
* type unforgeable without circular module imports.
|
|
1145
|
+
*/
|
|
1146
|
+
declare const _gateBrand: unique symbol;
|
|
1147
|
+
/**
|
|
1148
|
+
* Brand-typed marker returned by `gate(step)`. Wrapping a slot in
|
|
1149
|
+
* `gate()` makes it a hard prerequisite: an uncleared gate seals every
|
|
1150
|
+
* step positioned after it, and the gate's own form is the only way
|
|
1151
|
+
* past. A gate clears on a member form's clean submit (confirmation),
|
|
1152
|
+
* never on a value merely going valid (intent), and its form freezes
|
|
1153
|
+
* once cleared so a back-navigation is a read-only review.
|
|
1154
|
+
*
|
|
1155
|
+
* `Inner` carries the wrapped slot's static type so `gate` stays
|
|
1156
|
+
* transparent to the type machinery: `gate(form)` still contributes the
|
|
1157
|
+
* form's key to `wizard.forms` and still counts as a guaranteed step,
|
|
1158
|
+
* while `gate(lazy(fn))` stays maybe-absent exactly like the lazy slot
|
|
1159
|
+
* it wraps. See {@link UnwrapGate}.
|
|
1160
|
+
*
|
|
1161
|
+
* Construct via the `gate()` helper exported from the same entry as
|
|
1162
|
+
* `useWizard`. The marker is opaque at the type level; consumers do not
|
|
1163
|
+
* assemble it directly.
|
|
1164
|
+
*/
|
|
1165
|
+
type GateMarker<Inner = unknown> = {
|
|
1166
|
+
readonly [_gateBrand]: true;
|
|
1167
|
+
readonly inner: Inner;
|
|
1168
|
+
};
|
|
1169
|
+
/**
|
|
1170
|
+
* Strip every `gate()` wrapper off a slot type, exposing the inner
|
|
1171
|
+
* slot's static shape. A gate is identity-on-shape — it changes runtime
|
|
1172
|
+
* reachability, never the compiled type — so the forms map and the
|
|
1173
|
+
* non-empty-tuple predicate both unwrap it before inspecting a slot.
|
|
1174
|
+
* Recursive, so a doubly-wrapped `gate(gate(form))` still resolves to
|
|
1175
|
+
* `form`. This is what makes `gate(lazy(s))` and `lazy((ctx) => gate(s))`
|
|
1176
|
+
* agree at the type level as well as at runtime.
|
|
1177
|
+
*/
|
|
1178
|
+
type UnwrapGate<T> = T extends GateMarker<infer Inner> ? UnwrapGate<Inner> : T;
|
|
1108
1179
|
/**
|
|
1109
1180
|
* One position in the source `useWizard({ steps })` array. Each slot
|
|
1110
1181
|
* resolves to a compiled `{ key, form }` step, or drops out:
|
|
@@ -1118,12 +1189,15 @@ type LazyMarker<Ctx = WizardCtx> = {
|
|
|
1118
1189
|
* list. Lets a conditional step read inline as
|
|
1119
1190
|
* `cond ? form : null` without pre-filtering the
|
|
1120
1191
|
* array.
|
|
1121
|
-
* - function — eager slot, re-evaluates reactively. Returns
|
|
1122
|
-
*
|
|
1192
|
+
* - function — eager slot, re-evaluates reactively. Returns a
|
|
1193
|
+
* `SlotResolution`, or `null` / `undefined` to
|
|
1123
1194
|
* drop the slot from the compiled list.
|
|
1124
1195
|
* - `LazyMarker` — memoized function slot (see `lazy`).
|
|
1196
|
+
* - `GateMarker` — hard-prerequisite wrapper (see `gate`). Wraps
|
|
1197
|
+
* any of the above; transparent to the compiled
|
|
1198
|
+
* step's type, opaque to reachability.
|
|
1125
1199
|
*/
|
|
1126
|
-
type StepSlot<Ctx = WizardCtx> = AnyForm | string | null | undefined | ((ctx: Ctx) =>
|
|
1200
|
+
type StepSlot<Ctx = WizardCtx> = AnyForm | string | null | undefined | ((ctx: Ctx) => SlotResolution<Ctx>) | LazyMarker<Ctx> | GateMarker;
|
|
1127
1201
|
/**
|
|
1128
1202
|
* Shape returned by the `restore` callback. Carries the active step's
|
|
1129
1203
|
* key; intentionally open-ended (object form) so future additions land
|
|
@@ -1231,10 +1305,14 @@ type WizardOptions = {
|
|
|
1231
1305
|
* 3. else seed value for this key → frozen seed
|
|
1232
1306
|
* 4. else → pending sentinel
|
|
1233
1307
|
*
|
|
1308
|
+
* The `locked` flag is never seeded: it is computed live from the
|
|
1309
|
+
* wizard's gates and overlaid on every status read, so the seed shape
|
|
1310
|
+
* is `FormStatus` minus `locked`.
|
|
1311
|
+
*
|
|
1234
1312
|
* Unknown keys in the seed object dev-warn so a stale resume payload
|
|
1235
1313
|
* surfaces at construction.
|
|
1236
1314
|
*/
|
|
1237
|
-
readonly defaultStatuses?: Record<string,
|
|
1315
|
+
readonly defaultStatuses?: Record<string, FormStatusSeed> | (() => Record<string, FormStatusSeed>) | (() => Promise<Record<string, FormStatusSeed>>);
|
|
1238
1316
|
/**
|
|
1239
1317
|
* Optional progress override. When omitted, the wizard exposes
|
|
1240
1318
|
* `progress` as `valid_step_count / count` (normalised to `[0, 1]`).
|
|
@@ -1277,7 +1355,7 @@ type WizardOptions = {
|
|
|
1277
1355
|
* nullish nor a (maybe-absent) function / `lazy()` slot. One of these
|
|
1278
1356
|
* anywhere in the tuple proves the compiled list is non-empty.
|
|
1279
1357
|
*/
|
|
1280
|
-
type IsGuaranteedStep<T
|
|
1358
|
+
type IsGuaranteedStep<T, U = UnwrapGate<T>> = [null] extends [U] ? false : [undefined] extends [U] ? false : U extends LazyMarker | ((...args: unknown[]) => unknown) ? false : U extends string ? true : U extends {
|
|
1281
1359
|
readonly key: string;
|
|
1282
1360
|
} ? true : false;
|
|
1283
1361
|
/**
|
|
@@ -1307,13 +1385,16 @@ type CurrentStepOf<S> = StaticallyNonEmpty<S> extends true ? FormKey : FormKey |
|
|
|
1307
1385
|
*/
|
|
1308
1386
|
type ActiveFormOf<S> = StaticallyNonEmpty<S> extends true ? UseFormReturnType<GenericForm> : UseFormReturnType<GenericForm> | undefined;
|
|
1309
1387
|
/**
|
|
1310
|
-
* Per-slot contribution to {@link FormsRecordOf}.
|
|
1388
|
+
* Per-slot contribution to {@link FormsRecordOf}. Unwraps a `gate()`
|
|
1389
|
+
* wrapper (transparent to the compiled type) and strips a `null` /
|
|
1311
1390
|
* `undefined` (a literal absence or a `cond ? form : null` union) off the
|
|
1312
|
-
* slot first, so a conditionally-present form
|
|
1313
|
-
*
|
|
1314
|
-
* contributes nothing.
|
|
1391
|
+
* slot first, so both a conditionally-present form and a `gate(form)`
|
|
1392
|
+
* still map to their key and stay concretely typed on `wizard.forms`; a
|
|
1393
|
+
* purely nullish slot contributes nothing.
|
|
1315
1394
|
*/
|
|
1316
|
-
type SlotRecord<First, F = Exclude<
|
|
1395
|
+
type SlotRecord<First, U = UnwrapGate<First>, F = Exclude<U, null | undefined>> = [F] extends [
|
|
1396
|
+
never
|
|
1397
|
+
] ? unknown : F extends string ? {
|
|
1317
1398
|
readonly [P in F]: AnyForm;
|
|
1318
1399
|
} : F extends {
|
|
1319
1400
|
readonly key: infer K extends string;
|
|
@@ -1337,6 +1418,9 @@ type SlotRecord<First, F = Exclude<First, null | undefined>> = [F] extends [neve
|
|
|
1337
1418
|
* - **Function / `lazy()` slot**: contributes nothing to the static
|
|
1338
1419
|
* map. Runtime-resolved forms are still reachable via the
|
|
1339
1420
|
* catch-all index signature on `WizardForms` (typed as `AnyForm`).
|
|
1421
|
+
* - **`gate()` slot**: transparent — unwrapped to the slot it wraps, so
|
|
1422
|
+
* `gate(form)` contributes the form's key and `gate(lazy(fn))`
|
|
1423
|
+
* contributes nothing, exactly like the wrapped slot on its own.
|
|
1340
1424
|
*
|
|
1341
1425
|
* Recursion is bounded by the tuple length; real-world wizards land
|
|
1342
1426
|
* well below the TS instantiation budget.
|
|
@@ -1442,14 +1526,15 @@ type WizardForms<S> = FormsRecordOf<S> & Readonly<Record<FormKey, AnyForm>>;
|
|
|
1442
1526
|
* `back()` does not pop; the trail is the audit
|
|
1443
1527
|
* log, not the back-stack.
|
|
1444
1528
|
* - `next/back/goTo` — pure navigation. Refuses while `submitting`.
|
|
1445
|
-
* - `tryNext()` —
|
|
1446
|
-
*
|
|
1447
|
-
* form's standard error reveal (first
|
|
1448
|
-
* display state advanced). The
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1452
|
-
*
|
|
1529
|
+
* - `tryNext()` — submit the active step, and once that submit
|
|
1530
|
+
* resolves clean, advance; invalid input keeps the pin
|
|
1531
|
+
* put under the form's standard error reveal (first
|
|
1532
|
+
* error focused, display state advanced). The advance
|
|
1533
|
+
* runs after the submit settles, so a `gate()` on the
|
|
1534
|
+
* active step clears in a single call. Inline-bindable
|
|
1535
|
+
* (`@click="wizard.tryNext()"`); resolves to whether
|
|
1536
|
+
* the pin moved. No-ops to `false` on a degenerate or
|
|
1537
|
+
* final-step wizard (finish via `handleSubmit`).
|
|
1453
1538
|
* - `handleSubmit(onSubmit, onError?)` — always validates the entire
|
|
1454
1539
|
* step list, from any step, and never advances the
|
|
1455
1540
|
* pin: on success it latches `done`; on any error it
|
|
@@ -1809,11 +1894,61 @@ declare function injectWizard(input?: string | InjectWizardInput): UseWizardRetu
|
|
|
1809
1894
|
* resolves from scratch.
|
|
1810
1895
|
* - Resolving to `null` or `undefined` drops the slot from the compiled
|
|
1811
1896
|
* list until the resolver next re-fires.
|
|
1897
|
+
* - The resolver may return a `gate()` wrapper, so a lazy slot can gate
|
|
1898
|
+
* what it resolves to; `lazy((ctx) => gate(s))` and `gate(lazy(s))`
|
|
1899
|
+
* resolve identically.
|
|
1812
1900
|
*
|
|
1813
1901
|
* The runtime brand returned by `lazy()` is opaque. Use
|
|
1814
1902
|
* {@link isLazyMarker} to detect it.
|
|
1815
1903
|
*/
|
|
1816
|
-
declare function lazy<Ctx = WizardCtx>(resolve: (ctx: Ctx) =>
|
|
1904
|
+
declare function lazy<Ctx = WizardCtx>(resolve: (ctx: Ctx) => SlotResolution<Ctx>): LazyMarker<Ctx>;
|
|
1905
|
+
|
|
1906
|
+
/**
|
|
1907
|
+
* Wrap a step slot in `gate()` to make it a hard prerequisite: while the
|
|
1908
|
+
* gate is uncleared, every step positioned after it is inaccessible, and
|
|
1909
|
+
* the gate's own form is the only way past.
|
|
1910
|
+
*
|
|
1911
|
+
* A gate is safe by construction. It does not hand the consumer a
|
|
1912
|
+
* predicate to key on; it bakes the correct semantics in:
|
|
1913
|
+
*
|
|
1914
|
+
* - **Confirmation, not intent.** The gate clears only when a member
|
|
1915
|
+
* form submits clean, never when a value merely goes valid. Checking
|
|
1916
|
+
* the box does nothing; submitting the consent step is what opens the
|
|
1917
|
+
* rail. This is the whole reason `gate()` exists: a leading value
|
|
1918
|
+
* signal lets a downstream step collect data before the prerequisite
|
|
1919
|
+
* is confirmed.
|
|
1920
|
+
* - **Linear-forward.** An uncleared gate seals every step after it.
|
|
1921
|
+
* Order places it: put `gate(step)` immediately before what it
|
|
1922
|
+
* guards. Everything downstream is both un-navigable and, through the
|
|
1923
|
+
* `disabled` data freeze, un-fillable, so a deep link, the browser
|
|
1924
|
+
* back button, or a stray `goTo` all redirect to the gate.
|
|
1925
|
+
* - **Freeze-after-clear.** A cleared gate's own form freezes, so
|
|
1926
|
+
* navigating back to it is a read-only review with no withdrawal
|
|
1927
|
+
* path. There is no re-lock dance.
|
|
1928
|
+
*
|
|
1929
|
+
* Wrap any slot kind:
|
|
1930
|
+
*
|
|
1931
|
+
* const wizard = useWizard({ steps: [gate(consent), shipping, payment] })
|
|
1932
|
+
*
|
|
1933
|
+
* A **form** gate (`gate(consentForm)`) clears when its form submits
|
|
1934
|
+
* clean, and is treated as pre-cleared on reload when its member form
|
|
1935
|
+
* rehydrates already valid (a persisted consent), so a seeded-valid gate
|
|
1936
|
+
* SSR-renders open. A bare-string **affordance** gate (`gate('terms')`)
|
|
1937
|
+
* clears on acknowledgment (advancing past it), and re-prompts each
|
|
1938
|
+
* session because that acknowledgment is ephemeral.
|
|
1939
|
+
*
|
|
1940
|
+
* Conditional gates come from composition, not an options bag:
|
|
1941
|
+
*
|
|
1942
|
+
* () => (transfer.values.amount > 10_000 ? gate(kyc) : kyc)
|
|
1943
|
+
*
|
|
1944
|
+
* `gate()` composes with `lazy()` in either order:
|
|
1945
|
+
* `gate(lazy(fn))` and `lazy((ctx) => gate(fn(ctx)))` resolve
|
|
1946
|
+
* identically.
|
|
1947
|
+
*
|
|
1948
|
+
* The runtime brand returned by `gate()` is opaque. Use
|
|
1949
|
+
* {@link isGateMarker} to detect it.
|
|
1950
|
+
*/
|
|
1951
|
+
declare function gate<const Inner extends StepSlot>(step: Inner): GateMarker<Inner>;
|
|
1817
1952
|
|
|
1818
1953
|
/**
|
|
1819
1954
|
* Stable identifiers for library-emitted `ValidationError` codes.
|
|
@@ -1891,6 +2026,16 @@ declare const AttaformErrorCode: {
|
|
|
1891
2026
|
* form-level path `[]`.
|
|
1892
2027
|
*/
|
|
1893
2028
|
readonly SubmitError: "atta:submit-error";
|
|
2029
|
+
/**
|
|
2030
|
+
* Synthesized by `wizard.handleSubmit` when the whole-wizard submit
|
|
2031
|
+
* would otherwise succeed but a `gate()` step is still uncleared. A
|
|
2032
|
+
* gate clears only on its member form's clean submit (confirmation), so
|
|
2033
|
+
* a downstream step that happens to be valid-by-default must not let the
|
|
2034
|
+
* wizard finish past an unconfirmed prerequisite. Emitted at the gate
|
|
2035
|
+
* form's key (path `[]`) so the aggregate error pipeline routes focus to
|
|
2036
|
+
* the gate, and `done` never latches.
|
|
2037
|
+
*/
|
|
2038
|
+
readonly GateNotCleared: "atta:gate-not-cleared";
|
|
1894
2039
|
};
|
|
1895
2040
|
type AttaformErrorCode = (typeof AttaformErrorCode)[keyof typeof AttaformErrorCode];
|
|
1896
2041
|
|
|
@@ -2281,5 +2426,5 @@ declare function makeDefaultDisplayState({ showDelay, minVisible, }: DisplayTimi
|
|
|
2281
2426
|
*/
|
|
2282
2427
|
declare const defaultDisplayState: GetDisplayState;
|
|
2283
2428
|
|
|
2284
|
-
export {
|
|
2285
|
-
export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S, UseRegisterReturn as U, WizardAggregateError as W, AnyForm as a, AttaformDevtoolsBridge as b, AttaformPluginOptions as e, DisplayTimings as g, SerializedFormData as
|
|
2429
|
+
export { renderAttaformState as $, createAttaform as B, DEFAULT_TIMINGS as D, createRegistry as E, defaultCoercionRules as H, defaultDisplayState as J, defineCoercion as K, escapeForInlineScript as M, gate as N, OutsideSetupError as O, getRegistryFromApp as P, hydrateAttaformState as Q, RegistryNotInstalledError as R, injectForm as T, injectWizard as V, isRegisterValue as X, kAttaformRegistry as Y, lazy as Z, makeDefaultDisplayState as _, useRegister as a0, useRegistry as a1, useWizard as a2, vRegister as a3, AttaformError as c, AttaformErrorCode as d, DEVTOOLS_WINDOW_KEY as f, InvalidPathError as i, InvalidUseFormConfigError as j, ReservedFormKeyError as k, SubmitErrorHandlerError as n, assignKey as z };
|
|
2430
|
+
export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, GateMarker as G, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S, UseRegisterReturn as U, WizardAggregateError as W, AnyForm as a, AttaformDevtoolsBridge as b, AttaformPluginOptions as e, DisplayTimings as g, FormStatusSeed as h, SerializedFormData as l, StepSlot as m, UseWizardReturnType as o, WizardCtx as p, WizardCtxForm as q, WizardOnError as r, WizardOnSubmit as s, WizardOptions as t, WizardPersistFn as u, WizardRestoreFn as v, WizardRestoreState as w, WizardStatusesProxy as x, WizardSubmitContext as y };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { f as fieldMetaStore, g as getFieldMetaForSchema, a as getFieldMetaListForSchema, s as slimPrimitivesWalk, c as createAbstractSchema, w as walkPathSegments, d as deriveDefaultWalk, b as getFieldMetaPathMap, m as mergeDeep, p as peelEmbeddedDefault, N as NO_EMBEDDED_DEFAULT } from './attaform.
|
|
2
|
-
import {
|
|
3
|
-
import { A as AttaformError, _ as __DEV__, f as canonicalizePath, a as InvalidUseFormConfigError } from './attaform.
|
|
1
|
+
import { f as fieldMetaStore, g as getFieldMetaForSchema, a as getFieldMetaListForSchema, s as slimPrimitivesWalk, c as createAbstractSchema, w as walkPathSegments, d as deriveDefaultWalk, b as getFieldMetaPathMap, m as mergeDeep, p as peelEmbeddedDefault, N as NO_EMBEDDED_DEFAULT } from './attaform.BAlfXoAx.mjs';
|
|
2
|
+
import { q as humanize, r as getAtPath, p as slimKindOf, t as setAtPath, h as useAbstractForm } from './attaform.DGCijpZT.mjs';
|
|
3
|
+
import { A as AttaformError, _ as __DEV__, f as canonicalizePath, a as InvalidUseFormConfigError } from './attaform.CgsQZdy1.mjs';
|
|
4
4
|
|
|
5
5
|
const fieldMeta = fieldMetaStore;
|
|
6
6
|
function withMeta(schema, payload) {
|
|
@@ -1628,4 +1628,4 @@ function useForm(configuration) {
|
|
|
1628
1628
|
}
|
|
1629
1629
|
|
|
1630
1630
|
export { fieldMeta as f, isZodSchemaType as i, useForm as u, withMeta as w, zodAdapter as z };
|
|
1631
|
-
//# sourceMappingURL=attaform.
|
|
1631
|
+
//# sourceMappingURL=attaform.gyed1fGh.mjs.map
|