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,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const vue = require('vue');
|
|
4
|
-
const paths = require('./attaform.
|
|
5
|
-
const registerProtocol = require('./attaform.
|
|
4
|
+
const paths = require('./attaform.BPl-ECRT.cjs');
|
|
5
|
+
const registerProtocol = require('./attaform.ZXZ6dH72.cjs');
|
|
6
6
|
|
|
7
7
|
function safeAssign(target, key, value) {
|
|
8
8
|
if (key === "__proto__") {
|
|
@@ -584,7 +584,18 @@ const AttaformErrorCode = {
|
|
|
584
584
|
* produced `ValidationError` carrying a stable, branchable identifier.
|
|
585
585
|
* Override it per error by passing your own `code` (`api:…`, `auth:…`).
|
|
586
586
|
*/
|
|
587
|
-
UserError: "atta:user-error"
|
|
587
|
+
UserError: "atta:user-error",
|
|
588
|
+
/**
|
|
589
|
+
* Stamped on a `ValidationError` synthesized from a throw or rejection
|
|
590
|
+
* out of a `handleSubmit` `onSubmit` callback. The raw error also lands
|
|
591
|
+
* on `form.meta.submitError` (a raw-`Error` inspection channel); this
|
|
592
|
+
* code marks the copy piped into the user-error layer so the failure
|
|
593
|
+
* also surfaces on `form.errors` / `meta.ownErrors` / `firstOwnError`
|
|
594
|
+
* where the UI already reads. A throw carrying its own `path` / `code`
|
|
595
|
+
* keeps them; a bare `Error` or a non-Error throw defaults here at the
|
|
596
|
+
* form-level path `[]`.
|
|
597
|
+
*/
|
|
598
|
+
SubmitError: "atta:submit-error"
|
|
588
599
|
};
|
|
589
600
|
function makeBlankRequiredError(segments, formKey) {
|
|
590
601
|
return {
|
|
@@ -792,6 +803,11 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
792
803
|
elements: elementsArr,
|
|
793
804
|
updatedAt: record?.updatedAt ?? null,
|
|
794
805
|
errors,
|
|
806
|
+
// A leaf has no descendants, so its own-bucket errors ARE its subtree
|
|
807
|
+
// errors. Reuse the same array reference: referential `ownErrors ===
|
|
808
|
+
// errors`, and no second read of the whole-form `derivedBlankErrors`
|
|
809
|
+
// map (preserves the P3 blank-reactivity optimization above).
|
|
810
|
+
ownErrors: errors,
|
|
795
811
|
validating,
|
|
796
812
|
valid,
|
|
797
813
|
transforming,
|
|
@@ -970,6 +986,12 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
970
986
|
elements: EMPTY_ELEMENTS,
|
|
971
987
|
updatedAt,
|
|
972
988
|
errors,
|
|
989
|
+
// The container's OWN bucket only (this exact path), excluding every
|
|
990
|
+
// descendant that `errors` rolls up: a cross-field `.refine()` here,
|
|
991
|
+
// or `setErrors` pinned at this node. The same raw union the leaf
|
|
992
|
+
// builds from the three stores; the container already depends on all
|
|
993
|
+
// three via `aggregateErrorsAt`, so there's no new reactivity cost.
|
|
994
|
+
ownErrors: state.getErrorsForPath(segments),
|
|
973
995
|
validating,
|
|
974
996
|
valid,
|
|
975
997
|
transforming,
|
|
@@ -1008,6 +1030,7 @@ function buildContainerFieldState(state, segments, key, formInstanceId, getFormM
|
|
|
1008
1030
|
}
|
|
1009
1031
|
function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingSince, transformingSince, revealedDescendantError, isRoot, getDisplayState) {
|
|
1010
1032
|
const firstError = base.errors[0];
|
|
1033
|
+
const firstOwnError = base.ownErrors[0];
|
|
1011
1034
|
const predicate = getDisplayState ?? state.getDisplayState;
|
|
1012
1035
|
const formMeta = getFormMetaBase();
|
|
1013
1036
|
const ctx = {
|
|
@@ -1043,7 +1066,8 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
1043
1066
|
showPending: displayState === "pending",
|
|
1044
1067
|
showSuccess: displayState === "success",
|
|
1045
1068
|
showIdle: displayState === "idle",
|
|
1046
|
-
firstError
|
|
1069
|
+
firstError,
|
|
1070
|
+
firstOwnError
|
|
1047
1071
|
};
|
|
1048
1072
|
}
|
|
1049
1073
|
function aggregateErrorsAt(state, prefix) {
|
|
@@ -1412,17 +1436,15 @@ function buildErrorsProxy(state) {
|
|
|
1412
1436
|
// shared `aggregateErrorsAt` helper that `form.meta.errors` and
|
|
1413
1437
|
// `form.fields(path).errors` also use, so the surfaces never drift.
|
|
1414
1438
|
//
|
|
1415
|
-
// The root is
|
|
1416
|
-
//
|
|
1417
|
-
//
|
|
1418
|
-
//
|
|
1419
|
-
//
|
|
1420
|
-
//
|
|
1421
|
-
|
|
1422
|
-
resolveCallTarget: (path) => path.length === 0 ? state.getErrorsForPath([]) : aggregateErrorsAt(state, path),
|
|
1439
|
+
// The root is uniform with every other path: `errors([])` is the
|
|
1440
|
+
// subtree aggregate at `[]`, which is the whole form, identical to
|
|
1441
|
+
// the no-arg `errors()` and to `meta.errors`. The root `[]` bucket
|
|
1442
|
+
// alone (root `.refine()`, hydration failures, path-less
|
|
1443
|
+
// `setErrors`) is read through `meta.ownErrors` / `meta.firstOwnError`,
|
|
1444
|
+
// the dedicated own-bucket accessor, not a call-form carve-out.
|
|
1445
|
+
resolveCallTarget: (path) => aggregateErrorsAt(state, path),
|
|
1423
1446
|
// No-arg `errors()` = the whole-form aggregate, matching
|
|
1424
|
-
// `meta.errors
|
|
1425
|
-
// see `resolveCallTarget`.
|
|
1447
|
+
// `meta.errors` and `errors([])`. All three are the same aggregate.
|
|
1426
1448
|
resolveRootCall: () => aggregateErrorsAt(state, []),
|
|
1427
1449
|
// Enumeration unions the live form-data keys at this path with the
|
|
1428
1450
|
// first-child segments drawn from every error store. Without the
|
|
@@ -1606,6 +1628,7 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1606
1628
|
"elements",
|
|
1607
1629
|
"updatedAt",
|
|
1608
1630
|
"errors",
|
|
1631
|
+
"ownErrors",
|
|
1609
1632
|
"validating",
|
|
1610
1633
|
"valid",
|
|
1611
1634
|
"transforming",
|
|
@@ -1617,6 +1640,7 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1617
1640
|
"showSuccess",
|
|
1618
1641
|
"showIdle",
|
|
1619
1642
|
"firstError",
|
|
1643
|
+
"firstOwnError",
|
|
1620
1644
|
"path",
|
|
1621
1645
|
"id",
|
|
1622
1646
|
"aria",
|
|
@@ -1758,6 +1782,32 @@ function walk$1(value, basePath, schema, snapshotFieldStateAt) {
|
|
|
1758
1782
|
}
|
|
1759
1783
|
|
|
1760
1784
|
const warnedNoScopeStores = paths.__DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
1785
|
+
function isErrorInputLike(value) {
|
|
1786
|
+
if (value instanceof Error) return true;
|
|
1787
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1788
|
+
const shape = value;
|
|
1789
|
+
return typeof shape.message === "string" && shape.message.length > 0 || Array.isArray(shape.path);
|
|
1790
|
+
}
|
|
1791
|
+
function deriveSubmitErrors(err, formKey) {
|
|
1792
|
+
if (Array.isArray(err) && err.length > 0 && err.every(isErrorInputLike)) {
|
|
1793
|
+
return {
|
|
1794
|
+
entries: err.map(
|
|
1795
|
+
(item) => paths.normalizeErrorInput(item, void 0, formKey, AttaformErrorCode.SubmitError)
|
|
1796
|
+
),
|
|
1797
|
+
messageless: false
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
if (isErrorInputLike(err)) {
|
|
1801
|
+
return {
|
|
1802
|
+
entries: [paths.normalizeErrorInput(err, void 0, formKey, AttaformErrorCode.SubmitError)],
|
|
1803
|
+
messageless: false
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
return {
|
|
1807
|
+
entries: [paths.normalizeErrorInput({}, void 0, formKey, AttaformErrorCode.SubmitError)],
|
|
1808
|
+
messageless: true
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1761
1811
|
function buildProcessForm(state, formInstanceId, options = {}) {
|
|
1762
1812
|
const invalidPolicy = options.onInvalidSubmit ?? "focus-first-error";
|
|
1763
1813
|
function validate(pathInput) {
|
|
@@ -1939,13 +1989,6 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1939
1989
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
1940
1990
|
applyInvalidSubmitPolicy(state, formInstanceId, invalidPolicy);
|
|
1941
1991
|
}
|
|
1942
|
-
if (onError !== void 0) {
|
|
1943
|
-
try {
|
|
1944
|
-
await onError(Array.from(state.userErrors.values()).flat());
|
|
1945
|
-
} catch (cause) {
|
|
1946
|
-
throw new paths.SubmitErrorHandlerError("User-provided onError threw", { cause });
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
1992
|
return;
|
|
1950
1993
|
}
|
|
1951
1994
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
@@ -1955,6 +1998,25 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1955
1998
|
} catch (err) {
|
|
1956
1999
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
1957
2000
|
state.submitError.value = paths.toError(err);
|
|
2001
|
+
if (!(err instanceof paths.SubmitErrorHandlerError)) {
|
|
2002
|
+
const { entries, messageless } = deriveSubmitErrors(err, state.formKey);
|
|
2003
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
2004
|
+
for (const entry of entries) {
|
|
2005
|
+
const { key } = paths.canonicalizePath(entry.path);
|
|
2006
|
+
const bucket = byPath.get(key);
|
|
2007
|
+
if (bucket === void 0) byPath.set(key, { segments: entry.path, entries: [entry] });
|
|
2008
|
+
else bucket.entries.push(entry);
|
|
2009
|
+
}
|
|
2010
|
+
for (const { segments, entries: bucket } of byPath.values()) {
|
|
2011
|
+
state.setUserErrorsForPath(segments, bucket);
|
|
2012
|
+
}
|
|
2013
|
+
applyInvalidSubmitPolicy(state, formInstanceId, invalidPolicy);
|
|
2014
|
+
if (paths.__DEV__ && messageless) {
|
|
2015
|
+
console.warn(
|
|
2016
|
+
"[attaform] handleSubmit callback threw a non-Error value; throw an Error or a ValidationError ({ message, path? }) so the failure surfaces with a usable message."
|
|
2017
|
+
);
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
1958
2020
|
}
|
|
1959
2021
|
} finally {
|
|
1960
2022
|
if (!validationSettled) {
|
|
@@ -2020,11 +2082,11 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
|
|
|
2020
2082
|
return;
|
|
2021
2083
|
}
|
|
2022
2084
|
if (policy === "focus-first-error") {
|
|
2023
|
-
target.element.focus();
|
|
2085
|
+
target.element.focus({ focusVisible: true });
|
|
2024
2086
|
return;
|
|
2025
2087
|
}
|
|
2026
2088
|
target.element.scrollIntoView();
|
|
2027
|
-
target.element.focus({ preventScroll: true });
|
|
2089
|
+
target.element.focus({ preventScroll: true, focusVisible: true });
|
|
2028
2090
|
}
|
|
2029
2091
|
|
|
2030
2092
|
const warnedRejections = paths.__DEV__ ? /* @__PURE__ */ new WeakMap() : null;
|
|
@@ -2816,6 +2878,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2816
2878
|
get errors() {
|
|
2817
2879
|
return rootBase().errors;
|
|
2818
2880
|
},
|
|
2881
|
+
get ownErrors() {
|
|
2882
|
+
return rootBase().ownErrors;
|
|
2883
|
+
},
|
|
2819
2884
|
get validating() {
|
|
2820
2885
|
return rootBase().validating;
|
|
2821
2886
|
},
|
|
@@ -2979,28 +3044,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2979
3044
|
return true;
|
|
2980
3045
|
}
|
|
2981
3046
|
const errorsProxy = buildErrorsProxy(state);
|
|
2982
|
-
function normalizeErrorInput(item, scope) {
|
|
2983
|
-
if (item instanceof Error) {
|
|
2984
|
-
return {
|
|
2985
|
-
message: item.message.length > 0 ? item.message : "Unknown error",
|
|
2986
|
-
path: scope !== void 0 ? [...scope] : [],
|
|
2987
|
-
formKey: state.formKey,
|
|
2988
|
-
code: AttaformErrorCode.UserError
|
|
2989
|
-
};
|
|
2990
|
-
}
|
|
2991
|
-
const entry = {
|
|
2992
|
-
message: typeof item.message === "string" && item.message.length > 0 ? item.message : "Unknown error",
|
|
2993
|
-
path: scope !== void 0 ? [...scope] : Array.isArray(item.path) ? [...item.path] : [],
|
|
2994
|
-
formKey: state.formKey,
|
|
2995
|
-
code: typeof item.code === "string" && item.code.length > 0 ? item.code : AttaformErrorCode.UserError
|
|
2996
|
-
};
|
|
2997
|
-
if (item.data !== void 0) entry.data = item.data;
|
|
2998
|
-
return entry;
|
|
2999
|
-
}
|
|
3000
|
-
function normalizeErrorInputs(input, scope) {
|
|
3001
|
-
const items = Array.isArray(input) ? input : [input];
|
|
3002
|
-
return items.map((item) => normalizeErrorInput(item, scope));
|
|
3003
|
-
}
|
|
3004
3047
|
function flattenUserErrors() {
|
|
3005
3048
|
const all = [];
|
|
3006
3049
|
for (const errs of state.userErrors.values()) all.push(...errs);
|
|
@@ -3012,12 +3055,17 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3012
3055
|
const { segments, key } = paths.canonicalizePath(arg1);
|
|
3013
3056
|
const input2 = arg2;
|
|
3014
3057
|
const resolved2 = typeof input2 === "function" ? input2((state.userErrors.get(key) ?? []).slice()) : input2;
|
|
3015
|
-
state.setUserErrorsForPath(
|
|
3058
|
+
state.setUserErrorsForPath(
|
|
3059
|
+
segments,
|
|
3060
|
+
paths.normalizeErrorInputs(resolved2, segments, state.formKey, AttaformErrorCode.UserError)
|
|
3061
|
+
);
|
|
3016
3062
|
return;
|
|
3017
3063
|
}
|
|
3018
3064
|
const input = arg1;
|
|
3019
3065
|
const resolved = typeof input === "function" ? input(flattenUserErrors()) : input;
|
|
3020
|
-
state.setAllUserErrors(
|
|
3066
|
+
state.setAllUserErrors(
|
|
3067
|
+
paths.normalizeErrorInputs(resolved, void 0, state.formKey, AttaformErrorCode.UserError)
|
|
3068
|
+
);
|
|
3021
3069
|
}
|
|
3022
3070
|
function clearErrors(path) {
|
|
3023
3071
|
if (path === void 0) {
|
|
@@ -3112,6 +3160,17 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3112
3160
|
// keep the explicit form-level computation for the gate.
|
|
3113
3161
|
valid,
|
|
3114
3162
|
errors: metaErrors,
|
|
3163
|
+
// The root `[]` bucket alone: form-level errors from a root
|
|
3164
|
+
// `.refine()` or a path-less `setErrors`, excluding every field error
|
|
3165
|
+
// that `errors` (the whole-form aggregate) rolls up. This is the
|
|
3166
|
+
// banner accessor. Mirrors `rootFieldState` rather than taking a
|
|
3167
|
+
// dedicated computed: `getFieldState([])` routes a container root
|
|
3168
|
+
// through `getErrorsForPath([])` and a primitive root through its own
|
|
3169
|
+
// bucket, and both equal the root bucket, so the root field state is
|
|
3170
|
+
// already the single source of truth.
|
|
3171
|
+
get ownErrors() {
|
|
3172
|
+
return rootFieldState.value.ownErrors;
|
|
3173
|
+
},
|
|
3115
3174
|
// Whole-form transforming mirrors the global `activeTransforms`
|
|
3116
3175
|
// counter ORed with any per-leaf transform in flight (the root
|
|
3117
3176
|
// rollup), exactly as `validating` composes its lifecycle and
|
|
@@ -3150,6 +3209,11 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3150
3209
|
get firstError() {
|
|
3151
3210
|
return rootFieldState.value.firstError;
|
|
3152
3211
|
},
|
|
3212
|
+
// `ownErrors[0]`: the form's first top-level error. Pair it with
|
|
3213
|
+
// `ownErrors` for the form-level banner.
|
|
3214
|
+
get firstOwnError() {
|
|
3215
|
+
return rootFieldState.value.firstOwnError;
|
|
3216
|
+
},
|
|
3153
3217
|
get path() {
|
|
3154
3218
|
return rootFieldState.value.path;
|
|
3155
3219
|
},
|
|
@@ -3229,7 +3293,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3229
3293
|
const focusFirstError = (options2) => {
|
|
3230
3294
|
const target = state.getFirstErrorElement(formInstanceId);
|
|
3231
3295
|
if (target === null) return false;
|
|
3232
|
-
target.element.focus(options2);
|
|
3296
|
+
target.element.focus({ focusVisible: true, ...options2 });
|
|
3233
3297
|
return true;
|
|
3234
3298
|
};
|
|
3235
3299
|
const scrollToFirstError = (options2) => {
|
|
@@ -5366,10 +5430,7 @@ function createFormStore(options) {
|
|
|
5366
5430
|
if (elementToFormInstance.get(entry.element) !== formInstanceId) continue;
|
|
5367
5431
|
if (!entry.element.isConnected) continue;
|
|
5368
5432
|
if (entry.element.offsetParent === null) continue;
|
|
5369
|
-
|
|
5370
|
-
const hasSchemaErr = (schemaErrors.get(key)?.length ?? 0) > 0;
|
|
5371
|
-
const hasUserErr = (userErrors.get(key)?.length ?? 0) > 0;
|
|
5372
|
-
if (!hasSchemaErr && !hasUserErr) continue;
|
|
5433
|
+
if (getErrorsForPath(entry.path).length === 0) continue;
|
|
5373
5434
|
return { path: entry.path, element: entry.element };
|
|
5374
5435
|
}
|
|
5375
5436
|
return null;
|
|
@@ -5949,7 +6010,7 @@ function resolveState(key, registry) {
|
|
|
5949
6010
|
if (key !== void 0) {
|
|
5950
6011
|
const stored = registry.forms.get(key);
|
|
5951
6012
|
if (stored === void 0) {
|
|
5952
|
-
warnMiss$1(`no form registered for key '${key}'`, registry.ssr);
|
|
6013
|
+
warnMiss$1(`no form registered for key '${key}'`, registry.ssr, registry.forms);
|
|
5953
6014
|
return null;
|
|
5954
6015
|
}
|
|
5955
6016
|
return stored;
|
|
@@ -5959,12 +6020,22 @@ function resolveState(key, registry) {
|
|
|
5959
6020
|
warnIfAmbientProviderHadDuplicates();
|
|
5960
6021
|
return ambient;
|
|
5961
6022
|
}
|
|
5962
|
-
function
|
|
6023
|
+
function availableKeysHint$1(forms) {
|
|
6024
|
+
const addressable = [...forms.keys()].filter((key) => !key.startsWith(RESERVED_KEY_PREFIX));
|
|
6025
|
+
if (addressable.length === 0) return void 0;
|
|
6026
|
+
return `Registered keys: ${addressable.map((key) => `'${key}'`).join(", ")}.`;
|
|
6027
|
+
}
|
|
6028
|
+
function warnMiss$1(detail, ssr, forms) {
|
|
5963
6029
|
if (!paths.__DEV__ || ssr) return;
|
|
5964
6030
|
const frame = captureUserCallSite();
|
|
5965
|
-
|
|
5966
|
-
|
|
6031
|
+
const parts = [`[attaform] injectForm: ${detail}. Returning null.`];
|
|
6032
|
+
const keys = availableKeysHint$1(forms);
|
|
6033
|
+
if (keys !== void 0) parts.push(keys);
|
|
6034
|
+
parts.push(
|
|
6035
|
+
`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.`
|
|
5967
6036
|
);
|
|
6037
|
+
if (frame !== void 0) parts.push(frame);
|
|
6038
|
+
console.warn(parts.join(" "));
|
|
5968
6039
|
}
|
|
5969
6040
|
function warnIfAmbientProviderHadDuplicates() {
|
|
5970
6041
|
if (!paths.__DEV__ || ambientProvideHistory === null) return;
|
|
@@ -6224,6 +6295,9 @@ function asStatusSource(form) {
|
|
|
6224
6295
|
function asSubmissionSource(form) {
|
|
6225
6296
|
return form;
|
|
6226
6297
|
}
|
|
6298
|
+
function asHandleSubmitSource(form) {
|
|
6299
|
+
return form;
|
|
6300
|
+
}
|
|
6227
6301
|
function useWizard(options) {
|
|
6228
6302
|
const rawSteps = Array.isArray(options.steps) ? options.steps : [];
|
|
6229
6303
|
if (rawSteps.length === 0 && paths.__DEV__) {
|
|
@@ -6318,6 +6392,7 @@ function useWizard(options) {
|
|
|
6318
6392
|
}
|
|
6319
6393
|
};
|
|
6320
6394
|
function resolveSlot(slot, index, ctx) {
|
|
6395
|
+
if (slot === void 0 || slot === null) return void 0;
|
|
6321
6396
|
if (typeof slot === "string") {
|
|
6322
6397
|
return getOrBuildNoop(slot);
|
|
6323
6398
|
}
|
|
@@ -6333,7 +6408,7 @@ function useWizard(options) {
|
|
|
6333
6408
|
return void 0;
|
|
6334
6409
|
}
|
|
6335
6410
|
function resolveSlotResult(result) {
|
|
6336
|
-
if (result === void 0) return void 0;
|
|
6411
|
+
if (result === void 0 || result === null) return void 0;
|
|
6337
6412
|
if (typeof result === "string") {
|
|
6338
6413
|
return getOrBuildNoop(result);
|
|
6339
6414
|
}
|
|
@@ -6401,6 +6476,50 @@ function useWizard(options) {
|
|
|
6401
6476
|
const first = list[0];
|
|
6402
6477
|
return first === void 0 ? void 0 : first.form;
|
|
6403
6478
|
});
|
|
6479
|
+
vue.watch(compiledSteps, (list, prevList) => {
|
|
6480
|
+
const key = activeKey.value;
|
|
6481
|
+
if (key === "") return;
|
|
6482
|
+
if (list.some((step) => step.key === key)) return;
|
|
6483
|
+
if (list.length === 0) {
|
|
6484
|
+
activeKey.value = "";
|
|
6485
|
+
return;
|
|
6486
|
+
}
|
|
6487
|
+
const oldIndex = prevList.findIndex((step) => step.key === key);
|
|
6488
|
+
const slid = list[oldIndex < 0 ? 0 : Math.min(oldIndex, list.length - 1)];
|
|
6489
|
+
if (slid !== void 0) activeKey.value = slid.key;
|
|
6490
|
+
});
|
|
6491
|
+
const activeFormFacade = new Proxy({}, {
|
|
6492
|
+
get(_target, prop) {
|
|
6493
|
+
const form = activeForm.value;
|
|
6494
|
+
if (form === void 0) return void 0;
|
|
6495
|
+
if (prop === "handleSubmit") {
|
|
6496
|
+
const lateBound = (onValid, onInvalid) => {
|
|
6497
|
+
return (event) => {
|
|
6498
|
+
const current = activeForm.value;
|
|
6499
|
+
if (current === void 0) return Promise.resolve();
|
|
6500
|
+
return asHandleSubmitSource(current).handleSubmit(onValid, onInvalid)(event);
|
|
6501
|
+
};
|
|
6502
|
+
};
|
|
6503
|
+
return lateBound;
|
|
6504
|
+
}
|
|
6505
|
+
return Reflect.get(form, prop, form);
|
|
6506
|
+
},
|
|
6507
|
+
has(_target, prop) {
|
|
6508
|
+
const form = activeForm.value;
|
|
6509
|
+
return form === void 0 ? false : Reflect.has(form, prop);
|
|
6510
|
+
},
|
|
6511
|
+
ownKeys(_target) {
|
|
6512
|
+
const form = activeForm.value;
|
|
6513
|
+
return form === void 0 ? [] : Reflect.ownKeys(form);
|
|
6514
|
+
},
|
|
6515
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
6516
|
+
const form = activeForm.value;
|
|
6517
|
+
if (form === void 0) return void 0;
|
|
6518
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(form, prop);
|
|
6519
|
+
if (descriptor === void 0) return void 0;
|
|
6520
|
+
return { ...descriptor, configurable: true };
|
|
6521
|
+
}
|
|
6522
|
+
});
|
|
6404
6523
|
const isFinalStep = vue.computed(() => {
|
|
6405
6524
|
const list = compiledSteps.value;
|
|
6406
6525
|
const idx = activeIndex.value;
|
|
@@ -6765,6 +6884,39 @@ function useWizard(options) {
|
|
|
6765
6884
|
const target = list[idx + 1];
|
|
6766
6885
|
moveTo(target.key);
|
|
6767
6886
|
}
|
|
6887
|
+
async function tryNext() {
|
|
6888
|
+
if (submitting.value) {
|
|
6889
|
+
if (paths.__DEV__) {
|
|
6890
|
+
console.warn(`[attaform] wizard.tryNext(): blocked while a submit is in flight.`);
|
|
6891
|
+
}
|
|
6892
|
+
return false;
|
|
6893
|
+
}
|
|
6894
|
+
const list = compiledSteps.value;
|
|
6895
|
+
if (list.length === 0) {
|
|
6896
|
+
if (paths.__DEV__) {
|
|
6897
|
+
console.warn(`[attaform] wizard.tryNext(): wizard has no compiled steps; no-op.`);
|
|
6898
|
+
}
|
|
6899
|
+
return false;
|
|
6900
|
+
}
|
|
6901
|
+
const idx = activeIndex.value;
|
|
6902
|
+
if (idx < 0 || idx >= list.length - 1) {
|
|
6903
|
+
if (paths.__DEV__) {
|
|
6904
|
+
console.warn(
|
|
6905
|
+
`[attaform] wizard.tryNext(): already on the final step ("${activeKey.value}"). Use wizard.handleSubmit() to submit.`
|
|
6906
|
+
);
|
|
6907
|
+
}
|
|
6908
|
+
return false;
|
|
6909
|
+
}
|
|
6910
|
+
const form = activeForm.value;
|
|
6911
|
+
if (form === void 0) return false;
|
|
6912
|
+
let advanced = false;
|
|
6913
|
+
await asHandleSubmitSource(form).handleSubmit(() => {
|
|
6914
|
+
const before = activeKey.value;
|
|
6915
|
+
next();
|
|
6916
|
+
advanced = activeKey.value !== before;
|
|
6917
|
+
})();
|
|
6918
|
+
return advanced;
|
|
6919
|
+
}
|
|
6768
6920
|
function back() {
|
|
6769
6921
|
if (submitting.value) {
|
|
6770
6922
|
if (paths.__DEV__) {
|
|
@@ -6901,20 +7053,13 @@ function useWizard(options) {
|
|
|
6901
7053
|
const final = isFinalStep.value;
|
|
6902
7054
|
const list = compiledSteps.value;
|
|
6903
7055
|
const results = /* @__PURE__ */ new Map();
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
);
|
|
6912
|
-
} else {
|
|
6913
|
-
const active = activeForm.value;
|
|
6914
|
-
registry.forms.get(active.key)?.clearUserErrors();
|
|
6915
|
-
const result = await processOne(active);
|
|
6916
|
-
results.set(active.key, result);
|
|
6917
|
-
}
|
|
7056
|
+
await Promise.all(
|
|
7057
|
+
list.map(async (step) => {
|
|
7058
|
+
registry.forms.get(step.key)?.clearUserErrors();
|
|
7059
|
+
const result = await processOne(step.form);
|
|
7060
|
+
results.set(step.key, result);
|
|
7061
|
+
})
|
|
7062
|
+
);
|
|
6918
7063
|
for (const key of results.keys()) {
|
|
6919
7064
|
const store = registry.forms.get(key);
|
|
6920
7065
|
if (store !== void 0) {
|
|
@@ -6949,14 +7094,7 @@ function useWizard(options) {
|
|
|
6949
7094
|
}
|
|
6950
7095
|
return;
|
|
6951
7096
|
}
|
|
6952
|
-
|
|
6953
|
-
done.value = true;
|
|
6954
|
-
} else {
|
|
6955
|
-
recordDeparture(currentKey);
|
|
6956
|
-
const idx = activeIndex.value;
|
|
6957
|
-
const target = list[idx + 1];
|
|
6958
|
-
if (target !== void 0) moveTo(target.key);
|
|
6959
|
-
}
|
|
7097
|
+
done.value = true;
|
|
6960
7098
|
} else {
|
|
6961
7099
|
await focusFirstWizardError(errors);
|
|
6962
7100
|
if (onError !== void 0) {
|
|
@@ -7006,13 +7144,14 @@ function useWizard(options) {
|
|
|
7006
7144
|
next,
|
|
7007
7145
|
back,
|
|
7008
7146
|
goTo,
|
|
7147
|
+
tryNext,
|
|
7009
7148
|
handleSubmit,
|
|
7010
7149
|
reset,
|
|
7011
7150
|
get currentStep() {
|
|
7012
7151
|
return currentStep.value;
|
|
7013
7152
|
},
|
|
7014
7153
|
get activeForm() {
|
|
7015
|
-
return activeForm.value;
|
|
7154
|
+
return activeForm.value === void 0 ? void 0 : activeFormFacade;
|
|
7016
7155
|
},
|
|
7017
7156
|
get activeIndex() {
|
|
7018
7157
|
return activeIndex.value;
|
|
@@ -7144,6 +7283,9 @@ function warnMiss(detail, ssr, hint) {
|
|
|
7144
7283
|
const frame = captureUserCallSite();
|
|
7145
7284
|
const parts = [`[attaform] injectWizard: ${detail}. Returning null.`];
|
|
7146
7285
|
if (hint !== void 0) parts.push(hint);
|
|
7286
|
+
parts.push(
|
|
7287
|
+
`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.`
|
|
7288
|
+
);
|
|
7147
7289
|
if (frame !== void 0) parts.push(frame);
|
|
7148
7290
|
console.warn(parts.join(" "));
|
|
7149
7291
|
}
|
|
@@ -7186,4 +7328,4 @@ exports.unset = unset;
|
|
|
7186
7328
|
exports.useAbstractForm = useAbstractForm;
|
|
7187
7329
|
exports.useRegister = useRegister;
|
|
7188
7330
|
exports.useWizard = useWizard;
|
|
7189
|
-
//# sourceMappingURL=attaform.
|
|
7331
|
+
//# sourceMappingURL=attaform.Du9RZp8m.cjs.map
|