react-f0rm 0.8.0 → 0.10.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 +90 -4
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.mjs +1 -1
- package/dist/{form-B2pyaLdK.d.ts → form-BNqHYba-.d.ts} +72 -9
- package/dist/form-BQsb2CuG.mjs +2 -0
- package/dist/form-BQsb2CuG.mjs.map +1 -0
- package/dist/form-DZK8HgZ7.cjs.js +2 -0
- package/dist/form-DZK8HgZ7.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 +3 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +102 -14
- 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-BhOEz8BS.d.ts → validate-CbteZ-Jb.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/form-DnM4ONxf.cjs.js +0 -2
- package/dist/form-DnM4ONxf.cjs.js.map +0 -1
- package/dist/form-O5yKsVPM.mjs +0 -2
- package/dist/form-O5yKsVPM.mjs.map +0 -1
package/dist/index.umd.js
CHANGED
|
@@ -222,6 +222,7 @@
|
|
|
222
222
|
mode: options?.mode ?? "onSubmit",
|
|
223
223
|
reValidateMode: options?.reValidateMode ?? "onChange",
|
|
224
224
|
disabled: options?.disabled ?? false,
|
|
225
|
+
validateDeps: options?.validateDeps ? new Set(options.validateDeps.map((dep) => create$1(dep).key)) : void 0,
|
|
225
226
|
initialValues: options?.initialValues ?? {},
|
|
226
227
|
values: /* @__PURE__ */ new Map(),
|
|
227
228
|
deleted: /* @__PURE__ */ new Set(),
|
|
@@ -263,18 +264,21 @@
|
|
|
263
264
|
const { emitter, values, deleted } = form;
|
|
264
265
|
values.set(path.key, value);
|
|
265
266
|
reviveBranch(deleted, path);
|
|
267
|
+
pruneDirtyBaselines(form, path);
|
|
268
|
+
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
266
269
|
bumpDirtyVersion(form);
|
|
267
270
|
if (options?.shouldTouch) setTouchedByPath(form, path);
|
|
268
271
|
if (options?.shouldValidate) form.validators.get(path.key)?.();
|
|
269
272
|
emit(emitter, "change", path);
|
|
270
273
|
}
|
|
271
|
-
function changeValue(form, name, value) {
|
|
272
|
-
changeValueByPath(form, create$1(name), value);
|
|
274
|
+
function changeValue(form, name, value, options) {
|
|
275
|
+
changeValueByPath(form, create$1(name), value, options);
|
|
273
276
|
}
|
|
274
|
-
function changeValueByPath(form, path, value) {
|
|
277
|
+
function changeValueByPath(form, path, value, options) {
|
|
278
|
+
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
275
279
|
const change = form.changeHandlers.get(path.key);
|
|
276
280
|
if (change) change(value);
|
|
277
|
-
else setValueByPath(form, path, value);
|
|
281
|
+
else setValueByPath(form, path, value, options);
|
|
278
282
|
}
|
|
279
283
|
function getError(form, name) {
|
|
280
284
|
return getErrorByPath(form, create$1(name));
|
|
@@ -302,13 +306,15 @@
|
|
|
302
306
|
}
|
|
303
307
|
function getFieldState(form, name) {
|
|
304
308
|
const path = create$1(name);
|
|
305
|
-
const {
|
|
309
|
+
const { values, touched, validating } = form;
|
|
306
310
|
const live = values.get(path.key);
|
|
307
311
|
return {
|
|
308
312
|
value: getValueByPath(form, path),
|
|
309
313
|
error: getErrorByPath(form, path),
|
|
310
314
|
errors: getFieldErrorsByPath(form, path),
|
|
311
|
-
|
|
315
|
+
// Same rule as getDirtyFields, committed baselines included: the field
|
|
316
|
+
// is dirty while its live value differs from its effective baseline.
|
|
317
|
+
isDirty: values.has(path.key) && getDirtyBaseline(form, path.key, path.value) !== live,
|
|
312
318
|
isTouched: touched.has(path.key),
|
|
313
319
|
isValidating: validating.has(path.key)
|
|
314
320
|
};
|
|
@@ -391,11 +397,39 @@
|
|
|
391
397
|
});
|
|
392
398
|
return dirty;
|
|
393
399
|
}
|
|
394
|
-
function forEachDirtyField(
|
|
395
|
-
for (const [key, value] of values) {
|
|
400
|
+
function forEachDirtyField(form, fn) {
|
|
401
|
+
for (const [key, value] of form.values) {
|
|
396
402
|
const path = JSON.parse(key);
|
|
397
|
-
if (
|
|
403
|
+
if (getDirtyBaseline(form, key, path) !== value) fn(path.join("."));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const dirtyBaselines = /* @__PURE__ */ new WeakMap();
|
|
407
|
+
function getDirtyBaseline(form, key, segments) {
|
|
408
|
+
const baselines = dirtyBaselines.get(form);
|
|
409
|
+
if (baselines?.has(key)) return baselines.get(key);
|
|
410
|
+
return get(form.initialValues, segments);
|
|
411
|
+
}
|
|
412
|
+
function setDirtyBaseline(form, { key }, value) {
|
|
413
|
+
let baselines = dirtyBaselines.get(form);
|
|
414
|
+
if (!baselines) {
|
|
415
|
+
baselines = /* @__PURE__ */ new Map();
|
|
416
|
+
dirtyBaselines.set(form, baselines);
|
|
398
417
|
}
|
|
418
|
+
baselines.set(key, value);
|
|
419
|
+
}
|
|
420
|
+
function pruneDirtyBaselines(form, { key }) {
|
|
421
|
+
const baselines = dirtyBaselines.get(form);
|
|
422
|
+
if (!baselines?.size) return;
|
|
423
|
+
const stem = `${key.slice(0, -1)},`;
|
|
424
|
+
for (const baselineKey of baselines.keys()) {
|
|
425
|
+
if (baselineKey.startsWith(stem)) baselines.delete(baselineKey);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function clearDirtyBaselines(form, key) {
|
|
429
|
+
const baselines = dirtyBaselines.get(form);
|
|
430
|
+
if (!baselines) return;
|
|
431
|
+
if (key === void 0) baselines.clear();
|
|
432
|
+
else baselines.delete(key);
|
|
399
433
|
}
|
|
400
434
|
const dirtyFieldsCaches = /* @__PURE__ */ new WeakMap();
|
|
401
435
|
function bumpDirtyVersion(form) {
|
|
@@ -444,6 +478,7 @@
|
|
|
444
478
|
touched.delete(key);
|
|
445
479
|
errors.delete(key);
|
|
446
480
|
validating.delete(key);
|
|
481
|
+
clearDirtyBaselines(form, key);
|
|
447
482
|
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
448
483
|
bumpDirtyVersion(form);
|
|
449
484
|
emit(emitter, "change");
|
|
@@ -477,6 +512,7 @@
|
|
|
477
512
|
form.parsedValues = void 0;
|
|
478
513
|
form.values.clear();
|
|
479
514
|
form.deleted.clear();
|
|
515
|
+
clearDirtyBaselines(form);
|
|
480
516
|
bumpDirtyVersion(form);
|
|
481
517
|
emit(form.emitter, "change");
|
|
482
518
|
}
|
|
@@ -491,6 +527,7 @@
|
|
|
491
527
|
const { emitter, touched, values, deleted, validating } = form;
|
|
492
528
|
values.clear();
|
|
493
529
|
deleted.clear();
|
|
530
|
+
clearDirtyBaselines(form);
|
|
494
531
|
if (!options?.keepTouched) touched.clear();
|
|
495
532
|
validating.clear();
|
|
496
533
|
if (!options?.keepIsSubmitting) form.isSubmitting = false;
|
|
@@ -512,6 +549,7 @@
|
|
|
512
549
|
const path = create$1(name);
|
|
513
550
|
const { emitter, values, touched, errors, deleted } = form;
|
|
514
551
|
values.delete(path.key);
|
|
552
|
+
clearDirtyBaselines(form, path.key);
|
|
515
553
|
if (form.parsedValues !== void 0) {
|
|
516
554
|
form.parsedValues = unset(form.parsedValues, path.value);
|
|
517
555
|
const initial = get(form.initialValues, path.value);
|
|
@@ -557,34 +595,75 @@
|
|
|
557
595
|
function isFieldError(value) {
|
|
558
596
|
return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.message === "string";
|
|
559
597
|
}
|
|
560
|
-
function setFormErrors(form, result, segments = []) {
|
|
598
|
+
function setFormErrors(form, result, segments = [], footprint) {
|
|
561
599
|
Object.entries(result).forEach(([key, value]) => {
|
|
562
600
|
const path = [...segments, ...normalizePath(key)];
|
|
563
601
|
if (typeof value === "string") {
|
|
564
|
-
if (value)
|
|
602
|
+
if (value) {
|
|
603
|
+
setError(form, path, value);
|
|
604
|
+
recordFootprint(form, path, footprint);
|
|
605
|
+
}
|
|
565
606
|
} else if (Array.isArray(value)) {
|
|
566
607
|
setError(form, path, value);
|
|
608
|
+
recordFootprint(form, path, footprint);
|
|
567
609
|
} else if (isFieldError(value)) {
|
|
568
610
|
setError(form, path, value);
|
|
611
|
+
recordFootprint(form, path, footprint);
|
|
569
612
|
} else if (value && typeof value === "object") {
|
|
570
|
-
setFormErrors(form, value, path);
|
|
613
|
+
setFormErrors(form, value, path, footprint);
|
|
571
614
|
}
|
|
572
615
|
});
|
|
573
616
|
}
|
|
617
|
+
function recordFootprint(form, segments, footprint) {
|
|
618
|
+
if (!footprint) return;
|
|
619
|
+
const path = create$1(segments);
|
|
620
|
+
const stored = form.errors.get(path.key);
|
|
621
|
+
if (stored) footprint.set(path.key, stored);
|
|
622
|
+
}
|
|
574
623
|
function setParsedValues(form, values) {
|
|
575
624
|
if (values === void 0 || values === form.parsedValues) return;
|
|
576
625
|
form.parsedValues = values;
|
|
577
626
|
emit(form.emitter, "change");
|
|
578
627
|
}
|
|
579
628
|
function applyValidateResult(form, result) {
|
|
629
|
+
const footprint = form.validateDeps ? getFormErrorFootprint(form) : void 0;
|
|
630
|
+
if (footprint) {
|
|
631
|
+
clearFormValidateErrors(form, footprint);
|
|
632
|
+
footprint.clear();
|
|
633
|
+
}
|
|
580
634
|
if (!result) return;
|
|
581
635
|
if (typeof result === "object" && VALIDATION_OUTCOME in result) {
|
|
582
636
|
const outcome = result;
|
|
583
|
-
if (outcome.errors) setFormErrors(form, outcome.errors);
|
|
637
|
+
if (outcome.errors) setFormErrors(form, outcome.errors, [], footprint);
|
|
584
638
|
setParsedValues(form, outcome.values);
|
|
585
639
|
return;
|
|
586
640
|
}
|
|
587
|
-
setFormErrors(form, result);
|
|
641
|
+
setFormErrors(form, result, [], footprint);
|
|
642
|
+
}
|
|
643
|
+
const formErrorFootprints = /* @__PURE__ */ new WeakMap();
|
|
644
|
+
function getFormErrorFootprint(form) {
|
|
645
|
+
let footprint = formErrorFootprints.get(form);
|
|
646
|
+
if (!footprint) {
|
|
647
|
+
footprint = /* @__PURE__ */ new Map();
|
|
648
|
+
formErrorFootprints.set(form, footprint);
|
|
649
|
+
}
|
|
650
|
+
return footprint;
|
|
651
|
+
}
|
|
652
|
+
function hasFormValidateErrors(form) {
|
|
653
|
+
const footprint = formErrorFootprints.get(form);
|
|
654
|
+
if (!footprint) return false;
|
|
655
|
+
for (const [key, written] of footprint) {
|
|
656
|
+
if (form.errors.get(key) === written) return true;
|
|
657
|
+
}
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
function clearFormValidateErrors(form, footprint) {
|
|
661
|
+
for (const [key, written] of footprint) {
|
|
662
|
+
const stored = form.errors.get(key);
|
|
663
|
+
if (stored !== written) continue;
|
|
664
|
+
form.errors.delete(key);
|
|
665
|
+
emit(form.emitter, "errors", create$1(JSON.parse(key)));
|
|
666
|
+
}
|
|
588
667
|
}
|
|
589
668
|
const FORM_VALIDATING_KEY = "__form_validate__";
|
|
590
669
|
function fieldsSettled(form) {
|
|
@@ -678,6 +757,13 @@
|
|
|
678
757
|
else waiter.reject(outcome);
|
|
679
758
|
}
|
|
680
759
|
}
|
|
760
|
+
function revalidateFormOnChange(form, path, mode) {
|
|
761
|
+
if (!form.validateDeps?.has(path.key) || !form.validate) return;
|
|
762
|
+
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || form.reValidateMode === "onChange" && hasFormValidateErrors(form)) {
|
|
763
|
+
runFormValidate(form).catch(() => {
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
}
|
|
681
767
|
async function ensureValidate(form) {
|
|
682
768
|
form.validators.forEach((validator) => validator());
|
|
683
769
|
await waitUntil(
|
|
@@ -1429,6 +1515,7 @@
|
|
|
1429
1515
|
setValueByPath(form, path, v);
|
|
1430
1516
|
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || liveErrors.length > 0 && form.reValidateMode === "onChange")
|
|
1431
1517
|
validator();
|
|
1518
|
+
revalidateFormOnChange(form, path, mode);
|
|
1432
1519
|
});
|
|
1433
1520
|
React.useEffect(() => {
|
|
1434
1521
|
form.changeHandlers.set(path.key, onChange);
|
|
@@ -1901,6 +1988,7 @@
|
|
|
1901
1988
|
exports.removeFieldByPath = removeFieldByPath;
|
|
1902
1989
|
exports.reset = reset;
|
|
1903
1990
|
exports.resetField = resetField;
|
|
1991
|
+
exports.revalidateFormOnChange = revalidateFormOnChange;
|
|
1904
1992
|
exports.setDisabled = setDisabled;
|
|
1905
1993
|
exports.setError = setError;
|
|
1906
1994
|
exports.setErrorByPath = setErrorByPath;
|