attaform 0.24.4 → 0.26.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/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 -4
- 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 +4 -4
- 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 +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.CO0e7YVY.d.cts → attaform.55hFR_cl.d.ts} +3 -0
- package/dist/shared/{attaform.Ib7oSpxj.d.cts → attaform.B71rfNL5.d.mts} +1 -1
- package/dist/shared/{attaform.DTn1J0Eq.d.mts → attaform.BFfY7HRI.d.cts} +1 -1
- package/dist/shared/{attaform.CAVK56f8.cjs → attaform.BPl-ECRT.cjs} +49 -2
- package/dist/shared/attaform.BPl-ECRT.cjs.map +1 -0
- package/dist/shared/{attaform.CBMI57RP.cjs → attaform.BQflyVOL.cjs} +3 -3
- package/dist/shared/{attaform.CBMI57RP.cjs.map → attaform.BQflyVOL.cjs.map} +1 -1
- package/dist/shared/{attaform.DWKcw1ud.cjs → attaform.BRzKBj2g.cjs} +101 -4
- package/dist/shared/attaform.BRzKBj2g.cjs.map +1 -0
- package/dist/shared/{attaform.EeVCVnoH.d.ts → attaform.Be5otUVw.d.ts} +1 -1
- package/dist/shared/{attaform.iJ4y3sHU.mjs → attaform.BoYqnIPI.mjs} +223 -81
- package/dist/shared/attaform.BoYqnIPI.mjs.map +1 -0
- package/dist/shared/{attaform.B1N47eDM.d.ts → attaform.CEY_WLRJ.d.mts} +127 -56
- package/dist/shared/{attaform.CwqTCeTZ.mjs → attaform.CSXDW2tO.mjs} +4 -4
- package/dist/shared/{attaform.CwqTCeTZ.mjs.map → attaform.CSXDW2tO.mjs.map} +1 -1
- package/dist/shared/{attaform.lcTiMoma.mjs → attaform.CXVmZtFq.mjs} +3 -3
- package/dist/shared/{attaform.lcTiMoma.mjs.map → attaform.CXVmZtFq.mjs.map} +1 -1
- package/dist/shared/{attaform.CE-KJZ0j.cjs → attaform.Cs0UZ7q6.cjs} +4 -4
- package/dist/shared/{attaform.CE-KJZ0j.cjs.map → attaform.Cs0UZ7q6.cjs.map} +1 -1
- package/dist/shared/{attaform.AkX9wzfY.cjs → attaform.D51IwDtP.cjs} +2 -2
- package/dist/shared/{attaform.AkX9wzfY.cjs.map → attaform.D51IwDtP.cjs.map} +1 -1
- package/dist/shared/{attaform.QFrCtJBO.d.mts → attaform.DBNjHgNj.d.cts} +86 -17
- package/dist/shared/{attaform.QFrCtJBO.d.cts → attaform.DBNjHgNj.d.mts} +86 -17
- package/dist/shared/{attaform.QFrCtJBO.d.ts → attaform.DBNjHgNj.d.ts} +86 -17
- package/dist/shared/{attaform.DwsfkfSY.mjs → attaform.DGhIix5D.mjs} +48 -3
- package/dist/shared/attaform.DGhIix5D.mjs.map +1 -0
- package/dist/shared/{attaform.CO0e7YVY.d.mts → attaform.DJRz_bzM.d.cts} +3 -0
- package/dist/shared/{attaform.ChY7tIrn.mjs → attaform.DSOIz08n.mjs} +4 -4
- package/dist/shared/{attaform.ChY7tIrn.mjs.map → attaform.DSOIz08n.mjs.map} +1 -1
- package/dist/shared/{attaform.Buedl_UL.cjs → attaform.Du9RZp8m.cjs} +223 -81
- package/dist/shared/attaform.Du9RZp8m.cjs.map +1 -0
- package/dist/shared/{attaform.CO0e7YVY.d.ts → attaform.JPsaqjLl.d.mts} +3 -0
- package/dist/shared/{attaform.CqW4gF_Z.d.cts → attaform.MgaYKlPP.d.cts} +127 -56
- package/dist/shared/{attaform.CZpUm-2l.mjs → attaform.NqYEzRcM.mjs} +2 -2
- package/dist/shared/{attaform.CZpUm-2l.mjs.map → attaform.NqYEzRcM.mjs.map} +1 -1
- package/dist/shared/{attaform.WvcckZMD.mjs → attaform.Vp2-CWZB.mjs} +3 -2
- package/dist/shared/attaform.Vp2-CWZB.mjs.map +1 -0
- package/dist/shared/{attaform.CjdepGnw.cjs → attaform.ZXZ6dH72.cjs} +3 -1
- package/dist/shared/attaform.ZXZ6dH72.cjs.map +1 -0
- package/dist/shared/{attaform.f0l5ydy1.d.mts → attaform.ceYeVkjn.d.ts} +127 -56
- package/dist/shared/{attaform.QwLSdxuk.mjs → attaform.k9V0py0s.mjs} +101 -5
- package/dist/shared/attaform.k9V0py0s.mjs.map +1 -0
- package/dist/shared/{attaform.Bnm0FQaH.cjs → attaform.tZ0YKisf.cjs} +4 -4
- package/dist/shared/{attaform.Bnm0FQaH.cjs.map → attaform.tZ0YKisf.cjs.map} +1 -1
- package/dist/transforms.cjs +2 -1
- package/dist/transforms.cjs.map +1 -1
- package/dist/transforms.d.cts +13 -1
- package/dist/transforms.d.mts +13 -1
- package/dist/transforms.d.ts +13 -1
- package/dist/transforms.mjs +1 -1
- package/dist/vite.cjs +2 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +2 -1
- package/dist/vite.mjs.map +1 -1
- package/dist/zod-v3.cjs +2 -2
- 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 +2 -2
- package/dist/zod-v4.cjs +2 -2
- 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 +2 -2
- package/dist/zod.cjs +5 -5
- package/dist/zod.d.cts +5 -5
- package/dist/zod.d.mts +5 -5
- package/dist/zod.d.ts +5 -5
- package/dist/zod.mjs +5 -5
- package/package.json +1 -1
- package/dist/shared/attaform.Buedl_UL.cjs.map +0 -1
- package/dist/shared/attaform.CAVK56f8.cjs.map +0 -1
- package/dist/shared/attaform.CjdepGnw.cjs.map +0 -1
- package/dist/shared/attaform.DWKcw1ud.cjs.map +0 -1
- package/dist/shared/attaform.DwsfkfSY.mjs.map +0 -1
- package/dist/shared/attaform.QwLSdxuk.mjs.map +0 -1
- package/dist/shared/attaform.WvcckZMD.mjs.map +0 -1
- package/dist/shared/attaform.iJ4y3sHU.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, readonly, toRaw, reactive, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope } from 'vue';
|
|
2
|
-
import { n as pathsEqual, j as isPathPrefix, _ as __DEV__, f as canonicalizePath, s as segmentsForPathKey, o as keyForSegments, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, q as INTERACTIVE_TAG_NAMES, R as ROOT_PATH,
|
|
3
|
-
import { R as REGISTER_OWNER_MARKER,
|
|
2
|
+
import { n as pathsEqual, j as isPathPrefix, _ as __DEV__, f as canonicalizePath, s as segmentsForPathKey, o as keyForSegments, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, q as normalizeErrorInput, r as INTERACTIVE_TAG_NAMES, R as ROOT_PATH, w as normalizeErrorInputs, x as coerceToPathKey, a as InvalidUseFormConfigError, y as ensureAttaformInstalled, u as useRegistry, z as kFormContext, B as kFormInstanceId, d as ReservedFormKeyError, l as kAttaformWizardActiveStepResolver, C as kAttaformAncestorWizard } from './attaform.DGhIix5D.mjs';
|
|
3
|
+
import { R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.Vp2-CWZB.mjs';
|
|
4
4
|
|
|
5
5
|
function safeAssign(target, key, value) {
|
|
6
6
|
if (key === "__proto__") {
|
|
@@ -582,7 +582,18 @@ const AttaformErrorCode = {
|
|
|
582
582
|
* produced `ValidationError` carrying a stable, branchable identifier.
|
|
583
583
|
* Override it per error by passing your own `code` (`api:…`, `auth:…`).
|
|
584
584
|
*/
|
|
585
|
-
UserError: "atta:user-error"
|
|
585
|
+
UserError: "atta:user-error",
|
|
586
|
+
/**
|
|
587
|
+
* Stamped on a `ValidationError` synthesized from a throw or rejection
|
|
588
|
+
* out of a `handleSubmit` `onSubmit` callback. The raw error also lands
|
|
589
|
+
* on `form.meta.submitError` (a raw-`Error` inspection channel); this
|
|
590
|
+
* code marks the copy piped into the user-error layer so the failure
|
|
591
|
+
* also surfaces on `form.errors` / `meta.ownErrors` / `firstOwnError`
|
|
592
|
+
* where the UI already reads. A throw carrying its own `path` / `code`
|
|
593
|
+
* keeps them; a bare `Error` or a non-Error throw defaults here at the
|
|
594
|
+
* form-level path `[]`.
|
|
595
|
+
*/
|
|
596
|
+
SubmitError: "atta:submit-error"
|
|
586
597
|
};
|
|
587
598
|
function makeBlankRequiredError(segments, formKey) {
|
|
588
599
|
return {
|
|
@@ -790,6 +801,11 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
790
801
|
elements: elementsArr,
|
|
791
802
|
updatedAt: record?.updatedAt ?? null,
|
|
792
803
|
errors,
|
|
804
|
+
// A leaf has no descendants, so its own-bucket errors ARE its subtree
|
|
805
|
+
// errors. Reuse the same array reference: referential `ownErrors ===
|
|
806
|
+
// errors`, and no second read of the whole-form `derivedBlankErrors`
|
|
807
|
+
// map (preserves the P3 blank-reactivity optimization above).
|
|
808
|
+
ownErrors: errors,
|
|
793
809
|
validating,
|
|
794
810
|
valid,
|
|
795
811
|
transforming,
|
|
@@ -968,6 +984,12 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
968
984
|
elements: EMPTY_ELEMENTS,
|
|
969
985
|
updatedAt,
|
|
970
986
|
errors,
|
|
987
|
+
// The container's OWN bucket only (this exact path), excluding every
|
|
988
|
+
// descendant that `errors` rolls up: a cross-field `.refine()` here,
|
|
989
|
+
// or `setErrors` pinned at this node. The same raw union the leaf
|
|
990
|
+
// builds from the three stores; the container already depends on all
|
|
991
|
+
// three via `aggregateErrorsAt`, so there's no new reactivity cost.
|
|
992
|
+
ownErrors: state.getErrorsForPath(segments),
|
|
971
993
|
validating,
|
|
972
994
|
valid,
|
|
973
995
|
transforming,
|
|
@@ -1006,6 +1028,7 @@ function buildContainerFieldState(state, segments, key, formInstanceId, getFormM
|
|
|
1006
1028
|
}
|
|
1007
1029
|
function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingSince, transformingSince, revealedDescendantError, isRoot, getDisplayState) {
|
|
1008
1030
|
const firstError = base.errors[0];
|
|
1031
|
+
const firstOwnError = base.ownErrors[0];
|
|
1009
1032
|
const predicate = getDisplayState ?? state.getDisplayState;
|
|
1010
1033
|
const formMeta = getFormMetaBase();
|
|
1011
1034
|
const ctx = {
|
|
@@ -1041,7 +1064,8 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
1041
1064
|
showPending: displayState === "pending",
|
|
1042
1065
|
showSuccess: displayState === "success",
|
|
1043
1066
|
showIdle: displayState === "idle",
|
|
1044
|
-
firstError
|
|
1067
|
+
firstError,
|
|
1068
|
+
firstOwnError
|
|
1045
1069
|
};
|
|
1046
1070
|
}
|
|
1047
1071
|
function aggregateErrorsAt(state, prefix) {
|
|
@@ -1410,17 +1434,15 @@ function buildErrorsProxy(state) {
|
|
|
1410
1434
|
// shared `aggregateErrorsAt` helper that `form.meta.errors` and
|
|
1411
1435
|
// `form.fields(path).errors` also use, so the surfaces never drift.
|
|
1412
1436
|
//
|
|
1413
|
-
// The root is
|
|
1414
|
-
//
|
|
1415
|
-
//
|
|
1416
|
-
//
|
|
1417
|
-
//
|
|
1418
|
-
//
|
|
1419
|
-
|
|
1420
|
-
resolveCallTarget: (path) => path.length === 0 ? state.getErrorsForPath([]) : aggregateErrorsAt(state, path),
|
|
1437
|
+
// The root is uniform with every other path: `errors([])` is the
|
|
1438
|
+
// subtree aggregate at `[]`, which is the whole form, identical to
|
|
1439
|
+
// the no-arg `errors()` and to `meta.errors`. The root `[]` bucket
|
|
1440
|
+
// alone (root `.refine()`, hydration failures, path-less
|
|
1441
|
+
// `setErrors`) is read through `meta.ownErrors` / `meta.firstOwnError`,
|
|
1442
|
+
// the dedicated own-bucket accessor, not a call-form carve-out.
|
|
1443
|
+
resolveCallTarget: (path) => aggregateErrorsAt(state, path),
|
|
1421
1444
|
// No-arg `errors()` = the whole-form aggregate, matching
|
|
1422
|
-
// `meta.errors
|
|
1423
|
-
// see `resolveCallTarget`.
|
|
1445
|
+
// `meta.errors` and `errors([])`. All three are the same aggregate.
|
|
1424
1446
|
resolveRootCall: () => aggregateErrorsAt(state, []),
|
|
1425
1447
|
// Enumeration unions the live form-data keys at this path with the
|
|
1426
1448
|
// first-child segments drawn from every error store. Without the
|
|
@@ -1604,6 +1626,7 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1604
1626
|
"elements",
|
|
1605
1627
|
"updatedAt",
|
|
1606
1628
|
"errors",
|
|
1629
|
+
"ownErrors",
|
|
1607
1630
|
"validating",
|
|
1608
1631
|
"valid",
|
|
1609
1632
|
"transforming",
|
|
@@ -1615,6 +1638,7 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1615
1638
|
"showSuccess",
|
|
1616
1639
|
"showIdle",
|
|
1617
1640
|
"firstError",
|
|
1641
|
+
"firstOwnError",
|
|
1618
1642
|
"path",
|
|
1619
1643
|
"id",
|
|
1620
1644
|
"aria",
|
|
@@ -1756,6 +1780,32 @@ function walk$1(value, basePath, schema, snapshotFieldStateAt) {
|
|
|
1756
1780
|
}
|
|
1757
1781
|
|
|
1758
1782
|
const warnedNoScopeStores = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
1783
|
+
function isErrorInputLike(value) {
|
|
1784
|
+
if (value instanceof Error) return true;
|
|
1785
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1786
|
+
const shape = value;
|
|
1787
|
+
return typeof shape.message === "string" && shape.message.length > 0 || Array.isArray(shape.path);
|
|
1788
|
+
}
|
|
1789
|
+
function deriveSubmitErrors(err, formKey) {
|
|
1790
|
+
if (Array.isArray(err) && err.length > 0 && err.every(isErrorInputLike)) {
|
|
1791
|
+
return {
|
|
1792
|
+
entries: err.map(
|
|
1793
|
+
(item) => normalizeErrorInput(item, void 0, formKey, AttaformErrorCode.SubmitError)
|
|
1794
|
+
),
|
|
1795
|
+
messageless: false
|
|
1796
|
+
};
|
|
1797
|
+
}
|
|
1798
|
+
if (isErrorInputLike(err)) {
|
|
1799
|
+
return {
|
|
1800
|
+
entries: [normalizeErrorInput(err, void 0, formKey, AttaformErrorCode.SubmitError)],
|
|
1801
|
+
messageless: false
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
return {
|
|
1805
|
+
entries: [normalizeErrorInput({}, void 0, formKey, AttaformErrorCode.SubmitError)],
|
|
1806
|
+
messageless: true
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1759
1809
|
function buildProcessForm(state, formInstanceId, options = {}) {
|
|
1760
1810
|
const invalidPolicy = options.onInvalidSubmit ?? "focus-first-error";
|
|
1761
1811
|
function validate(pathInput) {
|
|
@@ -1937,13 +1987,6 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1937
1987
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
1938
1988
|
applyInvalidSubmitPolicy(state, formInstanceId, invalidPolicy);
|
|
1939
1989
|
}
|
|
1940
|
-
if (onError !== void 0) {
|
|
1941
|
-
try {
|
|
1942
|
-
await onError(Array.from(state.userErrors.values()).flat());
|
|
1943
|
-
} catch (cause) {
|
|
1944
|
-
throw new SubmitErrorHandlerError("User-provided onError threw", { cause });
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
1990
|
return;
|
|
1948
1991
|
}
|
|
1949
1992
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
@@ -1953,6 +1996,25 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1953
1996
|
} catch (err) {
|
|
1954
1997
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
1955
1998
|
state.submitError.value = toError(err);
|
|
1999
|
+
if (!(err instanceof SubmitErrorHandlerError)) {
|
|
2000
|
+
const { entries, messageless } = deriveSubmitErrors(err, state.formKey);
|
|
2001
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
2002
|
+
for (const entry of entries) {
|
|
2003
|
+
const { key } = canonicalizePath(entry.path);
|
|
2004
|
+
const bucket = byPath.get(key);
|
|
2005
|
+
if (bucket === void 0) byPath.set(key, { segments: entry.path, entries: [entry] });
|
|
2006
|
+
else bucket.entries.push(entry);
|
|
2007
|
+
}
|
|
2008
|
+
for (const { segments, entries: bucket } of byPath.values()) {
|
|
2009
|
+
state.setUserErrorsForPath(segments, bucket);
|
|
2010
|
+
}
|
|
2011
|
+
applyInvalidSubmitPolicy(state, formInstanceId, invalidPolicy);
|
|
2012
|
+
if (__DEV__ && messageless) {
|
|
2013
|
+
console.warn(
|
|
2014
|
+
"[attaform] handleSubmit callback threw a non-Error value; throw an Error or a ValidationError ({ message, path? }) so the failure surfaces with a usable message."
|
|
2015
|
+
);
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
1956
2018
|
}
|
|
1957
2019
|
} finally {
|
|
1958
2020
|
if (!validationSettled) {
|
|
@@ -2018,11 +2080,11 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
|
|
|
2018
2080
|
return;
|
|
2019
2081
|
}
|
|
2020
2082
|
if (policy === "focus-first-error") {
|
|
2021
|
-
target.element.focus();
|
|
2083
|
+
target.element.focus({ focusVisible: true });
|
|
2022
2084
|
return;
|
|
2023
2085
|
}
|
|
2024
2086
|
target.element.scrollIntoView();
|
|
2025
|
-
target.element.focus({ preventScroll: true });
|
|
2087
|
+
target.element.focus({ preventScroll: true, focusVisible: true });
|
|
2026
2088
|
}
|
|
2027
2089
|
|
|
2028
2090
|
const warnedRejections = __DEV__ ? /* @__PURE__ */ new WeakMap() : null;
|
|
@@ -2814,6 +2876,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2814
2876
|
get errors() {
|
|
2815
2877
|
return rootBase().errors;
|
|
2816
2878
|
},
|
|
2879
|
+
get ownErrors() {
|
|
2880
|
+
return rootBase().ownErrors;
|
|
2881
|
+
},
|
|
2817
2882
|
get validating() {
|
|
2818
2883
|
return rootBase().validating;
|
|
2819
2884
|
},
|
|
@@ -2977,28 +3042,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2977
3042
|
return true;
|
|
2978
3043
|
}
|
|
2979
3044
|
const errorsProxy = buildErrorsProxy(state);
|
|
2980
|
-
function normalizeErrorInput(item, scope) {
|
|
2981
|
-
if (item instanceof Error) {
|
|
2982
|
-
return {
|
|
2983
|
-
message: item.message.length > 0 ? item.message : "Unknown error",
|
|
2984
|
-
path: scope !== void 0 ? [...scope] : [],
|
|
2985
|
-
formKey: state.formKey,
|
|
2986
|
-
code: AttaformErrorCode.UserError
|
|
2987
|
-
};
|
|
2988
|
-
}
|
|
2989
|
-
const entry = {
|
|
2990
|
-
message: typeof item.message === "string" && item.message.length > 0 ? item.message : "Unknown error",
|
|
2991
|
-
path: scope !== void 0 ? [...scope] : Array.isArray(item.path) ? [...item.path] : [],
|
|
2992
|
-
formKey: state.formKey,
|
|
2993
|
-
code: typeof item.code === "string" && item.code.length > 0 ? item.code : AttaformErrorCode.UserError
|
|
2994
|
-
};
|
|
2995
|
-
if (item.data !== void 0) entry.data = item.data;
|
|
2996
|
-
return entry;
|
|
2997
|
-
}
|
|
2998
|
-
function normalizeErrorInputs(input, scope) {
|
|
2999
|
-
const items = Array.isArray(input) ? input : [input];
|
|
3000
|
-
return items.map((item) => normalizeErrorInput(item, scope));
|
|
3001
|
-
}
|
|
3002
3045
|
function flattenUserErrors() {
|
|
3003
3046
|
const all = [];
|
|
3004
3047
|
for (const errs of state.userErrors.values()) all.push(...errs);
|
|
@@ -3010,12 +3053,17 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3010
3053
|
const { segments, key } = canonicalizePath(arg1);
|
|
3011
3054
|
const input2 = arg2;
|
|
3012
3055
|
const resolved2 = typeof input2 === "function" ? input2((state.userErrors.get(key) ?? []).slice()) : input2;
|
|
3013
|
-
state.setUserErrorsForPath(
|
|
3056
|
+
state.setUserErrorsForPath(
|
|
3057
|
+
segments,
|
|
3058
|
+
normalizeErrorInputs(resolved2, segments, state.formKey, AttaformErrorCode.UserError)
|
|
3059
|
+
);
|
|
3014
3060
|
return;
|
|
3015
3061
|
}
|
|
3016
3062
|
const input = arg1;
|
|
3017
3063
|
const resolved = typeof input === "function" ? input(flattenUserErrors()) : input;
|
|
3018
|
-
state.setAllUserErrors(
|
|
3064
|
+
state.setAllUserErrors(
|
|
3065
|
+
normalizeErrorInputs(resolved, void 0, state.formKey, AttaformErrorCode.UserError)
|
|
3066
|
+
);
|
|
3019
3067
|
}
|
|
3020
3068
|
function clearErrors(path) {
|
|
3021
3069
|
if (path === void 0) {
|
|
@@ -3110,6 +3158,17 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3110
3158
|
// keep the explicit form-level computation for the gate.
|
|
3111
3159
|
valid,
|
|
3112
3160
|
errors: metaErrors,
|
|
3161
|
+
// The root `[]` bucket alone: form-level errors from a root
|
|
3162
|
+
// `.refine()` or a path-less `setErrors`, excluding every field error
|
|
3163
|
+
// that `errors` (the whole-form aggregate) rolls up. This is the
|
|
3164
|
+
// banner accessor. Mirrors `rootFieldState` rather than taking a
|
|
3165
|
+
// dedicated computed: `getFieldState([])` routes a container root
|
|
3166
|
+
// through `getErrorsForPath([])` and a primitive root through its own
|
|
3167
|
+
// bucket, and both equal the root bucket, so the root field state is
|
|
3168
|
+
// already the single source of truth.
|
|
3169
|
+
get ownErrors() {
|
|
3170
|
+
return rootFieldState.value.ownErrors;
|
|
3171
|
+
},
|
|
3113
3172
|
// Whole-form transforming mirrors the global `activeTransforms`
|
|
3114
3173
|
// counter ORed with any per-leaf transform in flight (the root
|
|
3115
3174
|
// rollup), exactly as `validating` composes its lifecycle and
|
|
@@ -3148,6 +3207,11 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3148
3207
|
get firstError() {
|
|
3149
3208
|
return rootFieldState.value.firstError;
|
|
3150
3209
|
},
|
|
3210
|
+
// `ownErrors[0]`: the form's first top-level error. Pair it with
|
|
3211
|
+
// `ownErrors` for the form-level banner.
|
|
3212
|
+
get firstOwnError() {
|
|
3213
|
+
return rootFieldState.value.firstOwnError;
|
|
3214
|
+
},
|
|
3151
3215
|
get path() {
|
|
3152
3216
|
return rootFieldState.value.path;
|
|
3153
3217
|
},
|
|
@@ -3227,7 +3291,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3227
3291
|
const focusFirstError = (options2) => {
|
|
3228
3292
|
const target = state.getFirstErrorElement(formInstanceId);
|
|
3229
3293
|
if (target === null) return false;
|
|
3230
|
-
target.element.focus(options2);
|
|
3294
|
+
target.element.focus({ focusVisible: true, ...options2 });
|
|
3231
3295
|
return true;
|
|
3232
3296
|
};
|
|
3233
3297
|
const scrollToFirstError = (options2) => {
|
|
@@ -5364,10 +5428,7 @@ function createFormStore(options) {
|
|
|
5364
5428
|
if (elementToFormInstance.get(entry.element) !== formInstanceId) continue;
|
|
5365
5429
|
if (!entry.element.isConnected) continue;
|
|
5366
5430
|
if (entry.element.offsetParent === null) continue;
|
|
5367
|
-
|
|
5368
|
-
const hasSchemaErr = (schemaErrors.get(key)?.length ?? 0) > 0;
|
|
5369
|
-
const hasUserErr = (userErrors.get(key)?.length ?? 0) > 0;
|
|
5370
|
-
if (!hasSchemaErr && !hasUserErr) continue;
|
|
5431
|
+
if (getErrorsForPath(entry.path).length === 0) continue;
|
|
5371
5432
|
return { path: entry.path, element: entry.element };
|
|
5372
5433
|
}
|
|
5373
5434
|
return null;
|
|
@@ -5947,7 +6008,7 @@ function resolveState(key, registry) {
|
|
|
5947
6008
|
if (key !== void 0) {
|
|
5948
6009
|
const stored = registry.forms.get(key);
|
|
5949
6010
|
if (stored === void 0) {
|
|
5950
|
-
warnMiss$1(`no form registered for key '${key}'`, registry.ssr);
|
|
6011
|
+
warnMiss$1(`no form registered for key '${key}'`, registry.ssr, registry.forms);
|
|
5951
6012
|
return null;
|
|
5952
6013
|
}
|
|
5953
6014
|
return stored;
|
|
@@ -5957,12 +6018,22 @@ function resolveState(key, registry) {
|
|
|
5957
6018
|
warnIfAmbientProviderHadDuplicates();
|
|
5958
6019
|
return ambient;
|
|
5959
6020
|
}
|
|
5960
|
-
function
|
|
6021
|
+
function availableKeysHint$1(forms) {
|
|
6022
|
+
const addressable = [...forms.keys()].filter((key) => !key.startsWith(RESERVED_KEY_PREFIX));
|
|
6023
|
+
if (addressable.length === 0) return void 0;
|
|
6024
|
+
return `Registered keys: ${addressable.map((key) => `'${key}'`).join(", ")}.`;
|
|
6025
|
+
}
|
|
6026
|
+
function warnMiss$1(detail, ssr, forms) {
|
|
5961
6027
|
if (!__DEV__ || ssr) return;
|
|
5962
6028
|
const frame = captureUserCallSite();
|
|
5963
|
-
|
|
5964
|
-
|
|
6029
|
+
const parts = [`[attaform] injectForm: ${detail}. Returning null.`];
|
|
6030
|
+
const keys = availableKeysHint$1(forms);
|
|
6031
|
+
if (keys !== void 0) parts.push(keys);
|
|
6032
|
+
parts.push(
|
|
6033
|
+
`A form created by a child or sibling component is not registered until that component's own setup runs, which happens after this point. Lift its useForm({ key }) call to a common ancestor, or read the form after mount.`
|
|
5965
6034
|
);
|
|
6035
|
+
if (frame !== void 0) parts.push(frame);
|
|
6036
|
+
console.warn(parts.join(" "));
|
|
5966
6037
|
}
|
|
5967
6038
|
function warnIfAmbientProviderHadDuplicates() {
|
|
5968
6039
|
if (!__DEV__ || ambientProvideHistory === null) return;
|
|
@@ -6222,6 +6293,9 @@ function asStatusSource(form) {
|
|
|
6222
6293
|
function asSubmissionSource(form) {
|
|
6223
6294
|
return form;
|
|
6224
6295
|
}
|
|
6296
|
+
function asHandleSubmitSource(form) {
|
|
6297
|
+
return form;
|
|
6298
|
+
}
|
|
6225
6299
|
function useWizard(options) {
|
|
6226
6300
|
const rawSteps = Array.isArray(options.steps) ? options.steps : [];
|
|
6227
6301
|
if (rawSteps.length === 0 && __DEV__) {
|
|
@@ -6316,6 +6390,7 @@ function useWizard(options) {
|
|
|
6316
6390
|
}
|
|
6317
6391
|
};
|
|
6318
6392
|
function resolveSlot(slot, index, ctx) {
|
|
6393
|
+
if (slot === void 0 || slot === null) return void 0;
|
|
6319
6394
|
if (typeof slot === "string") {
|
|
6320
6395
|
return getOrBuildNoop(slot);
|
|
6321
6396
|
}
|
|
@@ -6331,7 +6406,7 @@ function useWizard(options) {
|
|
|
6331
6406
|
return void 0;
|
|
6332
6407
|
}
|
|
6333
6408
|
function resolveSlotResult(result) {
|
|
6334
|
-
if (result === void 0) return void 0;
|
|
6409
|
+
if (result === void 0 || result === null) return void 0;
|
|
6335
6410
|
if (typeof result === "string") {
|
|
6336
6411
|
return getOrBuildNoop(result);
|
|
6337
6412
|
}
|
|
@@ -6399,6 +6474,50 @@ function useWizard(options) {
|
|
|
6399
6474
|
const first = list[0];
|
|
6400
6475
|
return first === void 0 ? void 0 : first.form;
|
|
6401
6476
|
});
|
|
6477
|
+
watch(compiledSteps, (list, prevList) => {
|
|
6478
|
+
const key = activeKey.value;
|
|
6479
|
+
if (key === "") return;
|
|
6480
|
+
if (list.some((step) => step.key === key)) return;
|
|
6481
|
+
if (list.length === 0) {
|
|
6482
|
+
activeKey.value = "";
|
|
6483
|
+
return;
|
|
6484
|
+
}
|
|
6485
|
+
const oldIndex = prevList.findIndex((step) => step.key === key);
|
|
6486
|
+
const slid = list[oldIndex < 0 ? 0 : Math.min(oldIndex, list.length - 1)];
|
|
6487
|
+
if (slid !== void 0) activeKey.value = slid.key;
|
|
6488
|
+
});
|
|
6489
|
+
const activeFormFacade = new Proxy({}, {
|
|
6490
|
+
get(_target, prop) {
|
|
6491
|
+
const form = activeForm.value;
|
|
6492
|
+
if (form === void 0) return void 0;
|
|
6493
|
+
if (prop === "handleSubmit") {
|
|
6494
|
+
const lateBound = (onValid, onInvalid) => {
|
|
6495
|
+
return (event) => {
|
|
6496
|
+
const current = activeForm.value;
|
|
6497
|
+
if (current === void 0) return Promise.resolve();
|
|
6498
|
+
return asHandleSubmitSource(current).handleSubmit(onValid, onInvalid)(event);
|
|
6499
|
+
};
|
|
6500
|
+
};
|
|
6501
|
+
return lateBound;
|
|
6502
|
+
}
|
|
6503
|
+
return Reflect.get(form, prop, form);
|
|
6504
|
+
},
|
|
6505
|
+
has(_target, prop) {
|
|
6506
|
+
const form = activeForm.value;
|
|
6507
|
+
return form === void 0 ? false : Reflect.has(form, prop);
|
|
6508
|
+
},
|
|
6509
|
+
ownKeys(_target) {
|
|
6510
|
+
const form = activeForm.value;
|
|
6511
|
+
return form === void 0 ? [] : Reflect.ownKeys(form);
|
|
6512
|
+
},
|
|
6513
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
6514
|
+
const form = activeForm.value;
|
|
6515
|
+
if (form === void 0) return void 0;
|
|
6516
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(form, prop);
|
|
6517
|
+
if (descriptor === void 0) return void 0;
|
|
6518
|
+
return { ...descriptor, configurable: true };
|
|
6519
|
+
}
|
|
6520
|
+
});
|
|
6402
6521
|
const isFinalStep = computed(() => {
|
|
6403
6522
|
const list = compiledSteps.value;
|
|
6404
6523
|
const idx = activeIndex.value;
|
|
@@ -6763,6 +6882,39 @@ function useWizard(options) {
|
|
|
6763
6882
|
const target = list[idx + 1];
|
|
6764
6883
|
moveTo(target.key);
|
|
6765
6884
|
}
|
|
6885
|
+
async function tryNext() {
|
|
6886
|
+
if (submitting.value) {
|
|
6887
|
+
if (__DEV__) {
|
|
6888
|
+
console.warn(`[attaform] wizard.tryNext(): blocked while a submit is in flight.`);
|
|
6889
|
+
}
|
|
6890
|
+
return false;
|
|
6891
|
+
}
|
|
6892
|
+
const list = compiledSteps.value;
|
|
6893
|
+
if (list.length === 0) {
|
|
6894
|
+
if (__DEV__) {
|
|
6895
|
+
console.warn(`[attaform] wizard.tryNext(): wizard has no compiled steps; no-op.`);
|
|
6896
|
+
}
|
|
6897
|
+
return false;
|
|
6898
|
+
}
|
|
6899
|
+
const idx = activeIndex.value;
|
|
6900
|
+
if (idx < 0 || idx >= list.length - 1) {
|
|
6901
|
+
if (__DEV__) {
|
|
6902
|
+
console.warn(
|
|
6903
|
+
`[attaform] wizard.tryNext(): already on the final step ("${activeKey.value}"). Use wizard.handleSubmit() to submit.`
|
|
6904
|
+
);
|
|
6905
|
+
}
|
|
6906
|
+
return false;
|
|
6907
|
+
}
|
|
6908
|
+
const form = activeForm.value;
|
|
6909
|
+
if (form === void 0) return false;
|
|
6910
|
+
let advanced = false;
|
|
6911
|
+
await asHandleSubmitSource(form).handleSubmit(() => {
|
|
6912
|
+
const before = activeKey.value;
|
|
6913
|
+
next();
|
|
6914
|
+
advanced = activeKey.value !== before;
|
|
6915
|
+
})();
|
|
6916
|
+
return advanced;
|
|
6917
|
+
}
|
|
6766
6918
|
function back() {
|
|
6767
6919
|
if (submitting.value) {
|
|
6768
6920
|
if (__DEV__) {
|
|
@@ -6899,20 +7051,13 @@ function useWizard(options) {
|
|
|
6899
7051
|
const final = isFinalStep.value;
|
|
6900
7052
|
const list = compiledSteps.value;
|
|
6901
7053
|
const results = /* @__PURE__ */ new Map();
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
);
|
|
6910
|
-
} else {
|
|
6911
|
-
const active = activeForm.value;
|
|
6912
|
-
registry.forms.get(active.key)?.clearUserErrors();
|
|
6913
|
-
const result = await processOne(active);
|
|
6914
|
-
results.set(active.key, result);
|
|
6915
|
-
}
|
|
7054
|
+
await Promise.all(
|
|
7055
|
+
list.map(async (step) => {
|
|
7056
|
+
registry.forms.get(step.key)?.clearUserErrors();
|
|
7057
|
+
const result = await processOne(step.form);
|
|
7058
|
+
results.set(step.key, result);
|
|
7059
|
+
})
|
|
7060
|
+
);
|
|
6916
7061
|
for (const key of results.keys()) {
|
|
6917
7062
|
const store = registry.forms.get(key);
|
|
6918
7063
|
if (store !== void 0) {
|
|
@@ -6947,14 +7092,7 @@ function useWizard(options) {
|
|
|
6947
7092
|
}
|
|
6948
7093
|
return;
|
|
6949
7094
|
}
|
|
6950
|
-
|
|
6951
|
-
done.value = true;
|
|
6952
|
-
} else {
|
|
6953
|
-
recordDeparture(currentKey);
|
|
6954
|
-
const idx = activeIndex.value;
|
|
6955
|
-
const target = list[idx + 1];
|
|
6956
|
-
if (target !== void 0) moveTo(target.key);
|
|
6957
|
-
}
|
|
7095
|
+
done.value = true;
|
|
6958
7096
|
} else {
|
|
6959
7097
|
await focusFirstWizardError(errors);
|
|
6960
7098
|
if (onError !== void 0) {
|
|
@@ -7004,13 +7142,14 @@ function useWizard(options) {
|
|
|
7004
7142
|
next,
|
|
7005
7143
|
back,
|
|
7006
7144
|
goTo,
|
|
7145
|
+
tryNext,
|
|
7007
7146
|
handleSubmit,
|
|
7008
7147
|
reset,
|
|
7009
7148
|
get currentStep() {
|
|
7010
7149
|
return currentStep.value;
|
|
7011
7150
|
},
|
|
7012
7151
|
get activeForm() {
|
|
7013
|
-
return activeForm.value;
|
|
7152
|
+
return activeForm.value === void 0 ? void 0 : activeFormFacade;
|
|
7014
7153
|
},
|
|
7015
7154
|
get activeIndex() {
|
|
7016
7155
|
return activeIndex.value;
|
|
@@ -7142,6 +7281,9 @@ function warnMiss(detail, ssr, hint) {
|
|
|
7142
7281
|
const frame = captureUserCallSite();
|
|
7143
7282
|
const parts = [`[attaform] injectWizard: ${detail}. Returning null.`];
|
|
7144
7283
|
if (hint !== void 0) parts.push(hint);
|
|
7284
|
+
parts.push(
|
|
7285
|
+
`A wizard created by a child or sibling component is not registered until that component's own setup runs, which happens after this point. Lift its useWizard({ key }) call to a common ancestor, or read the wizard after mount.`
|
|
7286
|
+
);
|
|
7145
7287
|
if (frame !== void 0) parts.push(frame);
|
|
7146
7288
|
console.warn(parts.join(" "));
|
|
7147
7289
|
}
|
|
@@ -7164,4 +7306,4 @@ function warnIfAmbientWizardProviderHadDuplicates() {
|
|
|
7164
7306
|
}
|
|
7165
7307
|
|
|
7166
7308
|
export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, defaultCoercionRules as e, defaultDisplayState as f, defineCoercion as g, useAbstractForm as h, injectForm as i, isPlainRecord as j, safeAssign as k, lazy as l, makeDefaultDisplayState as m, slimKindOf as n, humanize as o, getAtPath as p, setAtPath as q, safeOwnRead as s, unset as u };
|
|
7167
|
-
//# sourceMappingURL=attaform.
|
|
7309
|
+
//# sourceMappingURL=attaform.BoYqnIPI.mjs.map
|