attaform 0.18.1 → 0.19.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/README.md +3 -0
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/indexeddb.cjs +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/session-storage.cjs +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +68 -75
- package/dist/index.d.mts +68 -75
- package/dist/index.d.ts +68 -75
- package/dist/index.mjs +5 -5
- 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.DsC3rZHG.mjs → attaform.BTi-PsHr.mjs} +544 -134
- package/dist/shared/attaform.BTi-PsHr.mjs.map +1 -0
- package/dist/shared/{attaform.iTqxvl-P.d.mts → attaform.BTpuvGec.d.ts} +46 -13
- package/dist/shared/{attaform.BqK_L4gK.cjs → attaform.BqEfHpVB.cjs} +119 -1
- package/dist/shared/attaform.BqEfHpVB.cjs.map +1 -0
- package/dist/shared/{attaform.DK9aj0N8.d.ts → attaform.BtBmfLQN.d.mts} +46 -13
- package/dist/shared/{attaform.Dj9mwbaV.d.mts → attaform.C0uGZQ4M.d.cts} +365 -86
- package/dist/shared/{attaform.Dj9mwbaV.d.ts → attaform.C0uGZQ4M.d.mts} +365 -86
- package/dist/shared/{attaform.Dj9mwbaV.d.cts → attaform.C0uGZQ4M.d.ts} +365 -86
- package/dist/shared/{attaform.II89Pcf4.cjs → attaform.C1msmO2v.cjs} +544 -134
- package/dist/shared/attaform.C1msmO2v.cjs.map +1 -0
- package/dist/shared/{attaform.tts_OM7j.d.cts → attaform.CBjmobqk.d.cts} +1 -1
- package/dist/shared/{attaform.2b7M2mww.d.mts → attaform.CJ-e9gYI.d.ts} +1 -1
- package/dist/shared/{attaform.tsNFcEW7.d.ts → attaform.CRNA0vrd.d.mts} +1 -1
- package/dist/shared/{attaform.BDdFdjeX.mjs → attaform.Cghpuav8.mjs} +3 -3
- package/dist/shared/{attaform.BDdFdjeX.mjs.map → attaform.Cghpuav8.mjs.map} +1 -1
- package/dist/shared/{attaform.CtNUB9nf.mjs → attaform.CiMqJHDm.mjs} +3 -3
- package/dist/shared/{attaform.CtNUB9nf.mjs.map → attaform.CiMqJHDm.mjs.map} +1 -1
- package/dist/shared/{attaform.5UhpSVFI.cjs → attaform.CoxJ8Qm8.cjs} +2 -2
- package/dist/shared/{attaform.5UhpSVFI.cjs.map → attaform.CoxJ8Qm8.cjs.map} +1 -1
- package/dist/shared/{attaform.Xhg0AYNa.mjs → attaform.CrpjyXdO.mjs} +120 -2
- package/dist/shared/attaform.CrpjyXdO.mjs.map +1 -0
- package/dist/shared/{attaform.DF8wo-ry.d.ts → attaform.D4I63aBV.d.ts} +1 -1
- package/dist/shared/{attaform.DVLB6CAn.d.mts → attaform.DXYHL99q.d.mts} +1 -1
- package/dist/shared/{attaform.Dlk1jMuv.cjs → attaform.JBx8cfMA.cjs} +3 -3
- package/dist/shared/{attaform.Dlk1jMuv.cjs.map → attaform.JBx8cfMA.cjs.map} +1 -1
- package/dist/shared/{attaform.DUHru0OF.cjs → attaform.OznWyOPy.cjs} +3 -3
- package/dist/shared/{attaform.DUHru0OF.cjs.map → attaform.OznWyOPy.cjs.map} +1 -1
- package/dist/shared/{attaform.M33WKVV4.d.cts → attaform.QvygsFGh.d.cts} +1 -1
- package/dist/shared/{attaform.Xt0A3QUd.mjs → attaform.a3uBo-gw.mjs} +3 -3
- package/dist/shared/{attaform.Xt0A3QUd.mjs.map → attaform.a3uBo-gw.mjs.map} +1 -1
- package/dist/shared/{attaform.DoSuaKMd.d.cts → attaform.ePUcKxId.d.cts} +46 -13
- package/dist/zod-v3.cjs +3 -3
- package/dist/zod-v3.d.cts +4 -4
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.d.ts +4 -4
- package/dist/zod-v3.mjs +3 -3
- package/dist/zod-v4.cjs +3 -3
- package/dist/zod-v4.d.cts +4 -4
- package/dist/zod-v4.d.mts +4 -4
- package/dist/zod-v4.d.ts +4 -4
- package/dist/zod-v4.mjs +3 -3
- package/dist/zod.cjs +4 -4
- package/dist/zod.d.cts +6 -6
- package/dist/zod.d.mts +6 -6
- package/dist/zod.d.ts +6 -6
- package/dist/zod.mjs +5 -5
- package/package.json +5 -5
- package/dist/shared/attaform.BqK_L4gK.cjs.map +0 -1
- package/dist/shared/attaform.DsC3rZHG.mjs.map +0 -1
- package/dist/shared/attaform.II89Pcf4.cjs.map +0 -1
- package/dist/shared/attaform.Xhg0AYNa.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const vue = require('vue');
|
|
4
|
-
const paths = require('./attaform.
|
|
4
|
+
const paths = require('./attaform.BqEfHpVB.cjs');
|
|
5
5
|
|
|
6
6
|
const NOT_FOUND = Symbol("NOT_FOUND");
|
|
7
7
|
function descendStep(value, segment) {
|
|
@@ -436,6 +436,74 @@ function structuralSnapshot(value) {
|
|
|
436
436
|
return out;
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
+
const defaultDisplayState = (field, formMeta) => {
|
|
440
|
+
const gateOpen = formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
|
|
441
|
+
if (!gateOpen) return "idle";
|
|
442
|
+
if (field.validating === true) return "pending";
|
|
443
|
+
const hasOwnError = field.errors.some(
|
|
444
|
+
(e) => e.path.length === field.path.length && e.path.every((s, i) => s === field.path[i])
|
|
445
|
+
);
|
|
446
|
+
if (hasOwnError) return "error";
|
|
447
|
+
if (field.valid === true && field.blank !== true && field.dirty === true) return "success";
|
|
448
|
+
return "idle";
|
|
449
|
+
};
|
|
450
|
+
function resolveGetDisplayState(config) {
|
|
451
|
+
return config ?? defaultDisplayState;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS = 0;
|
|
455
|
+
const DEFAULT_PERSISTENCE_DEBOUNCE_MS = 300;
|
|
456
|
+
const DEFAULT_HISTORY_MAX_SNAPSHOTS = 128;
|
|
457
|
+
const PERSISTENCE_KEY_PREFIX = "attaform:";
|
|
458
|
+
const RESERVED_KEY_PREFIX = "__atta:";
|
|
459
|
+
const ANONYMOUS_FORM_KEY_PREFIX = `${RESERVED_KEY_PREFIX}anon:`;
|
|
460
|
+
const ANONYMOUS_WIZARD_KEY_PREFIX = `${RESERVED_KEY_PREFIX}anon-wizard:`;
|
|
461
|
+
const DEFAULT_MAX_RECURSION_DEPTH = 64;
|
|
462
|
+
function normalizeNumericOption(config) {
|
|
463
|
+
const { value, source, allowInfinity, min, defaultValue } = config;
|
|
464
|
+
if (allowInfinity && value === Infinity) return Infinity;
|
|
465
|
+
if (typeof value !== "number" || Number.isNaN(value) || value === Infinity || value === -Infinity) {
|
|
466
|
+
if (paths.__DEV__) {
|
|
467
|
+
const acceptedDescription = allowInfinity ? "a non-negative integer or Infinity" : "a non-negative finite integer";
|
|
468
|
+
console.warn(
|
|
469
|
+
`[attaform] ${source} must be ${acceptedDescription}; got ${String(value)}. Falling back to ${String(defaultValue)}.`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
return defaultValue;
|
|
473
|
+
}
|
|
474
|
+
return Math.max(min, Math.floor(value));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function hashStableString(input, seed = 0) {
|
|
478
|
+
let h1 = 3735928559 ^ seed;
|
|
479
|
+
let h2 = 1103547991 ^ seed;
|
|
480
|
+
for (let i = 0; i < input.length; i++) {
|
|
481
|
+
const ch = input.charCodeAt(i);
|
|
482
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
483
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
484
|
+
}
|
|
485
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
486
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
487
|
+
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36).padStart(11, "0");
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const ANON_STEM = "atta";
|
|
491
|
+
function readableFormKeyStem(formKey) {
|
|
492
|
+
if (formKey === "" || formKey.startsWith(ANONYMOUS_FORM_KEY_PREFIX)) return ANON_STEM;
|
|
493
|
+
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
494
|
+
return sanitized === "" ? ANON_STEM : sanitized;
|
|
495
|
+
}
|
|
496
|
+
function fieldIdToken(formInstanceId, pathKey) {
|
|
497
|
+
return hashStableString(`${formInstanceId}:${pathKey}`).slice(-7);
|
|
498
|
+
}
|
|
499
|
+
function computeFieldIdentity(formInstanceId, formKey, pathKey) {
|
|
500
|
+
const id = `${readableFormKeyStem(formKey)}-${fieldIdToken(formInstanceId, pathKey)}`;
|
|
501
|
+
return {
|
|
502
|
+
id,
|
|
503
|
+
aria: Object.freeze({ errorId: `${id}-error`, descriptionId: `${id}-description` })
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
|
|
439
507
|
const EMPTY_RESOLVED_FIELD_META = Object.freeze({
|
|
440
508
|
label: "",
|
|
441
509
|
description: void 0,
|
|
@@ -469,21 +537,21 @@ function isUnderStubAncestor(state, segments) {
|
|
|
469
537
|
}
|
|
470
538
|
return false;
|
|
471
539
|
}
|
|
472
|
-
function buildFieldStateAccessor(state, getFormMetaBase, options) {
|
|
540
|
+
function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, options) {
|
|
473
541
|
const cache = /* @__PURE__ */ new Map();
|
|
474
|
-
const predicate = options?.
|
|
542
|
+
const predicate = options?.getDisplayState;
|
|
475
543
|
return function getFieldState(pathInput) {
|
|
476
544
|
const { segments, key } = paths.canonicalizePath(pathInput);
|
|
477
545
|
const cached = cache.get(key);
|
|
478
546
|
if (cached !== void 0) return cached;
|
|
479
547
|
const c = vue.computed(
|
|
480
|
-
() => state.schema.isLeafAtPath(segments) ? buildLeafFieldState(state, segments, key, getFormMetaBase, predicate) : buildContainerFieldState(state, segments, key, getFormMetaBase, predicate)
|
|
548
|
+
() => state.schema.isLeafAtPath(segments) ? buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase, predicate) : buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase, predicate)
|
|
481
549
|
);
|
|
482
550
|
cache.set(key, c);
|
|
483
551
|
return c;
|
|
484
552
|
};
|
|
485
553
|
}
|
|
486
|
-
function buildLeafFieldStateBase(state, segments, key) {
|
|
554
|
+
function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
487
555
|
const record = state.fields.get(key);
|
|
488
556
|
const value = state.getValueAtPath(segments);
|
|
489
557
|
const original = state.originals.get(key)?.value;
|
|
@@ -513,6 +581,8 @@ function buildLeafFieldStateBase(state, segments, key) {
|
|
|
513
581
|
focused: record?.focused ?? null,
|
|
514
582
|
blurred: record?.blurred ?? null,
|
|
515
583
|
touched: record?.touched ?? false,
|
|
584
|
+
interacted: record?.interacted ?? false,
|
|
585
|
+
blurredAfterInteraction: record?.blurredAfterInteraction ?? false,
|
|
516
586
|
connected: record?.connected ?? false,
|
|
517
587
|
element: firstElement,
|
|
518
588
|
elements: elementsArr,
|
|
@@ -521,6 +591,8 @@ function buildLeafFieldStateBase(state, segments, key) {
|
|
|
521
591
|
validating,
|
|
522
592
|
valid,
|
|
523
593
|
path: segments,
|
|
594
|
+
...computeFieldIdentity(formInstanceId, state.formKey, key),
|
|
595
|
+
key: state.arrayElementKey(segments),
|
|
524
596
|
blank: state.blankPaths.has(key),
|
|
525
597
|
label,
|
|
526
598
|
description: resolved.description,
|
|
@@ -528,11 +600,11 @@ function buildLeafFieldStateBase(state, segments, key) {
|
|
|
528
600
|
meta: resolved.meta
|
|
529
601
|
};
|
|
530
602
|
}
|
|
531
|
-
function buildLeafFieldState(state, segments, key, getFormMetaBase,
|
|
532
|
-
const base = buildLeafFieldStateBase(state, segments, key);
|
|
533
|
-
return decorateWithDerivedProps(base, state, getFormMetaBase,
|
|
603
|
+
function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase, getDisplayState) {
|
|
604
|
+
const base = buildLeafFieldStateBase(state, segments, key, formInstanceId);
|
|
605
|
+
return decorateWithDerivedProps(base, state, getFormMetaBase, getDisplayState);
|
|
534
606
|
}
|
|
535
|
-
function buildContainerFieldStateBase(state, segments,
|
|
607
|
+
function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
536
608
|
const formValue = state.form.value;
|
|
537
609
|
const value = state.getValueAtPath(segments);
|
|
538
610
|
const original = state.originals.get(paths.canonicalizePath(segments).key)?.value;
|
|
@@ -542,6 +614,8 @@ function buildContainerFieldStateBase(state, segments, _key) {
|
|
|
542
614
|
let focused = false;
|
|
543
615
|
let blurred = false;
|
|
544
616
|
let touched = false;
|
|
617
|
+
let interacted = false;
|
|
618
|
+
let blurredAfterInteraction = false;
|
|
545
619
|
let connected = false;
|
|
546
620
|
let validating = false;
|
|
547
621
|
let updatedAt = null;
|
|
@@ -560,6 +634,8 @@ function buildContainerFieldStateBase(state, segments, _key) {
|
|
|
560
634
|
if (leafRecord?.focused === true) focused = true;
|
|
561
635
|
if (leafRecord?.blurred === true) blurred = true;
|
|
562
636
|
if (leafRecord?.touched === true) touched = true;
|
|
637
|
+
if (leafRecord?.interacted === true) interacted = true;
|
|
638
|
+
if (leafRecord?.blurredAfterInteraction === true) blurredAfterInteraction = true;
|
|
563
639
|
if (leafRecord?.connected === true) connected = true;
|
|
564
640
|
if ((state.fieldValidationCounts.get(leafKey) ?? 0) > 0) validating = true;
|
|
565
641
|
if (state.pathHasAsyncValidation(entry.segments)) asyncPending = true;
|
|
@@ -568,6 +644,10 @@ function buildContainerFieldStateBase(state, segments, _key) {
|
|
|
568
644
|
if (updatedAt === null || ts > updatedAt) updatedAt = ts;
|
|
569
645
|
}
|
|
570
646
|
}
|
|
647
|
+
if (!dirty && state.hasStructuralChangeUnder(segments)) {
|
|
648
|
+
pristine = false;
|
|
649
|
+
dirty = true;
|
|
650
|
+
}
|
|
571
651
|
const errors = aggregateErrorsAt(state, segments);
|
|
572
652
|
if (!asyncPending && state.pathHasAsyncValidation(segments)) asyncPending = true;
|
|
573
653
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
@@ -583,6 +663,8 @@ function buildContainerFieldStateBase(state, segments, _key) {
|
|
|
583
663
|
focused,
|
|
584
664
|
blurred,
|
|
585
665
|
touched,
|
|
666
|
+
interacted,
|
|
667
|
+
blurredAfterInteraction,
|
|
586
668
|
connected,
|
|
587
669
|
element: null,
|
|
588
670
|
elements: EMPTY_ELEMENTS,
|
|
@@ -591,6 +673,8 @@ function buildContainerFieldStateBase(state, segments, _key) {
|
|
|
591
673
|
validating,
|
|
592
674
|
valid,
|
|
593
675
|
path: segments,
|
|
676
|
+
...computeFieldIdentity(formInstanceId, state.formKey, key),
|
|
677
|
+
key: state.arrayElementKey(segments),
|
|
594
678
|
blank,
|
|
595
679
|
label,
|
|
596
680
|
description: resolved.description,
|
|
@@ -598,15 +682,29 @@ function buildContainerFieldStateBase(state, segments, _key) {
|
|
|
598
682
|
meta: resolved.meta
|
|
599
683
|
};
|
|
600
684
|
}
|
|
601
|
-
function buildContainerFieldState(state, segments, key, getFormMetaBase,
|
|
602
|
-
const base = buildContainerFieldStateBase(state, segments);
|
|
603
|
-
return decorateWithDerivedProps(base, state, getFormMetaBase,
|
|
685
|
+
function buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase, getDisplayState) {
|
|
686
|
+
const base = buildContainerFieldStateBase(state, segments, key, formInstanceId);
|
|
687
|
+
return decorateWithDerivedProps(base, state, getFormMetaBase, getDisplayState);
|
|
604
688
|
}
|
|
605
|
-
function decorateWithDerivedProps(base, state, getFormMetaBase,
|
|
689
|
+
function decorateWithDerivedProps(base, state, getFormMetaBase, getDisplayState) {
|
|
606
690
|
const firstError = base.errors[0];
|
|
607
|
-
const predicate =
|
|
608
|
-
const
|
|
609
|
-
|
|
691
|
+
const predicate = getDisplayState ?? state.getDisplayState;
|
|
692
|
+
const formMeta = getFormMetaBase();
|
|
693
|
+
let displayState;
|
|
694
|
+
try {
|
|
695
|
+
displayState = predicate(base, formMeta);
|
|
696
|
+
} catch {
|
|
697
|
+
displayState = defaultDisplayState(base, formMeta);
|
|
698
|
+
}
|
|
699
|
+
return {
|
|
700
|
+
...base,
|
|
701
|
+
displayState,
|
|
702
|
+
showErrors: displayState === "error",
|
|
703
|
+
showPending: displayState === "pending",
|
|
704
|
+
showSuccess: displayState === "success",
|
|
705
|
+
showIdle: displayState === "idle",
|
|
706
|
+
firstError
|
|
707
|
+
};
|
|
610
708
|
}
|
|
611
709
|
function aggregateErrorsAt(state, prefix) {
|
|
612
710
|
const formValue = state.form.value;
|
|
@@ -988,19 +1086,19 @@ function buildFieldArrayApi(state) {
|
|
|
988
1086
|
prepend(path, value) {
|
|
989
1087
|
const next = readArray(path);
|
|
990
1088
|
next.unshift(value);
|
|
991
|
-
return writeArray(path, next, { kind: "
|
|
1089
|
+
return writeArray(path, next, { kind: "insert", index: 0 });
|
|
992
1090
|
},
|
|
993
1091
|
insert(path, index, value) {
|
|
994
1092
|
const next = readArray(path);
|
|
995
1093
|
next.splice(index, 0, value);
|
|
996
1094
|
const clampedIndex = Math.max(0, Math.min(index, next.length));
|
|
997
|
-
return writeArray(path, next, { kind: "
|
|
1095
|
+
return writeArray(path, next, { kind: "insert", index: clampedIndex });
|
|
998
1096
|
},
|
|
999
1097
|
remove(path, index) {
|
|
1000
1098
|
const next = readArray(path);
|
|
1001
1099
|
if (index < 0 || index >= next.length) return false;
|
|
1002
1100
|
next.splice(index, 1);
|
|
1003
|
-
return writeArray(path, next, { kind: "
|
|
1101
|
+
return writeArray(path, next, { kind: "remove", index });
|
|
1004
1102
|
},
|
|
1005
1103
|
swap(path, a, b) {
|
|
1006
1104
|
const next = readArray(path);
|
|
@@ -1018,11 +1116,7 @@ function buildFieldArrayApi(state) {
|
|
|
1018
1116
|
const [item] = next.splice(from, 1);
|
|
1019
1117
|
const clampedTo = Math.max(0, Math.min(to, next.length));
|
|
1020
1118
|
next.splice(clampedTo, 0, item);
|
|
1021
|
-
return writeArray(path, next, {
|
|
1022
|
-
kind: "shift-range",
|
|
1023
|
-
fromIndex: Math.min(from, clampedTo),
|
|
1024
|
-
toIndex: Math.max(from, clampedTo)
|
|
1025
|
-
});
|
|
1119
|
+
return writeArray(path, next, { kind: "move", from, to: clampedTo });
|
|
1026
1120
|
},
|
|
1027
1121
|
replace(path, index, value) {
|
|
1028
1122
|
const next = readArray(path);
|
|
@@ -1041,6 +1135,8 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1041
1135
|
"focused",
|
|
1042
1136
|
"blurred",
|
|
1043
1137
|
"touched",
|
|
1138
|
+
"interacted",
|
|
1139
|
+
"blurredAfterInteraction",
|
|
1044
1140
|
"connected",
|
|
1045
1141
|
"element",
|
|
1046
1142
|
"elements",
|
|
@@ -1048,20 +1144,28 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1048
1144
|
"errors",
|
|
1049
1145
|
"validating",
|
|
1050
1146
|
"valid",
|
|
1147
|
+
"displayState",
|
|
1051
1148
|
"showErrors",
|
|
1149
|
+
"showPending",
|
|
1150
|
+
"showSuccess",
|
|
1151
|
+
"showIdle",
|
|
1052
1152
|
"firstError",
|
|
1053
1153
|
"path",
|
|
1154
|
+
"id",
|
|
1155
|
+
"aria",
|
|
1156
|
+
"key",
|
|
1054
1157
|
"blank",
|
|
1055
1158
|
"label",
|
|
1056
1159
|
"description",
|
|
1057
1160
|
"placeholder",
|
|
1058
1161
|
"meta"
|
|
1059
1162
|
]);
|
|
1060
|
-
function buildFieldStateProxy(state, getFormMetaBase, options) {
|
|
1163
|
+
function buildFieldStateProxy(state, formInstanceId, getFormMetaBase, options) {
|
|
1061
1164
|
const getFieldStateAt = buildFieldStateAccessor(
|
|
1062
1165
|
state,
|
|
1166
|
+
formInstanceId,
|
|
1063
1167
|
getFormMetaBase,
|
|
1064
|
-
options?.
|
|
1168
|
+
options?.getDisplayState !== void 0 ? { getDisplayState: options.getDisplayState } : void 0
|
|
1065
1169
|
);
|
|
1066
1170
|
const snapshotFieldStateAt = (path) => {
|
|
1067
1171
|
const view = getFieldStateAt(path).value;
|
|
@@ -1168,29 +1272,6 @@ function walk$2(value, basePath, schema, snapshotFieldStateAt) {
|
|
|
1168
1272
|
return result;
|
|
1169
1273
|
}
|
|
1170
1274
|
|
|
1171
|
-
const DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS = 0;
|
|
1172
|
-
const DEFAULT_PERSISTENCE_DEBOUNCE_MS = 300;
|
|
1173
|
-
const DEFAULT_HISTORY_MAX_SNAPSHOTS = 128;
|
|
1174
|
-
const PERSISTENCE_KEY_PREFIX = "attaform:";
|
|
1175
|
-
const RESERVED_KEY_PREFIX = "__atta:";
|
|
1176
|
-
const ANONYMOUS_FORM_KEY_PREFIX = `${RESERVED_KEY_PREFIX}anon:`;
|
|
1177
|
-
const ANONYMOUS_WIZARD_KEY_PREFIX = `${RESERVED_KEY_PREFIX}anon-wizard:`;
|
|
1178
|
-
const DEFAULT_MAX_RECURSION_DEPTH = 64;
|
|
1179
|
-
function normalizeNumericOption(config) {
|
|
1180
|
-
const { value, source, allowInfinity, min, defaultValue } = config;
|
|
1181
|
-
if (allowInfinity && value === Infinity) return Infinity;
|
|
1182
|
-
if (typeof value !== "number" || Number.isNaN(value) || value === Infinity || value === -Infinity) {
|
|
1183
|
-
if (paths.__DEV__) {
|
|
1184
|
-
const acceptedDescription = allowInfinity ? "a non-negative integer or Infinity" : "a non-negative finite integer";
|
|
1185
|
-
console.warn(
|
|
1186
|
-
`[attaform] ${source} must be ${acceptedDescription}; got ${String(value)}. Falling back to ${String(defaultValue)}.`
|
|
1187
|
-
);
|
|
1188
|
-
}
|
|
1189
|
-
return defaultValue;
|
|
1190
|
-
}
|
|
1191
|
-
return Math.max(min, Math.floor(value));
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
1275
|
const PERSISTENCE_MODULE_KEY = "persistence";
|
|
1195
1276
|
async function getStorageAdapter(storage) {
|
|
1196
1277
|
if (typeof storage === "object") return storage;
|
|
@@ -1996,6 +2077,8 @@ function detachFocusListeners(element) {
|
|
|
1996
2077
|
function buildRegister(state, formInstanceId, instanceConfig) {
|
|
1997
2078
|
const coerceIndex = instanceConfig?.coerce !== void 0 ? resolveCoercionIndex(instanceConfig.coerce) : state.coerceIndex;
|
|
1998
2079
|
const instanceMeta = instanceConfig?.instanceMeta;
|
|
2080
|
+
const formAutoAria = instanceConfig?.autoAria ?? true;
|
|
2081
|
+
const getDisplayStateAt = instanceConfig?.getDisplayStateAt;
|
|
1999
2082
|
const withInstanceMeta = (meta) => {
|
|
2000
2083
|
if (instanceMeta === void 0) return meta;
|
|
2001
2084
|
return meta === void 0 ? { instance: instanceMeta } : { ...meta, instance: instanceMeta };
|
|
@@ -2050,6 +2133,10 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2050
2133
|
callSite: paths.captureUserCallSite()
|
|
2051
2134
|
});
|
|
2052
2135
|
}
|
|
2136
|
+
const { aria } = computeFieldIdentity(formInstanceId, state.formKey, pathKey);
|
|
2137
|
+
const isRequired = state.schema.isRequiredAtPath(segments);
|
|
2138
|
+
const ariaEnabled = options?.autoAria ?? formAutoAria;
|
|
2139
|
+
const ariaDisplayState = getDisplayStateAt !== void 0 ? vue.computed(() => getDisplayStateAt(segments)) : void 0;
|
|
2053
2140
|
const internalRv = {
|
|
2054
2141
|
innerRef,
|
|
2055
2142
|
displayValue,
|
|
@@ -2064,6 +2151,9 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2064
2151
|
})
|
|
2065
2152
|
);
|
|
2066
2153
|
},
|
|
2154
|
+
markInteracted: () => {
|
|
2155
|
+
state.markInteracted(segments);
|
|
2156
|
+
},
|
|
2067
2157
|
registerElement: (element) => {
|
|
2068
2158
|
if (!INTERACTIVE_TAG_NAMES.has(element.tagName)) return;
|
|
2069
2159
|
const added = state.registerElement(segments, element, formInstanceId);
|
|
@@ -2108,7 +2198,12 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2108
2198
|
coerce,
|
|
2109
2199
|
...coerceElement !== void 0 ? { coerceElement } : {},
|
|
2110
2200
|
acceptsUndefined,
|
|
2111
|
-
acceptsString
|
|
2201
|
+
acceptsString,
|
|
2202
|
+
// --- Aria (internal; consumed by the directive) ---
|
|
2203
|
+
aria,
|
|
2204
|
+
isRequired,
|
|
2205
|
+
ariaEnabled,
|
|
2206
|
+
...ariaDisplayState !== void 0 ? { ariaDisplayState } : {}
|
|
2112
2207
|
};
|
|
2113
2208
|
return vue.shallowReadonly(internalRv);
|
|
2114
2209
|
};
|
|
@@ -2352,15 +2447,34 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2352
2447
|
if (instanceMeta === void 0) return meta;
|
|
2353
2448
|
return meta === void 0 ? { instance: instanceMeta } : { ...meta, instance: instanceMeta };
|
|
2354
2449
|
};
|
|
2355
|
-
const
|
|
2356
|
-
|
|
2357
|
-
|
|
2450
|
+
const getFormMetaBase = () => {
|
|
2451
|
+
const rootBase = buildContainerFieldStateBase(state, paths.ROOT_PATH, paths.ROOT_PATH_KEY, formInstanceId);
|
|
2452
|
+
return {
|
|
2453
|
+
...rootBase,
|
|
2454
|
+
submitting: state.submitting.value,
|
|
2455
|
+
submissionAttempts: state.submissionAttempts.value,
|
|
2456
|
+
departAttempts: state.departAttempts.value,
|
|
2457
|
+
submitError: state.submitError.value,
|
|
2458
|
+
errorCount: rootBase.errors.length,
|
|
2459
|
+
submitted: state.submitted.value,
|
|
2460
|
+
instanceId: formInstanceId
|
|
2461
|
+
};
|
|
2358
2462
|
};
|
|
2359
|
-
const
|
|
2463
|
+
const fieldStateAccessorOptions = options.getDisplayState !== void 0 ? { getDisplayState: options.getDisplayState } : void 0;
|
|
2464
|
+
const getRootFieldStateAt = buildFieldStateAccessor(
|
|
2360
2465
|
state,
|
|
2361
2466
|
formInstanceId,
|
|
2362
|
-
|
|
2467
|
+
getFormMetaBase,
|
|
2468
|
+
fieldStateAccessorOptions
|
|
2363
2469
|
);
|
|
2470
|
+
const getDisplayStateAt = (segments) => getRootFieldStateAt(segments).value.displayState;
|
|
2471
|
+
const registerConfig = {
|
|
2472
|
+
...instanceMeta !== void 0 ? { instanceMeta } : {},
|
|
2473
|
+
...options.coerce !== void 0 ? { coerce: options.coerce } : {},
|
|
2474
|
+
...options.autoAria !== void 0 ? { autoAria: options.autoAria } : {},
|
|
2475
|
+
getDisplayStateAt
|
|
2476
|
+
};
|
|
2477
|
+
const register = buildRegister(state, formInstanceId, registerConfig);
|
|
2364
2478
|
const processOptions = options.onInvalidSubmit !== void 0 ? { onInvalidSubmit: options.onInvalidSubmit } : {};
|
|
2365
2479
|
const defaultInvalidSubmitPolicy = options.onInvalidSubmit ?? "focus-first-error";
|
|
2366
2480
|
const {
|
|
@@ -2532,25 +2646,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2532
2646
|
const metaErrors = vue.computed(
|
|
2533
2647
|
() => aggregateErrorsAt(state, [])
|
|
2534
2648
|
);
|
|
2535
|
-
const getFormMetaBase = () => {
|
|
2536
|
-
const rootBase = buildContainerFieldStateBase(state, paths.ROOT_PATH);
|
|
2537
|
-
return {
|
|
2538
|
-
...rootBase,
|
|
2539
|
-
submitting: state.submitting.value,
|
|
2540
|
-
submissionAttempts: state.submissionAttempts.value,
|
|
2541
|
-
departAttempts: state.departAttempts.value,
|
|
2542
|
-
submitError: state.submitError.value,
|
|
2543
|
-
errorCount: rootBase.errors.length,
|
|
2544
|
-
submitted: state.submitted.value,
|
|
2545
|
-
instanceId: formInstanceId
|
|
2546
|
-
};
|
|
2547
|
-
};
|
|
2548
|
-
const fieldStateAccessorOptions = options.shouldShowErrors !== void 0 ? { shouldShowErrors: options.shouldShowErrors } : void 0;
|
|
2549
|
-
const getRootFieldStateAt = buildFieldStateAccessor(
|
|
2550
|
-
state,
|
|
2551
|
-
getFormMetaBase,
|
|
2552
|
-
fieldStateAccessorOptions
|
|
2553
|
-
);
|
|
2554
2649
|
const rootFieldState = getRootFieldStateAt([]);
|
|
2555
2650
|
const formMeta = vue.readonly(
|
|
2556
2651
|
vue.reactive({
|
|
@@ -2565,6 +2660,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2565
2660
|
focused: vue.computed(() => rootFieldState.value.focused),
|
|
2566
2661
|
blurred: vue.computed(() => rootFieldState.value.blurred),
|
|
2567
2662
|
touched: vue.computed(() => rootFieldState.value.touched),
|
|
2663
|
+
interacted: vue.computed(() => rootFieldState.value.interacted),
|
|
2664
|
+
blurredAfterInteraction: vue.computed(() => rootFieldState.value.blurredAfterInteraction),
|
|
2568
2665
|
connected: vue.computed(() => rootFieldState.value.connected),
|
|
2569
2666
|
element: vue.computed(() => rootFieldState.value.element),
|
|
2570
2667
|
elements: vue.computed(() => rootFieldState.value.elements),
|
|
@@ -2586,14 +2683,21 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2586
2683
|
// keep the explicit form-level computation for the gate.
|
|
2587
2684
|
valid,
|
|
2588
2685
|
errors: metaErrors,
|
|
2589
|
-
// `
|
|
2590
|
-
// field-state computed as the rest of the
|
|
2591
|
-
// so `form.meta.
|
|
2592
|
-
// exactly — the predicate runs once
|
|
2593
|
-
// is shared.
|
|
2686
|
+
// `displayState` / the `show*` booleans / `firstError` flow
|
|
2687
|
+
// through the same root field-state computed as the rest of the
|
|
2688
|
+
// FieldState surface, so `form.meta.displayState` matches
|
|
2689
|
+
// `form.fields().displayState` exactly — the predicate runs once
|
|
2690
|
+
// at the root and the result is shared.
|
|
2691
|
+
displayState: vue.computed(() => rootFieldState.value.displayState),
|
|
2594
2692
|
showErrors: vue.computed(() => rootFieldState.value.showErrors),
|
|
2693
|
+
showPending: vue.computed(() => rootFieldState.value.showPending),
|
|
2694
|
+
showSuccess: vue.computed(() => rootFieldState.value.showSuccess),
|
|
2695
|
+
showIdle: vue.computed(() => rootFieldState.value.showIdle),
|
|
2595
2696
|
firstError: vue.computed(() => rootFieldState.value.firstError),
|
|
2596
2697
|
path: vue.computed(() => rootFieldState.value.path),
|
|
2698
|
+
id: vue.computed(() => rootFieldState.value.id),
|
|
2699
|
+
aria: vue.computed(() => rootFieldState.value.aria),
|
|
2700
|
+
key: vue.computed(() => rootFieldState.value.key),
|
|
2597
2701
|
blank: vue.computed(() => rootFieldState.value.blank),
|
|
2598
2702
|
label: vue.computed(() => rootFieldState.value.label),
|
|
2599
2703
|
description: vue.computed(() => rootFieldState.value.description),
|
|
@@ -2709,13 +2813,41 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2709
2813
|
return Object.freeze(view);
|
|
2710
2814
|
});
|
|
2711
2815
|
const valuesProxy = buildValuesProxy(state.form);
|
|
2712
|
-
const fieldStateProxy = buildFieldStateProxy(
|
|
2816
|
+
const fieldStateProxy = buildFieldStateProxy(
|
|
2817
|
+
state,
|
|
2818
|
+
formInstanceId,
|
|
2819
|
+
getFormMetaBase,
|
|
2820
|
+
fieldStateAccessorOptions
|
|
2821
|
+
);
|
|
2713
2822
|
function gated(fn) {
|
|
2714
2823
|
return ((...args) => {
|
|
2715
2824
|
void state.activate();
|
|
2716
2825
|
return fn(...args);
|
|
2717
2826
|
});
|
|
2718
2827
|
}
|
|
2828
|
+
const callTerminal = fieldStateProxy;
|
|
2829
|
+
const EMPTY_FIELD_LIST = Object.freeze([]);
|
|
2830
|
+
function list(path) {
|
|
2831
|
+
const { segments } = paths.canonicalizePath(path);
|
|
2832
|
+
const value = state.getValueAtPath(segments);
|
|
2833
|
+
if (!Array.isArray(value)) return EMPTY_FIELD_LIST;
|
|
2834
|
+
const out = new Array(value.length);
|
|
2835
|
+
for (let i = 0; i < value.length; i += 1) out[i] = callTerminal(`${path}.${i}`);
|
|
2836
|
+
return Object.freeze(out);
|
|
2837
|
+
}
|
|
2838
|
+
const EMPTY_FIELD_RECORD = Object.freeze({});
|
|
2839
|
+
function record(path) {
|
|
2840
|
+
const { segments } = paths.canonicalizePath(path);
|
|
2841
|
+
const value = state.getValueAtPath(segments);
|
|
2842
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
2843
|
+
return EMPTY_FIELD_RECORD;
|
|
2844
|
+
}
|
|
2845
|
+
const out = {};
|
|
2846
|
+
for (const key of Object.keys(value)) {
|
|
2847
|
+
out[key] = callTerminal(`${path}.${key}`);
|
|
2848
|
+
}
|
|
2849
|
+
return Object.freeze(out);
|
|
2850
|
+
}
|
|
2719
2851
|
return {
|
|
2720
2852
|
handleSubmit: gated(handleSubmit),
|
|
2721
2853
|
// Callable readonly Proxies (`values`, `fields`, `errors`) and the
|
|
@@ -2797,6 +2929,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2797
2929
|
swap: gated(fieldArrays.swap),
|
|
2798
2930
|
move: gated(fieldArrays.move),
|
|
2799
2931
|
replace: gated(fieldArrays.replace),
|
|
2932
|
+
list: gated(list),
|
|
2933
|
+
record: gated(record),
|
|
2800
2934
|
get blankPaths() {
|
|
2801
2935
|
void state.activate();
|
|
2802
2936
|
return blankPathsView;
|
|
@@ -2804,28 +2938,186 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2804
2938
|
};
|
|
2805
2939
|
}
|
|
2806
2940
|
|
|
2807
|
-
|
|
2808
|
-
const
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2941
|
+
function createArrayIdentity(getArrayLength) {
|
|
2942
|
+
const tokens = /* @__PURE__ */ new Map();
|
|
2943
|
+
const baselines = /* @__PURE__ */ new Map();
|
|
2944
|
+
let counter = 0;
|
|
2945
|
+
const allocate = () => `k${(counter++).toString(36)}`;
|
|
2946
|
+
function ensure(arrayKey, expectedLen) {
|
|
2947
|
+
let ids = tokens.get(arrayKey);
|
|
2948
|
+
const firstTrack = ids === void 0;
|
|
2949
|
+
if (ids === void 0) {
|
|
2950
|
+
ids = [];
|
|
2951
|
+
tokens.set(arrayKey, ids);
|
|
2952
|
+
}
|
|
2953
|
+
while (ids.length < expectedLen) ids.push(allocate());
|
|
2954
|
+
if (ids.length > expectedLen) ids.length = expectedLen;
|
|
2955
|
+
if (firstTrack) baselines.set(arrayKey, [...ids]);
|
|
2956
|
+
return ids;
|
|
2957
|
+
}
|
|
2958
|
+
function orderPristineForKey(arrayKey) {
|
|
2959
|
+
const baseline = baselines.get(arrayKey);
|
|
2960
|
+
const current = tokens.get(arrayKey);
|
|
2961
|
+
if (baseline === void 0 || current === void 0) return true;
|
|
2962
|
+
if (baseline.length !== current.length) return false;
|
|
2963
|
+
for (let i = 0; i < current.length; i++) {
|
|
2964
|
+
if (current[i] !== baseline[i]) return false;
|
|
2965
|
+
}
|
|
2966
|
+
return true;
|
|
2967
|
+
}
|
|
2968
|
+
return {
|
|
2969
|
+
tokenAt(arraySegs, index) {
|
|
2970
|
+
const len = getArrayLength(arraySegs);
|
|
2971
|
+
if (index < 0 || index >= len) return "";
|
|
2972
|
+
const ids = ensure(paths.canonicalizePath(arraySegs).key, len);
|
|
2973
|
+
return ids[index] ?? "";
|
|
2974
|
+
},
|
|
2975
|
+
applyOp(arraySegs, op) {
|
|
2976
|
+
const arrayKey = paths.canonicalizePath(arraySegs).key;
|
|
2977
|
+
const postLen = getArrayLength(arraySegs);
|
|
2978
|
+
const preLen = op.kind === "insert" ? postLen - 1 : op.kind === "remove" ? postLen + 1 : postLen;
|
|
2979
|
+
const ids = ensure(arrayKey, Math.max(0, preLen));
|
|
2980
|
+
switch (op.kind) {
|
|
2981
|
+
case "insert":
|
|
2982
|
+
ids.splice(op.index, 0, allocate());
|
|
2983
|
+
return;
|
|
2984
|
+
case "remove":
|
|
2985
|
+
ids.splice(op.index, 1);
|
|
2986
|
+
return;
|
|
2987
|
+
case "move": {
|
|
2988
|
+
const [moved] = ids.splice(op.from, 1);
|
|
2989
|
+
ids.splice(op.to, 0, moved ?? allocate());
|
|
2990
|
+
return;
|
|
2991
|
+
}
|
|
2992
|
+
case "swap": {
|
|
2993
|
+
const tmp = ids[op.a] ?? allocate();
|
|
2994
|
+
ids[op.a] = ids[op.b] ?? allocate();
|
|
2995
|
+
ids[op.b] = tmp;
|
|
2996
|
+
return;
|
|
2997
|
+
}
|
|
2998
|
+
case "replace-at":
|
|
2999
|
+
ids[op.index] = allocate();
|
|
3000
|
+
return;
|
|
3001
|
+
}
|
|
3002
|
+
},
|
|
3003
|
+
realign(arraySegs) {
|
|
3004
|
+
ensure(paths.canonicalizePath(arraySegs).key, getArrayLength(arraySegs));
|
|
3005
|
+
},
|
|
3006
|
+
hasStructuralChangeUnder(prefix) {
|
|
3007
|
+
for (const arrayKey of tokens.keys()) {
|
|
3008
|
+
if (orderPristineForKey(arrayKey)) continue;
|
|
3009
|
+
const segs = paths.segmentsForPathKey(arrayKey);
|
|
3010
|
+
if (segs === null) continue;
|
|
3011
|
+
if (paths.isPathPrefix(prefix, segs)) return true;
|
|
3012
|
+
}
|
|
3013
|
+
return false;
|
|
3014
|
+
},
|
|
3015
|
+
rebaselineAll() {
|
|
3016
|
+
for (const arrayKey of [...tokens.keys()]) {
|
|
3017
|
+
const segs = paths.segmentsForPathKey(arrayKey);
|
|
3018
|
+
if (segs === null) continue;
|
|
3019
|
+
const ids = ensure(arrayKey, getArrayLength(segs));
|
|
3020
|
+
baselines.set(arrayKey, [...ids]);
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
};
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
function remapForOp(op, oldLen) {
|
|
3027
|
+
const moved = /* @__PURE__ */ new Map();
|
|
3028
|
+
const vacated = /* @__PURE__ */ new Set();
|
|
3029
|
+
const fresh = /* @__PURE__ */ new Set();
|
|
3030
|
+
switch (op.kind) {
|
|
3031
|
+
case "insert":
|
|
3032
|
+
for (let i = op.index; i < oldLen; i++) moved.set(i, i + 1);
|
|
3033
|
+
fresh.add(op.index);
|
|
3034
|
+
return { moved, vacated, fresh };
|
|
3035
|
+
case "remove":
|
|
3036
|
+
vacated.add(op.index);
|
|
3037
|
+
for (let i = op.index + 1; i < oldLen; i++) moved.set(i, i - 1);
|
|
3038
|
+
return { moved, vacated, fresh };
|
|
3039
|
+
case "move":
|
|
3040
|
+
if (op.from !== op.to) {
|
|
3041
|
+
moved.set(op.from, op.to);
|
|
3042
|
+
if (op.from < op.to) {
|
|
3043
|
+
for (let i = op.from + 1; i <= op.to; i++) moved.set(i, i - 1);
|
|
3044
|
+
} else {
|
|
3045
|
+
for (let i = op.to; i < op.from; i++) moved.set(i, i + 1);
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
return { moved, vacated, fresh };
|
|
3049
|
+
case "swap":
|
|
3050
|
+
if (op.a !== op.b) {
|
|
3051
|
+
moved.set(op.a, op.b);
|
|
3052
|
+
moved.set(op.b, op.a);
|
|
3053
|
+
}
|
|
3054
|
+
return { moved, vacated, fresh };
|
|
3055
|
+
case "replace-at":
|
|
3056
|
+
vacated.add(op.index);
|
|
3057
|
+
fresh.add(op.index);
|
|
3058
|
+
return { moved, vacated, fresh };
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
function changedIndices(remap) {
|
|
3062
|
+
const changed = new Set(remap.vacated);
|
|
3063
|
+
for (const [from, to] of remap.moved) {
|
|
3064
|
+
changed.add(from);
|
|
3065
|
+
changed.add(to);
|
|
3066
|
+
}
|
|
3067
|
+
for (const index of remap.fresh) changed.add(index);
|
|
3068
|
+
return changed;
|
|
3069
|
+
}
|
|
3070
|
+
function elementIndexUnder(arrayPath, key, idxPos) {
|
|
3071
|
+
const segments = paths.segmentsForPathKey(key);
|
|
3072
|
+
if (segments === null) return null;
|
|
3073
|
+
if (!paths.isPathPrefix(arrayPath, segments)) return null;
|
|
3074
|
+
if (segments.length <= idxPos) return null;
|
|
3075
|
+
const index = segments[idxPos];
|
|
3076
|
+
return typeof index === "number" ? index : null;
|
|
3077
|
+
}
|
|
3078
|
+
function migrateMapSubtree(map, arrayPath, remap, rewriteValue) {
|
|
3079
|
+
const idxPos = arrayPath.length;
|
|
3080
|
+
const snapshots = [];
|
|
3081
|
+
for (const [key, value] of map) {
|
|
3082
|
+
const index = elementIndexUnder(arrayPath, key, idxPos);
|
|
3083
|
+
if (index === null) continue;
|
|
3084
|
+
if (!remap.moved.has(index) && !remap.vacated.has(index)) continue;
|
|
3085
|
+
snapshots.push({ segments: [...paths.segmentsForPathKey(key)], index, value });
|
|
3086
|
+
}
|
|
3087
|
+
if (snapshots.length === 0) return;
|
|
3088
|
+
for (const snap of snapshots) map.delete(paths.canonicalizePath(snap.segments).key);
|
|
3089
|
+
for (const snap of snapshots) {
|
|
3090
|
+
const target = remap.moved.get(snap.index);
|
|
3091
|
+
if (target === void 0) continue;
|
|
3092
|
+
const relocated = snap.segments.slice();
|
|
3093
|
+
relocated[idxPos] = target;
|
|
3094
|
+
map.set(paths.canonicalizePath(relocated).key, rewriteValue(snap.value, relocated));
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
function migrateSetSubtree(set, arrayPath, remap) {
|
|
3098
|
+
const idxPos = arrayPath.length;
|
|
3099
|
+
const snapshots = [];
|
|
3100
|
+
for (const key of set) {
|
|
3101
|
+
const index = elementIndexUnder(arrayPath, key, idxPos);
|
|
3102
|
+
if (index === null) continue;
|
|
3103
|
+
if (!remap.moved.has(index) && !remap.vacated.has(index)) continue;
|
|
3104
|
+
snapshots.push({ segments: [...paths.segmentsForPathKey(key)], index });
|
|
3105
|
+
}
|
|
3106
|
+
if (snapshots.length === 0) return;
|
|
3107
|
+
for (const snap of snapshots) set.delete(paths.canonicalizePath(snap.segments).key);
|
|
3108
|
+
for (const snap of snapshots) {
|
|
3109
|
+
const target = remap.moved.get(snap.index);
|
|
3110
|
+
if (target === void 0) continue;
|
|
3111
|
+
const relocated = snap.segments.slice();
|
|
3112
|
+
relocated[idxPos] = target;
|
|
3113
|
+
set.add(paths.canonicalizePath(relocated).key);
|
|
3114
|
+
}
|
|
2823
3115
|
}
|
|
2824
3116
|
|
|
2825
3117
|
function isHydratedFieldRecord(value) {
|
|
2826
3118
|
if (typeof value !== "object" || value === null) return false;
|
|
2827
3119
|
const r = value;
|
|
2828
|
-
return Array.isArray(r.path) && (typeof r.updatedAt === "string" || r.updatedAt === null) && typeof r.connected === "boolean" && (typeof r.focused === "boolean" || r.focused === null) && (typeof r.blurred === "boolean" || r.blurred === null) && typeof r.touched === "boolean";
|
|
3120
|
+
return Array.isArray(r.path) && (typeof r.updatedAt === "string" || r.updatedAt === null) && typeof r.connected === "boolean" && (typeof r.focused === "boolean" || r.focused === null) && (typeof r.blurred === "boolean" || r.blurred === null) && typeof r.touched === "boolean" && typeof r.interacted === "boolean" && typeof r.blurredAfterInteraction === "boolean";
|
|
2829
3121
|
}
|
|
2830
3122
|
function isHydratedValidationErrorArray(value) {
|
|
2831
3123
|
if (!Array.isArray(value)) return false;
|
|
@@ -3012,9 +3304,7 @@ function createFormStore(options) {
|
|
|
3012
3304
|
noSyncPathCounts.set(path, current - 1);
|
|
3013
3305
|
}
|
|
3014
3306
|
const coerceIndex = resolveCoercionIndex(options.coerce);
|
|
3015
|
-
const
|
|
3016
|
-
options.shouldShowErrors
|
|
3017
|
-
);
|
|
3307
|
+
const resolvedGetDisplayState = resolveGetDisplayState(options.getDisplayState);
|
|
3018
3308
|
const resolvedIsSensitivePath = options.isSensitivePath ?? paths.isSensitivePath;
|
|
3019
3309
|
const resolvedSegmentMatchesSensitive = options.segmentMatchesSensitive ?? paths.segmentMatchesSensitive;
|
|
3020
3310
|
const cleanupHooks = [];
|
|
@@ -3054,6 +3344,16 @@ function createFormStore(options) {
|
|
|
3054
3344
|
warn: true
|
|
3055
3345
|
});
|
|
3056
3346
|
const form = vue.ref(stubbedInitialData);
|
|
3347
|
+
const arrayIdentity = createArrayIdentity((arraySegs) => {
|
|
3348
|
+
const v = getAtPath(form.value, arraySegs);
|
|
3349
|
+
return Array.isArray(v) ? v.length : 0;
|
|
3350
|
+
});
|
|
3351
|
+
function arrayElementKey(path) {
|
|
3352
|
+
if (path.length === 0) return "";
|
|
3353
|
+
const last = path[path.length - 1];
|
|
3354
|
+
if (typeof last === "number") return arrayIdentity.tokenAt(path.slice(0, -1), last);
|
|
3355
|
+
return "";
|
|
3356
|
+
}
|
|
3057
3357
|
const fields = vue.reactive(/* @__PURE__ */ new Map());
|
|
3058
3358
|
const elements = vue.reactive(/* @__PURE__ */ new Map());
|
|
3059
3359
|
const elementToFormInstance = /* @__PURE__ */ new WeakMap();
|
|
@@ -3090,12 +3390,16 @@ function createFormStore(options) {
|
|
|
3090
3390
|
}
|
|
3091
3391
|
function applyArrayOpToMemory(arrayPath, op) {
|
|
3092
3392
|
switch (op.kind) {
|
|
3093
|
-
case "
|
|
3393
|
+
case "insert":
|
|
3394
|
+
case "remove":
|
|
3094
3395
|
clearVariantMemoryAtArrayIndices(arrayPath, (i) => i >= op.index);
|
|
3095
3396
|
return;
|
|
3096
|
-
case "
|
|
3097
|
-
|
|
3397
|
+
case "move": {
|
|
3398
|
+
const lo = Math.min(op.from, op.to);
|
|
3399
|
+
const hi = Math.max(op.from, op.to);
|
|
3400
|
+
clearVariantMemoryAtArrayIndices(arrayPath, (i) => i >= lo && i <= hi);
|
|
3098
3401
|
return;
|
|
3402
|
+
}
|
|
3099
3403
|
case "swap":
|
|
3100
3404
|
clearVariantMemoryAtArrayIndices(arrayPath, (i) => i === op.a || i === op.b);
|
|
3101
3405
|
return;
|
|
@@ -3104,6 +3408,68 @@ function createFormStore(options) {
|
|
|
3104
3408
|
return;
|
|
3105
3409
|
}
|
|
3106
3410
|
}
|
|
3411
|
+
function migrateArrayElementState(arrayPath, remap) {
|
|
3412
|
+
if (remap.moved.size === 0 && remap.vacated.size === 0) return;
|
|
3413
|
+
migrateMapSubtree(fields, arrayPath, remap, (record, segments) => ({
|
|
3414
|
+
...record,
|
|
3415
|
+
path: segments
|
|
3416
|
+
}));
|
|
3417
|
+
migrateMapSubtree(
|
|
3418
|
+
userErrors,
|
|
3419
|
+
arrayPath,
|
|
3420
|
+
remap,
|
|
3421
|
+
(errors, segments) => errors.map((error) => ({ ...error, path: [...segments] }))
|
|
3422
|
+
);
|
|
3423
|
+
migrateMapSubtree(originals, arrayPath, remap, (record, segments) => ({
|
|
3424
|
+
segments,
|
|
3425
|
+
value: record.value
|
|
3426
|
+
}));
|
|
3427
|
+
migrateSetSubtree(blankPaths, arrayPath, remap);
|
|
3428
|
+
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
3429
|
+
}
|
|
3430
|
+
function seedFreshElement(arrayPath, freshIndex) {
|
|
3431
|
+
const elementPath = [...arrayPath, freshIndex];
|
|
3432
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3433
|
+
diffAndApply(void 0, getAtPath(form.value, elementPath), elementPath, (patch) => {
|
|
3434
|
+
if (patch.kind !== "added") return;
|
|
3435
|
+
const { key } = paths.canonicalizePath(patch.path);
|
|
3436
|
+
if (!originals.has(key)) originals.set(key, { segments: patch.path, value: void 0 });
|
|
3437
|
+
touchFieldRecord(key, patch.path, { updatedAt: now });
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
function dropSchemaErrorsAtChangedIndices(arrayPath, remap) {
|
|
3441
|
+
const changed = changedIndices(remap);
|
|
3442
|
+
if (changed.size === 0) return;
|
|
3443
|
+
const idxPos = arrayPath.length;
|
|
3444
|
+
for (const key of [...schemaErrors.keys()]) {
|
|
3445
|
+
const segs = paths.segmentsForPathKey(key);
|
|
3446
|
+
if (segs === null) continue;
|
|
3447
|
+
if (!isPathPrefix(arrayPath, segs)) continue;
|
|
3448
|
+
if (segs.length <= idxPos) continue;
|
|
3449
|
+
const idx = segs[idxPos];
|
|
3450
|
+
if (typeof idx === "number" && changed.has(idx)) schemaErrors.delete(key);
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
function abortValidationAtVacatedIndices(arrayPath, remap) {
|
|
3454
|
+
if (remap.vacated.size === 0) return;
|
|
3455
|
+
const idxPos = arrayPath.length;
|
|
3456
|
+
for (const [key, entry] of [...fieldValidationState]) {
|
|
3457
|
+
const segs = paths.segmentsForPathKey(key);
|
|
3458
|
+
if (segs === null) continue;
|
|
3459
|
+
if (!isPathPrefix(arrayPath, segs)) continue;
|
|
3460
|
+
if (segs.length <= idxPos) continue;
|
|
3461
|
+
const idx = segs[idxPos];
|
|
3462
|
+
if (typeof idx !== "number" || !remap.vacated.has(idx)) continue;
|
|
3463
|
+
if (entry.timer !== null) {
|
|
3464
|
+
clearTimeout(entry.timer);
|
|
3465
|
+
} else if (!entry.settled) {
|
|
3466
|
+
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
3467
|
+
decFieldValidation(key);
|
|
3468
|
+
}
|
|
3469
|
+
entry.controller.abort();
|
|
3470
|
+
fieldValidationState.delete(key);
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3107
3473
|
const pathOrdinals = /* @__PURE__ */ new Map();
|
|
3108
3474
|
let nextOrdinal = 0;
|
|
3109
3475
|
function ensurePathOrdinal(key) {
|
|
@@ -3141,6 +3507,7 @@ function createFormStore(options) {
|
|
|
3141
3507
|
const departAttempts = vue.ref(0);
|
|
3142
3508
|
const submissionGeneration = vue.ref(0);
|
|
3143
3509
|
const activeValidations = vue.ref(0);
|
|
3510
|
+
let lastValidatedSnapshot = null;
|
|
3144
3511
|
const hydrating = vue.ref(false);
|
|
3145
3512
|
const hydrateError = vue.ref(null);
|
|
3146
3513
|
const defaultValuesFactory = vue.ref(void 0);
|
|
@@ -3211,7 +3578,9 @@ function createFormStore(options) {
|
|
|
3211
3578
|
connected: false,
|
|
3212
3579
|
focused: null,
|
|
3213
3580
|
blurred: null,
|
|
3214
|
-
touched: false
|
|
3581
|
+
touched: false,
|
|
3582
|
+
interacted: false,
|
|
3583
|
+
blurredAfterInteraction: false
|
|
3215
3584
|
});
|
|
3216
3585
|
});
|
|
3217
3586
|
if (strict && !schemaResponse.success) {
|
|
@@ -3240,7 +3609,12 @@ function createFormStore(options) {
|
|
|
3240
3609
|
blurred: patch.blurred !== void 0 ? patch.blurred : current?.blurred ?? null,
|
|
3241
3610
|
// touched is plain `boolean`; `??` is equivalent to the explicit
|
|
3242
3611
|
// guard here because `false` is not nullish.
|
|
3243
|
-
touched: patch.touched ?? current?.touched ?? false
|
|
3612
|
+
touched: patch.touched ?? current?.touched ?? false,
|
|
3613
|
+
// interacted is sticky-true; a merge patch only ever sets it, so
|
|
3614
|
+
// `??` preserves the current bit. It flips back to false solely
|
|
3615
|
+
// through the reset paths, which reconstruct the record outright.
|
|
3616
|
+
interacted: patch.interacted ?? current?.interacted ?? false,
|
|
3617
|
+
blurredAfterInteraction: patch.blurredAfterInteraction ?? current?.blurredAfterInteraction ?? false
|
|
3244
3618
|
});
|
|
3245
3619
|
}
|
|
3246
3620
|
function applyFormReplacement(next, meta) {
|
|
@@ -3386,12 +3760,20 @@ function createFormStore(options) {
|
|
|
3386
3760
|
}
|
|
3387
3761
|
return true;
|
|
3388
3762
|
}
|
|
3763
|
+
const oldArrayLength = Array.isArray(currentValue) ? currentValue.length : 0;
|
|
3389
3764
|
const nextForm = setAtPathWithSchemaFill(form.value, schema, path, completedValue);
|
|
3390
3765
|
applyFormReplacement(nextForm, meta);
|
|
3391
3766
|
if (meta?.arrayOp !== void 0) {
|
|
3767
|
+
const remap = remapForOp(meta.arrayOp, oldArrayLength);
|
|
3768
|
+
migrateArrayElementState(path, remap);
|
|
3769
|
+
for (const freshIndex of remap.fresh) seedFreshElement(path, freshIndex);
|
|
3770
|
+
dropSchemaErrorsAtChangedIndices(path, remap);
|
|
3771
|
+
abortValidationAtVacatedIndices(path, remap);
|
|
3392
3772
|
applyArrayOpToMemory(path, meta.arrayOp);
|
|
3773
|
+
arrayIdentity.applyOp(path, meta.arrayOp);
|
|
3393
3774
|
} else if (Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3394
3775
|
clearVariantMemoryUnderPath(path);
|
|
3776
|
+
arrayIdentity.realign(path);
|
|
3395
3777
|
}
|
|
3396
3778
|
const effectiveModeAfterWrite = meta?.instance?.validateOn ?? fieldValidationMode;
|
|
3397
3779
|
if (effectiveModeAfterWrite === "change") {
|
|
@@ -3501,6 +3883,9 @@ function createFormStore(options) {
|
|
|
3501
3883
|
const run = () => {
|
|
3502
3884
|
fresh.timer = null;
|
|
3503
3885
|
if (controller.signal.aborted) return;
|
|
3886
|
+
if (effectiveMode === "blur") {
|
|
3887
|
+
lastValidatedSnapshot = { value: structuralSnapshot(form.value) };
|
|
3888
|
+
}
|
|
3504
3889
|
let activeIncremented = false;
|
|
3505
3890
|
try {
|
|
3506
3891
|
activeValidations.value += 1;
|
|
@@ -3743,25 +4128,47 @@ function createFormStore(options) {
|
|
|
3743
4128
|
}
|
|
3744
4129
|
function markFocused(path, focused, meta) {
|
|
3745
4130
|
const { key } = paths.canonicalizePath(path);
|
|
4131
|
+
const current = fields.get(key);
|
|
3746
4132
|
touchFieldRecord(key, path, {
|
|
3747
4133
|
focused,
|
|
3748
4134
|
blurred: !focused,
|
|
3749
4135
|
// `touched` flips to true on blur and stays true thereafter; while
|
|
3750
4136
|
// a field is currently focused we keep whatever value it held.
|
|
3751
|
-
touched: focused ?
|
|
4137
|
+
touched: focused ? current?.touched ?? false : true,
|
|
4138
|
+
// `blurredAfterInteraction` flips true on the first blur that lands
|
|
4139
|
+
// after a value edit and stays true. A tab-through blur before any
|
|
4140
|
+
// edit leaves it false (`interacted` is still false at that blur),
|
|
4141
|
+
// which is what keeps a clean tab-through from arming the gate.
|
|
4142
|
+
blurredAfterInteraction: !focused && current?.interacted === true ? true : current?.blurredAfterInteraction ?? false
|
|
3752
4143
|
});
|
|
3753
4144
|
const focusMode = meta?.instance?.validateOn ?? fieldValidationMode;
|
|
3754
4145
|
if (!focused && focusMode === "blur") {
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
4146
|
+
const firstInteractiveBlur = current?.interacted === true && current.blurredAfterInteraction !== true;
|
|
4147
|
+
const snapshot = lastValidatedSnapshot;
|
|
4148
|
+
let changed = true;
|
|
4149
|
+
if (!firstInteractiveBlur && snapshot !== null) {
|
|
4150
|
+
changed = false;
|
|
4151
|
+
diffAndApply(snapshot.value, form.value, [], () => {
|
|
4152
|
+
changed = true;
|
|
4153
|
+
});
|
|
4154
|
+
}
|
|
4155
|
+
if (changed) {
|
|
4156
|
+
scheduleFieldValidation(path, true, {
|
|
4157
|
+
...meta?.instance?.validateOn !== void 0 ? { mode: meta.instance.validateOn } : {},
|
|
4158
|
+
...meta?.instance?.debounceMs !== void 0 ? { debounceMs: meta.instance.debounceMs } : {}
|
|
4159
|
+
});
|
|
4160
|
+
}
|
|
3759
4161
|
}
|
|
3760
4162
|
}
|
|
3761
4163
|
function markTouched(path) {
|
|
3762
4164
|
const { key } = paths.canonicalizePath(path);
|
|
3763
4165
|
touchFieldRecord(key, path, { touched: true });
|
|
3764
4166
|
}
|
|
4167
|
+
function markInteracted(path) {
|
|
4168
|
+
const { key } = paths.canonicalizePath(path);
|
|
4169
|
+
if (fields.get(key)?.interacted === true) return;
|
|
4170
|
+
touchFieldRecord(key, path, { interacted: true });
|
|
4171
|
+
}
|
|
3765
4172
|
function touchAtPath(segments) {
|
|
3766
4173
|
const formValue = form.value;
|
|
3767
4174
|
let touchedAny = false;
|
|
@@ -3872,6 +4279,7 @@ function createFormStore(options) {
|
|
|
3872
4279
|
const next = resetResponse.data;
|
|
3873
4280
|
rebuildAuthoredPaths(resetSource, next);
|
|
3874
4281
|
applyFormReplacement(next);
|
|
4282
|
+
arrayIdentity.rebaselineAll();
|
|
3875
4283
|
originals.clear();
|
|
3876
4284
|
diffAndApply({}, next, [], (patch) => {
|
|
3877
4285
|
if (patch.kind !== "added") return;
|
|
@@ -3915,7 +4323,9 @@ function createFormStore(options) {
|
|
|
3915
4323
|
connected: record.connected,
|
|
3916
4324
|
focused: record.focused,
|
|
3917
4325
|
blurred: record.blurred,
|
|
3918
|
-
touched: false
|
|
4326
|
+
touched: false,
|
|
4327
|
+
interacted: false,
|
|
4328
|
+
blurredAfterInteraction: false
|
|
3919
4329
|
});
|
|
3920
4330
|
}
|
|
3921
4331
|
submissionGeneration.value += 1;
|
|
@@ -3999,7 +4409,9 @@ function createFormStore(options) {
|
|
|
3999
4409
|
connected: record.connected,
|
|
4000
4410
|
focused: record.focused,
|
|
4001
4411
|
blurred: record.blurred,
|
|
4002
|
-
touched: false
|
|
4412
|
+
touched: false,
|
|
4413
|
+
interacted: false,
|
|
4414
|
+
blurredAfterInteraction: false
|
|
4003
4415
|
});
|
|
4004
4416
|
}
|
|
4005
4417
|
function isPathPrefix(prefix, candidate) {
|
|
@@ -4016,6 +4428,9 @@ function createFormStore(options) {
|
|
|
4016
4428
|
if (entry === void 0) return true;
|
|
4017
4429
|
return Object.is(getAtPath(form.value, segments), entry.value);
|
|
4018
4430
|
}
|
|
4431
|
+
function hasStructuralChangeUnder(path) {
|
|
4432
|
+
return arrayIdentity.hasStructuralChangeUnder(path);
|
|
4433
|
+
}
|
|
4019
4434
|
function getFieldRecord(path) {
|
|
4020
4435
|
const { key } = paths.canonicalizePath(path);
|
|
4021
4436
|
return fields.get(key);
|
|
@@ -4059,7 +4474,7 @@ function createFormStore(options) {
|
|
|
4059
4474
|
originals,
|
|
4060
4475
|
schema,
|
|
4061
4476
|
ssr,
|
|
4062
|
-
|
|
4477
|
+
getDisplayState: resolvedGetDisplayState,
|
|
4063
4478
|
submitting,
|
|
4064
4479
|
activeSubmissions,
|
|
4065
4480
|
submissionAttempts,
|
|
@@ -4082,6 +4497,7 @@ function createFormStore(options) {
|
|
|
4082
4497
|
applyFormReplacement,
|
|
4083
4498
|
setValueAtPath,
|
|
4084
4499
|
getValueAtPath,
|
|
4500
|
+
arrayElementKey,
|
|
4085
4501
|
reset,
|
|
4086
4502
|
resetField,
|
|
4087
4503
|
clear,
|
|
@@ -4098,9 +4514,11 @@ function createFormStore(options) {
|
|
|
4098
4514
|
deregisterElement,
|
|
4099
4515
|
markFocused,
|
|
4100
4516
|
markTouched,
|
|
4517
|
+
markInteracted,
|
|
4101
4518
|
touchAtPath,
|
|
4102
4519
|
markConnectedOptimistically,
|
|
4103
4520
|
isPristineAtPath,
|
|
4521
|
+
hasStructuralChangeUnder,
|
|
4104
4522
|
getFieldRecord,
|
|
4105
4523
|
getOriginalAtPath,
|
|
4106
4524
|
getFirstErrorElement,
|
|
@@ -4317,19 +4735,6 @@ function createHistoryModule(state, config) {
|
|
|
4317
4735
|
};
|
|
4318
4736
|
}
|
|
4319
4737
|
|
|
4320
|
-
function hashStableString(input, seed = 0) {
|
|
4321
|
-
let h1 = 3735928559 ^ seed;
|
|
4322
|
-
let h2 = 1103547991 ^ seed;
|
|
4323
|
-
for (let i = 0; i < input.length; i++) {
|
|
4324
|
-
const ch = input.charCodeAt(i);
|
|
4325
|
-
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
4326
|
-
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
4327
|
-
}
|
|
4328
|
-
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
4329
|
-
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
4330
|
-
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36).padStart(11, "0");
|
|
4331
|
-
}
|
|
4332
|
-
|
|
4333
4738
|
const PROTOCOL_VERSION = 1;
|
|
4334
4739
|
const JOIN_COLLECTION_WINDOW_MS = 50;
|
|
4335
4740
|
const SNAPSHOT_TIMEOUT_MS = 200;
|
|
@@ -4852,8 +5257,8 @@ function useAbstractForm(configuration, options) {
|
|
|
4852
5257
|
if (mergedDebounceMs !== void 0) {
|
|
4853
5258
|
apiOptions.debounceMs = mergedDebounceMs;
|
|
4854
5259
|
}
|
|
4855
|
-
if (merged.
|
|
4856
|
-
apiOptions.
|
|
5260
|
+
if (merged.getDisplayState !== void 0) {
|
|
5261
|
+
apiOptions.getDisplayState = merged.getDisplayState;
|
|
4857
5262
|
}
|
|
4858
5263
|
if (merged.coerce !== void 0) {
|
|
4859
5264
|
apiOptions.coerce = merged.coerce;
|
|
@@ -4861,6 +5266,9 @@ function useAbstractForm(configuration, options) {
|
|
|
4861
5266
|
if (merged.rememberVariants !== void 0) {
|
|
4862
5267
|
apiOptions.rememberVariants = merged.rememberVariants;
|
|
4863
5268
|
}
|
|
5269
|
+
if (merged.autoAria !== void 0) {
|
|
5270
|
+
apiOptions.autoAria = merged.autoAria;
|
|
5271
|
+
}
|
|
4864
5272
|
return buildFormApi(
|
|
4865
5273
|
state,
|
|
4866
5274
|
formInstanceId,
|
|
@@ -4875,10 +5283,11 @@ function mergeWithDefaults(defaults, configuration) {
|
|
|
4875
5283
|
const coerce = configuration.coerce ?? defaults.coerce;
|
|
4876
5284
|
const validateOn = configuration.validateOn ?? defaults.validateOn;
|
|
4877
5285
|
const debounceMs = configuration.debounceMs ?? defaults.debounceMs;
|
|
4878
|
-
const
|
|
5286
|
+
const getDisplayState = configuration.getDisplayState ?? defaults.getDisplayState;
|
|
4879
5287
|
const maxRecursionDepth = configuration.maxRecursionDepth ?? defaults.maxRecursionDepth;
|
|
4880
5288
|
const sensitiveNames = configuration.sensitiveNames ?? defaults.sensitiveNames;
|
|
4881
5289
|
const multiTab = configuration.multiTab ?? defaults.multiTab;
|
|
5290
|
+
const autoAria = configuration.autoAria ?? defaults.autoAria;
|
|
4882
5291
|
return {
|
|
4883
5292
|
...configuration,
|
|
4884
5293
|
...strict === void 0 ? {} : { strict },
|
|
@@ -4888,10 +5297,11 @@ function mergeWithDefaults(defaults, configuration) {
|
|
|
4888
5297
|
...coerce === void 0 ? {} : { coerce },
|
|
4889
5298
|
...validateOn === void 0 ? {} : { validateOn },
|
|
4890
5299
|
...debounceMs === void 0 ? {} : { debounceMs },
|
|
4891
|
-
...
|
|
5300
|
+
...getDisplayState === void 0 ? {} : { getDisplayState },
|
|
4892
5301
|
...maxRecursionDepth === void 0 ? {} : { maxRecursionDepth },
|
|
4893
5302
|
...sensitiveNames === void 0 ? {} : { sensitiveNames },
|
|
4894
|
-
...multiTab === void 0 ? {} : { multiTab }
|
|
5303
|
+
...multiTab === void 0 ? {} : { multiTab },
|
|
5304
|
+
...autoAria === void 0 ? {} : { autoAria }
|
|
4895
5305
|
};
|
|
4896
5306
|
}
|
|
4897
5307
|
const HISTORY_MODULE_KEY = "history";
|
|
@@ -4935,7 +5345,7 @@ function buildFreshState(key, schema, configuration, registry) {
|
|
|
4935
5345
|
} : {},
|
|
4936
5346
|
...configuration.rememberVariants !== void 0 ? { rememberVariants: configuration.rememberVariants } : {},
|
|
4937
5347
|
...configuration.coerce !== void 0 ? { coerce: configuration.coerce } : {},
|
|
4938
|
-
...configuration.
|
|
5348
|
+
...configuration.getDisplayState !== void 0 ? { getDisplayState: configuration.getDisplayState } : {},
|
|
4939
5349
|
...initialBlankPaths !== void 0 ? { initialBlankPaths } : {},
|
|
4940
5350
|
...resolvedIsSensitivePath !== void 0 ? { isSensitivePath: resolvedIsSensitivePath } : {},
|
|
4941
5351
|
...resolvedSegmentMatchesSensitive !== void 0 ? { segmentMatchesSensitive: resolvedSegmentMatchesSensitive } : {}
|
|
@@ -6405,7 +6815,7 @@ function warnIfAmbientWizardProviderHadDuplicates() {
|
|
|
6405
6815
|
|
|
6406
6816
|
exports.AttaformErrorCode = AttaformErrorCode;
|
|
6407
6817
|
exports.defaultCoercionRules = defaultCoercionRules;
|
|
6408
|
-
exports.
|
|
6818
|
+
exports.defaultDisplayState = defaultDisplayState;
|
|
6409
6819
|
exports.defineCoercion = defineCoercion;
|
|
6410
6820
|
exports.getAtPath = getAtPath;
|
|
6411
6821
|
exports.humanize = humanize;
|
|
@@ -6420,4 +6830,4 @@ exports.slimKindOf = slimKindOf;
|
|
|
6420
6830
|
exports.unset = unset;
|
|
6421
6831
|
exports.useAbstractForm = useAbstractForm;
|
|
6422
6832
|
exports.useWizard = useWizard;
|
|
6423
|
-
//# sourceMappingURL=attaform.
|
|
6833
|
+
//# sourceMappingURL=attaform.C1msmO2v.cjs.map
|