react-f0rm 1.0.0 → 1.1.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 +34 -0
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.cjs.js.map +1 -1
- package/dist/devtools/index.mjs +1 -1
- package/dist/devtools/index.mjs.map +1 -1
- package/dist/form-BGWPwts2.mjs +2 -0
- package/dist/form-BGWPwts2.mjs.map +1 -0
- package/dist/{form-D-A2NoKo.d.ts → form-BiDaJLjD.d.ts} +79 -5
- package/dist/form-DwuY91QB.cjs.js +2 -0
- package/dist/form-DwuY91QB.cjs.js.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +25 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +133 -31
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +2 -2
- package/dist/index.umd.min.js.map +1 -1
- package/dist/resolvers/standard-schema.cjs.js +1 -1
- package/dist/resolvers/standard-schema.mjs +1 -1
- package/dist/resolvers/yup.cjs.js +1 -1
- package/dist/resolvers/yup.d.ts +1 -1
- package/dist/resolvers/yup.mjs +1 -1
- package/dist/resolvers/zod.cjs.js +1 -1
- package/dist/resolvers/zod.d.ts +1 -1
- package/dist/resolvers/zod.mjs +1 -1
- package/dist/{validate-Bj2oVj82.d.ts → validate-2XUilILy.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/form-D8RKC-r3.cjs.js +0 -2
- package/dist/form-D8RKC-r3.cjs.js.map +0 -1
- package/dist/form-fzTmS8jF.mjs +0 -2
- package/dist/form-fzTmS8jF.mjs.map +0 -1
package/dist/index.umd.js
CHANGED
|
@@ -249,7 +249,23 @@
|
|
|
249
249
|
isSubmitSuccessful: void 0
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
+
const valuesCaches = /* @__PURE__ */ new WeakMap();
|
|
253
|
+
function bumpValuesVersion(form) {
|
|
254
|
+
const cache = valuesCaches.get(form);
|
|
255
|
+
if (cache) cache.version++;
|
|
256
|
+
}
|
|
252
257
|
function getValues(form) {
|
|
258
|
+
let cache = valuesCaches.get(form);
|
|
259
|
+
if (!cache) {
|
|
260
|
+
cache = { version: 0, result: computeValues(form) };
|
|
261
|
+
valuesCaches.set(form, cache);
|
|
262
|
+
} else if (cache.version > 0) {
|
|
263
|
+
cache.result = computeValues(form);
|
|
264
|
+
cache.version = 0;
|
|
265
|
+
}
|
|
266
|
+
return cache.result;
|
|
267
|
+
}
|
|
268
|
+
function computeValues(form) {
|
|
253
269
|
const { initialValues, parsedValues, values, deleted } = form;
|
|
254
270
|
const owned = /* @__PURE__ */ new Set();
|
|
255
271
|
let merged = parsedValues ?? initialValues;
|
|
@@ -287,10 +303,23 @@
|
|
|
287
303
|
pruneDirtyBaselines(form, path);
|
|
288
304
|
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
289
305
|
bumpDirtyVersion(form);
|
|
306
|
+
bumpValuesVersion(form);
|
|
290
307
|
if (options?.shouldTouch) setTouchedByPath(form, path);
|
|
291
308
|
if (options?.shouldValidate) form.validators.get(path.key)?.();
|
|
292
309
|
emit(emitter, "change", path);
|
|
293
310
|
}
|
|
311
|
+
function seedValueByPath(form, path, value) {
|
|
312
|
+
const { values, deleted } = form;
|
|
313
|
+
values.set(path.key, value);
|
|
314
|
+
pruneDescendantKeys(values, path);
|
|
315
|
+
reviveBranch(deleted, path);
|
|
316
|
+
pruneDirtyBaselines(form, path);
|
|
317
|
+
bumpDirtyVersion(form);
|
|
318
|
+
bumpValuesVersion(form);
|
|
319
|
+
}
|
|
320
|
+
function emitChangeByPath({ emitter }, path) {
|
|
321
|
+
emit(emitter, "change", path);
|
|
322
|
+
}
|
|
294
323
|
function changeValue(form, name, value, options) {
|
|
295
324
|
changeValueByPath(form, create$1(name), value, options);
|
|
296
325
|
}
|
|
@@ -492,7 +521,8 @@
|
|
|
492
521
|
function removeField(form, name) {
|
|
493
522
|
removeFieldByPath(form, create$1(name));
|
|
494
523
|
}
|
|
495
|
-
function removeFieldByPath(form,
|
|
524
|
+
function removeFieldByPath(form, path) {
|
|
525
|
+
const { key, value: segments } = path;
|
|
496
526
|
const { emitter, values, touched, errors, validating, deleted } = form;
|
|
497
527
|
values.delete(key);
|
|
498
528
|
touched.delete(key);
|
|
@@ -501,10 +531,11 @@
|
|
|
501
531
|
clearDirtyBaselines(form, key);
|
|
502
532
|
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
503
533
|
bumpDirtyVersion(form);
|
|
504
|
-
|
|
505
|
-
emit(emitter, "
|
|
506
|
-
emit(emitter, "
|
|
507
|
-
emit(emitter, "
|
|
534
|
+
bumpValuesVersion(form);
|
|
535
|
+
emit(emitter, "change", path);
|
|
536
|
+
emit(emitter, "touched", path);
|
|
537
|
+
emit(emitter, "errors", path);
|
|
538
|
+
emit(emitter, "validating", path);
|
|
508
539
|
}
|
|
509
540
|
function hasLiveBranch(values, segments) {
|
|
510
541
|
for (let i = 1; i < segments.length; i++) {
|
|
@@ -541,13 +572,19 @@
|
|
|
541
572
|
form.deleted.clear();
|
|
542
573
|
clearDirtyBaselines(form);
|
|
543
574
|
bumpDirtyVersion(form);
|
|
575
|
+
bumpValuesVersion(form);
|
|
544
576
|
emit(form.emitter, "change");
|
|
545
577
|
}
|
|
546
578
|
function reset(form, initialValues, options) {
|
|
547
|
-
const dirtyValues =
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
579
|
+
const dirtyValues = [];
|
|
580
|
+
if (options?.keepDirtyValues) {
|
|
581
|
+
for (const [key, value] of form.values) {
|
|
582
|
+
const segments = JSON.parse(key);
|
|
583
|
+
if (getDirtyBaseline(form, key, segments) !== value) {
|
|
584
|
+
dirtyValues.push({ segments, value });
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
551
588
|
form.initialValues = initialValues;
|
|
552
589
|
form.parsedValues = void 0;
|
|
553
590
|
if (!options?.keepErrors) clearErrors(form);
|
|
@@ -561,8 +598,9 @@
|
|
|
561
598
|
if (!options?.keepSubmitCount) form.submitCount = 0;
|
|
562
599
|
if (!options?.keepIsSubmitted) form.isSubmitSuccessful = void 0;
|
|
563
600
|
bumpDirtyVersion(form);
|
|
564
|
-
|
|
565
|
-
|
|
601
|
+
bumpValuesVersion(form);
|
|
602
|
+
for (const { segments, value } of dirtyValues) {
|
|
603
|
+
setValueByPath(form, create$1(segments), value);
|
|
566
604
|
}
|
|
567
605
|
emit(emitter, "change");
|
|
568
606
|
emit(emitter, "touched");
|
|
@@ -594,15 +632,16 @@
|
|
|
594
632
|
emit(emitter, "errors", path);
|
|
595
633
|
}
|
|
596
634
|
bumpDirtyVersion(form);
|
|
635
|
+
bumpValuesVersion(form);
|
|
597
636
|
}
|
|
598
637
|
function hasErrors({ errors }) {
|
|
599
638
|
return errors.size > 0;
|
|
600
639
|
}
|
|
601
640
|
async function trigger(form, name) {
|
|
602
|
-
const settle = () => waitUntil(
|
|
641
|
+
const settle = (keys2) => waitUntil(
|
|
603
642
|
form.emitter,
|
|
604
643
|
"validating",
|
|
605
|
-
() => fieldsSettled(form),
|
|
644
|
+
() => keys2 === void 0 ? fieldsSettled(form) : keys2.every((key) => !form.validating.has(key)),
|
|
606
645
|
() => false
|
|
607
646
|
);
|
|
608
647
|
if (name === void 0) {
|
|
@@ -613,7 +652,7 @@
|
|
|
613
652
|
}
|
|
614
653
|
const keys = typeof name === "string" || isSegmentsPath(name) ? [create$1(name).key] : name.map((one) => create$1(one).key);
|
|
615
654
|
keys.forEach((key) => form.validators.get(key)?.());
|
|
616
|
-
await settle();
|
|
655
|
+
await settle(keys);
|
|
617
656
|
return keys.every((key) => !form.errors.has(key));
|
|
618
657
|
}
|
|
619
658
|
function isSegmentsPath(name) {
|
|
@@ -653,6 +692,7 @@
|
|
|
653
692
|
function setParsedValues(form, values) {
|
|
654
693
|
if (values === void 0 || values === form.parsedValues) return;
|
|
655
694
|
form.parsedValues = values;
|
|
695
|
+
bumpValuesVersion(form);
|
|
656
696
|
emit(form.emitter, "change");
|
|
657
697
|
}
|
|
658
698
|
function applyValidateResult(form, result) {
|
|
@@ -794,6 +834,46 @@
|
|
|
794
834
|
});
|
|
795
835
|
}
|
|
796
836
|
}
|
|
837
|
+
const fieldValidateDeps = /* @__PURE__ */ new WeakMap();
|
|
838
|
+
function registerFieldValidateDeps(form, key, depKeys) {
|
|
839
|
+
let deps = fieldValidateDeps.get(form);
|
|
840
|
+
if (!deps) {
|
|
841
|
+
deps = /* @__PURE__ */ new Map();
|
|
842
|
+
fieldValidateDeps.set(form, deps);
|
|
843
|
+
}
|
|
844
|
+
for (const depKey of depKeys) {
|
|
845
|
+
let dependents = deps.get(depKey);
|
|
846
|
+
if (!dependents) {
|
|
847
|
+
dependents = /* @__PURE__ */ new Set();
|
|
848
|
+
deps.set(depKey, dependents);
|
|
849
|
+
}
|
|
850
|
+
dependents.add(key);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
function unregisterFieldValidateDeps(form, key, depKeys) {
|
|
854
|
+
const deps = fieldValidateDeps.get(form);
|
|
855
|
+
if (!deps) return;
|
|
856
|
+
for (const depKey of depKeys) {
|
|
857
|
+
const dependents = deps.get(depKey);
|
|
858
|
+
if (!dependents?.delete(key)) continue;
|
|
859
|
+
if (!dependents.size) deps.delete(depKey);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
function revalidateDependentsOnChange(form, path, mode) {
|
|
863
|
+
const dependents = fieldValidateDeps.get(form)?.get(path.key);
|
|
864
|
+
if (!dependents?.size) return;
|
|
865
|
+
for (const dependent of dependents) {
|
|
866
|
+
if (dependent === path.key) continue;
|
|
867
|
+
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || form.reValidateMode === "onChange" && form.errors.has(dependent)) {
|
|
868
|
+
form.validators.get(dependent)?.();
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
function validationError(form) {
|
|
873
|
+
const error = new Error(getFirstError(form));
|
|
874
|
+
error.errors = getErrors(form);
|
|
875
|
+
return error;
|
|
876
|
+
}
|
|
797
877
|
async function ensureValidate(form) {
|
|
798
878
|
form.validators.forEach((validator) => validator());
|
|
799
879
|
await waitUntil(
|
|
@@ -802,11 +882,11 @@
|
|
|
802
882
|
() => fieldsSettled(form),
|
|
803
883
|
() => hasErrors(form)
|
|
804
884
|
).catch(() => {
|
|
805
|
-
throw
|
|
885
|
+
throw validationError(form);
|
|
806
886
|
});
|
|
807
887
|
if (form.validate) {
|
|
808
888
|
await runFormValidate(form);
|
|
809
|
-
if (hasErrors(form)) throw
|
|
889
|
+
if (hasErrors(form)) throw validationError(form);
|
|
810
890
|
}
|
|
811
891
|
}
|
|
812
892
|
async function validate(form) {
|
|
@@ -1216,6 +1296,7 @@
|
|
|
1216
1296
|
if (seededRef.current === null)
|
|
1217
1297
|
seededRef.current = { done: false, source: void 0 };
|
|
1218
1298
|
React.useEffect(() => {
|
|
1299
|
+
if (initialValues === void 0) return;
|
|
1219
1300
|
const seeded = seededRef.current;
|
|
1220
1301
|
if (seeded.done && (seeded.source === initialValues || isEqual(seeded.source, initialValues))) {
|
|
1221
1302
|
return;
|
|
@@ -1512,6 +1593,7 @@
|
|
|
1512
1593
|
validate,
|
|
1513
1594
|
rules,
|
|
1514
1595
|
validateDebounce,
|
|
1596
|
+
validateDeps,
|
|
1515
1597
|
delayError,
|
|
1516
1598
|
disabled,
|
|
1517
1599
|
mode: modeOption
|
|
@@ -1520,6 +1602,17 @@
|
|
|
1520
1602
|
const form = f1 || contextForm;
|
|
1521
1603
|
if (!form) throw new Error("no form provided");
|
|
1522
1604
|
const path = usePath(name);
|
|
1605
|
+
const seededRef = React.useRef(false);
|
|
1606
|
+
const seeded = initialValue !== void 0 && getValueByPath(form, path) === void 0;
|
|
1607
|
+
if (seeded) {
|
|
1608
|
+
seedValueByPath(form, path, initialValue);
|
|
1609
|
+
seededRef.current = true;
|
|
1610
|
+
}
|
|
1611
|
+
React.useEffect(() => {
|
|
1612
|
+
if (!seededRef.current) return;
|
|
1613
|
+
seededRef.current = false;
|
|
1614
|
+
emitChangeByPath(form, path);
|
|
1615
|
+
});
|
|
1523
1616
|
const validator = useValidate(
|
|
1524
1617
|
combineRulesAndValidate(rules, validate),
|
|
1525
1618
|
path,
|
|
@@ -1535,17 +1628,12 @@
|
|
|
1535
1628
|
const value = useValueByPath(form, path);
|
|
1536
1629
|
const formDisabled = useWatch(form.emitter, "disabled", () => form.disabled);
|
|
1537
1630
|
const mode = modeOption ?? form.mode;
|
|
1538
|
-
React.useEffect(() => {
|
|
1539
|
-
if (initialValue === void 0) return;
|
|
1540
|
-
if (getValueByPath(form, path) === void 0) {
|
|
1541
|
-
setValueByPath(form, path, initialValue);
|
|
1542
|
-
}
|
|
1543
|
-
}, [form, path, initialValue]);
|
|
1544
1631
|
const onChange = useStageFn((v) => {
|
|
1545
1632
|
setValueByPath(form, path, v);
|
|
1546
1633
|
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || liveErrors.length > 0 && form.reValidateMode === "onChange")
|
|
1547
1634
|
validator();
|
|
1548
1635
|
revalidateFormOnChange(form, path, mode);
|
|
1636
|
+
revalidateDependentsOnChange(form, path, mode);
|
|
1549
1637
|
});
|
|
1550
1638
|
React.useEffect(() => {
|
|
1551
1639
|
form.changeHandlers.set(path.key, onChange);
|
|
@@ -1554,6 +1642,13 @@
|
|
|
1554
1642
|
form.changeHandlers.delete(path.key);
|
|
1555
1643
|
};
|
|
1556
1644
|
}, [form, path.key, onChange]);
|
|
1645
|
+
const depsKey = validateDeps?.length ? validateDeps.join("\n") : void 0;
|
|
1646
|
+
React.useEffect(() => {
|
|
1647
|
+
if (!depsKey) return;
|
|
1648
|
+
const depKeys = validateDeps.map((dep) => create$1(dep).key);
|
|
1649
|
+
registerFieldValidateDeps(form, path.key, depKeys);
|
|
1650
|
+
return () => unregisterFieldValidateDeps(form, path.key, depKeys);
|
|
1651
|
+
}, [form, path.key, depsKey]);
|
|
1557
1652
|
const onBlur = useStageFn(() => {
|
|
1558
1653
|
setTouchedByPath(form, path);
|
|
1559
1654
|
if (mode === "onBlur" || mode === "onTouched" || mode === "all" || liveErrors.length > 0 && form.reValidateMode === "onBlur")
|
|
@@ -1583,9 +1678,11 @@
|
|
|
1583
1678
|
return useFieldCore(options, FormContext);
|
|
1584
1679
|
}
|
|
1585
1680
|
|
|
1586
|
-
|
|
1587
|
-
function generateId() {
|
|
1588
|
-
|
|
1681
|
+
const idCounters = /* @__PURE__ */ new WeakMap();
|
|
1682
|
+
function generateId(form) {
|
|
1683
|
+
const next = (idCounters.get(form) ?? 0) + 1;
|
|
1684
|
+
idCounters.set(form, next);
|
|
1685
|
+
return `_${next}`;
|
|
1589
1686
|
}
|
|
1590
1687
|
const arrayIdsRegistry = /* @__PURE__ */ new WeakMap();
|
|
1591
1688
|
function getArrayIds(form, key) {
|
|
@@ -1621,13 +1718,13 @@
|
|
|
1621
1718
|
const computeFields = React.useCallback(() => {
|
|
1622
1719
|
const arr = getArray();
|
|
1623
1720
|
while (idsRef.current.length < arr.length) {
|
|
1624
|
-
idsRef.current.push(generateId());
|
|
1721
|
+
idsRef.current.push(generateId(form));
|
|
1625
1722
|
}
|
|
1626
1723
|
while (idsRef.current.length > arr.length) {
|
|
1627
1724
|
idsRef.current.pop();
|
|
1628
1725
|
}
|
|
1629
1726
|
return idsRef.current.map((id, index) => ({ id, index }));
|
|
1630
|
-
}, [getArray]);
|
|
1727
|
+
}, [getArray, form]);
|
|
1631
1728
|
const [fields, syncFields] = React.useReducer(
|
|
1632
1729
|
computeFields,
|
|
1633
1730
|
void 0,
|
|
@@ -1647,17 +1744,17 @@
|
|
|
1647
1744
|
}, [form, path.key]);
|
|
1648
1745
|
const append = useStageFn((value) => {
|
|
1649
1746
|
const arr = getArray();
|
|
1650
|
-
idsRef.current.push(generateId());
|
|
1747
|
+
idsRef.current.push(generateId(form));
|
|
1651
1748
|
setArray([...arr, value]);
|
|
1652
1749
|
});
|
|
1653
1750
|
const prepend = useStageFn((value) => {
|
|
1654
1751
|
const arr = getArray();
|
|
1655
|
-
idsRef.current.unshift(generateId());
|
|
1752
|
+
idsRef.current.unshift(generateId(form));
|
|
1656
1753
|
setArray([value, ...arr]);
|
|
1657
1754
|
});
|
|
1658
1755
|
const insert = useStageFn((index, value) => {
|
|
1659
1756
|
const arr = getArray();
|
|
1660
|
-
idsRef.current.splice(index, 0, generateId());
|
|
1757
|
+
idsRef.current.splice(index, 0, generateId(form));
|
|
1661
1758
|
const newArr = [...arr.slice(0, index), value, ...arr.slice(index)];
|
|
1662
1759
|
setArray(newArr);
|
|
1663
1760
|
});
|
|
@@ -1687,7 +1784,7 @@
|
|
|
1687
1784
|
setArray(newArr);
|
|
1688
1785
|
});
|
|
1689
1786
|
const replace = useStageFn((values) => {
|
|
1690
|
-
idsRef.current = values.map(() => generateId());
|
|
1787
|
+
idsRef.current = values.map(() => generateId(form));
|
|
1691
1788
|
setArray([...values]);
|
|
1692
1789
|
});
|
|
1693
1790
|
const update = useStageFn((index, value) => {
|
|
@@ -2074,6 +2171,7 @@
|
|
|
2074
2171
|
exports.clearErrors = clearErrors;
|
|
2075
2172
|
exports.createForm = create;
|
|
2076
2173
|
exports.createFormContext = createFormContext;
|
|
2174
|
+
exports.emitChangeByPath = emitChangeByPath;
|
|
2077
2175
|
exports.ensureValidate = ensureValidate;
|
|
2078
2176
|
exports.fieldErrorId = fieldErrorId;
|
|
2079
2177
|
exports.getDirtyFields = getDirtyFields;
|
|
@@ -2095,11 +2193,14 @@
|
|
|
2095
2193
|
exports.incrementSubmitCount = incrementSubmitCount;
|
|
2096
2194
|
exports.isDirty = isDirty;
|
|
2097
2195
|
exports.isTouched = isTouched;
|
|
2196
|
+
exports.registerFieldValidateDeps = registerFieldValidateDeps;
|
|
2098
2197
|
exports.removeField = removeField;
|
|
2099
2198
|
exports.removeFieldByPath = removeFieldByPath;
|
|
2100
2199
|
exports.reset = reset;
|
|
2101
2200
|
exports.resetField = resetField;
|
|
2201
|
+
exports.revalidateDependentsOnChange = revalidateDependentsOnChange;
|
|
2102
2202
|
exports.revalidateFormOnChange = revalidateFormOnChange;
|
|
2203
|
+
exports.seedValueByPath = seedValueByPath;
|
|
2103
2204
|
exports.setDisabled = setDisabled;
|
|
2104
2205
|
exports.setError = setError;
|
|
2105
2206
|
exports.setErrorByPath = setErrorByPath;
|
|
@@ -2115,6 +2216,7 @@
|
|
|
2115
2216
|
exports.setValueByPath = setValueByPath;
|
|
2116
2217
|
exports.subscribe = subscribe;
|
|
2117
2218
|
exports.trigger = trigger;
|
|
2219
|
+
exports.unregisterFieldValidateDeps = unregisterFieldValidateDeps;
|
|
2118
2220
|
exports.unsetValidatingByPath = unsetValidatingByPath;
|
|
2119
2221
|
exports.useCanSubmit = useCanSubmit;
|
|
2120
2222
|
exports.useCheckboxGroupContext = useCheckboxGroupContext;
|