react-hook-form 7.29.0 → 7.31.1

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.
@@ -18,9 +18,9 @@ var getEventValue = (event) => isObject(event) && event.target
18
18
  : event.target.value
19
19
  : event;
20
20
 
21
- var getNodeParentName = (name) => name.substring(0, name.search(/.\d/)) || name;
21
+ var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
22
22
 
23
- var isNameInFieldArray = (names, name) => [...names].some((current) => getNodeParentName(name) === current);
23
+ var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
24
24
 
25
25
  var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
26
26
 
@@ -416,7 +416,20 @@ function useController(props) {
416
416
  }, [name, control._fields]),
417
417
  },
418
418
  formState,
419
- fieldState: control.getFieldState(name, formState),
419
+ fieldState: Object.defineProperties({}, {
420
+ invalid: {
421
+ get: () => !!get(formState.errors, name),
422
+ },
423
+ isDirty: {
424
+ get: () => !!get(formState.dirtyFields, name),
425
+ },
426
+ isTouched: {
427
+ get: () => !!get(formState.touchedFields, name),
428
+ },
429
+ error: {
430
+ get: () => get(formState.errors, name),
431
+ },
432
+ }),
420
433
  };
421
434
  }
422
435
 
@@ -554,14 +567,16 @@ function cloneObject(data) {
554
567
  else if (data instanceof Set) {
555
568
  copy = new Set(data);
556
569
  }
570
+ else if (globalThis.Blob && data instanceof Blob) {
571
+ copy = data;
572
+ }
573
+ else if (globalThis.FileList && data instanceof FileList) {
574
+ copy = data;
575
+ }
557
576
  else if (isArray || isObject(data)) {
558
577
  copy = isArray ? [] : {};
559
578
  for (const key in data) {
560
- if (isFunction(data[key])) {
561
- copy = data;
562
- break;
563
- }
564
- copy[key] = cloneObject(data[key]);
579
+ copy[key] = isFunction(data[key]) ? data[key] : cloneObject(data[key]);
565
580
  }
566
581
  }
567
582
  else {
@@ -612,6 +627,45 @@ var swapArrayAt = (data, indexA, indexB) => {
612
627
  data[indexA] = [data[indexB], (data[indexB] = data[indexA])][0];
613
628
  };
614
629
 
630
+ function baseGet(object, updatePath) {
631
+ const length = updatePath.slice(0, -1).length;
632
+ let index = 0;
633
+ while (index < length) {
634
+ object = isUndefined(object) ? index++ : object[updatePath[index++]];
635
+ }
636
+ return object;
637
+ }
638
+ function unset(object, path) {
639
+ const updatePath = isKey(path) ? [path] : stringToPath(path);
640
+ const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
641
+ const key = updatePath[updatePath.length - 1];
642
+ let previousObjRef;
643
+ if (childObject) {
644
+ delete childObject[key];
645
+ }
646
+ for (let k = 0; k < updatePath.slice(0, -1).length; k++) {
647
+ let index = -1;
648
+ let objectRef;
649
+ const currentPaths = updatePath.slice(0, -(k + 1));
650
+ const currentPathsLength = currentPaths.length - 1;
651
+ if (k > 0) {
652
+ previousObjRef = object;
653
+ }
654
+ while (++index < currentPaths.length) {
655
+ const item = currentPaths[index];
656
+ objectRef = objectRef ? objectRef[item] : object[item];
657
+ if (currentPathsLength === index &&
658
+ ((isObject(objectRef) && isEmptyObject(objectRef)) ||
659
+ (Array.isArray(objectRef) &&
660
+ !objectRef.filter((data) => !isUndefined(data)).length))) {
661
+ previousObjRef ? delete previousObjRef[item] : delete object[item];
662
+ }
663
+ previousObjRef = objectRef;
664
+ }
665
+ }
666
+ return object;
667
+ }
668
+
615
669
  var updateAt = (fieldValues, index, value) => {
616
670
  fieldValues[index] = value;
617
671
  return fieldValues;
@@ -769,8 +823,11 @@ function useFieldArray(props) {
769
823
  if (_actioned.current) {
770
824
  control._executeSchema([name]).then((result) => {
771
825
  const error = get(result.errors, name);
772
- if (error && error.type && !get(control._formState.errors, name)) {
773
- set(control._formState.errors, name, error);
826
+ const existingError = get(control._formState.errors, name);
827
+ if (existingError ? !error && existingError.type : error && error.type) {
828
+ error
829
+ ? set(control._formState.errors, name, error)
830
+ : unset(control._formState.errors, name);
774
831
  control._subjects.state.next({
775
832
  errors: control._formState.errors,
776
833
  });
@@ -896,45 +953,6 @@ var isWeb = typeof window !== 'undefined' &&
896
953
 
897
954
  var live = (ref) => isHTMLElement(ref) && ref.isConnected;
898
955
 
899
- function baseGet(object, updatePath) {
900
- const length = updatePath.slice(0, -1).length;
901
- let index = 0;
902
- while (index < length) {
903
- object = isUndefined(object) ? index++ : object[updatePath[index++]];
904
- }
905
- return object;
906
- }
907
- function unset(object, path) {
908
- const updatePath = isKey(path) ? [path] : stringToPath(path);
909
- const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
910
- const key = updatePath[updatePath.length - 1];
911
- let previousObjRef;
912
- if (childObject) {
913
- delete childObject[key];
914
- }
915
- for (let k = 0; k < updatePath.slice(0, -1).length; k++) {
916
- let index = -1;
917
- let objectRef;
918
- const currentPaths = updatePath.slice(0, -(k + 1));
919
- const currentPathsLength = currentPaths.length - 1;
920
- if (k > 0) {
921
- previousObjRef = object;
922
- }
923
- while (++index < currentPaths.length) {
924
- const item = currentPaths[index];
925
- objectRef = objectRef ? objectRef[item] : object[item];
926
- if (currentPathsLength === index &&
927
- ((isObject(objectRef) && isEmptyObject(objectRef)) ||
928
- (Array.isArray(objectRef) &&
929
- !objectRef.filter((data) => !isUndefined(data)).length))) {
930
- previousObjRef ? delete previousObjRef[item] : delete object[item];
931
- }
932
- previousObjRef = objectRef;
933
- }
934
- }
935
- return object;
936
- }
937
-
938
956
  function markFieldsDirty(data, fields = {}) {
939
957
  const isParentNodeArray = Array.isArray(data);
940
958
  if (isObject(data) || isParentNodeArray) {
@@ -1882,7 +1900,13 @@ function createFormControl(props = {}) {
1882
1900
  ...field._f,
1883
1901
  ...(radioOrCheckbox
1884
1902
  ? {
1885
- refs: [...refs.filter(live), fieldRef],
1903
+ refs: [
1904
+ ...refs.filter(live),
1905
+ fieldRef,
1906
+ ...(!!Array.isArray(get(_defaultValues, name))
1907
+ ? [{}]
1908
+ : []),
1909
+ ],
1886
1910
  ref: { type: fieldRef.type, name },
1887
1911
  }
1888
1912
  : { ref: fieldRef }),
@@ -1921,8 +1945,7 @@ function createFormControl(props = {}) {
1921
1945
  else {
1922
1946
  await executeBuildInValidation(_fields);
1923
1947
  }
1924
- if (isEmptyObject(_formState.errors) &&
1925
- Object.keys(_formState.errors).every((name) => get(fieldValues, name))) {
1948
+ if (isEmptyObject(_formState.errors)) {
1926
1949
  _subjects.state.next({
1927
1950
  errors: {},
1928
1951
  isSubmitting: true,
@@ -1987,28 +2010,37 @@ function createFormControl(props = {}) {
1987
2010
  _defaultValues = updatedValues;
1988
2011
  }
1989
2012
  if (!keepStateOptions.keepValues) {
1990
- if (isWeb && isUndefined(formValues)) {
1991
- for (const name of _names.mount) {
1992
- const field = get(_fields, name);
1993
- if (field && field._f) {
1994
- const fieldReference = Array.isArray(field._f.refs)
1995
- ? field._f.refs[0]
1996
- : field._f.ref;
1997
- try {
1998
- isHTMLElement(fieldReference) &&
1999
- fieldReference.closest('form').reset();
2000
- break;
2013
+ if (keepStateOptions.keepDirtyValues) {
2014
+ for (const fieldName of _names.mount) {
2015
+ get(_formState.dirtyFields, fieldName)
2016
+ ? set(values, fieldName, get(_formValues, fieldName))
2017
+ : setValue(fieldName, get(values, fieldName));
2018
+ }
2019
+ }
2020
+ else {
2021
+ if (isWeb && isUndefined(formValues)) {
2022
+ for (const name of _names.mount) {
2023
+ const field = get(_fields, name);
2024
+ if (field && field._f) {
2025
+ const fieldReference = Array.isArray(field._f.refs)
2026
+ ? field._f.refs[0]
2027
+ : field._f.ref;
2028
+ try {
2029
+ isHTMLElement(fieldReference) &&
2030
+ fieldReference.closest('form').reset();
2031
+ break;
2032
+ }
2033
+ catch (_a) { }
2001
2034
  }
2002
- catch (_a) { }
2003
2035
  }
2004
2036
  }
2037
+ _fields = {};
2005
2038
  }
2006
2039
  _formValues = props.shouldUnregister
2007
2040
  ? keepStateOptions.keepDefaultValues
2008
2041
  ? cloneObject(_defaultValues)
2009
2042
  : {}
2010
2043
  : cloneUpdatedValues;
2011
- _fields = {};
2012
2044
  _subjects.array.next({
2013
2045
  values,
2014
2046
  });
@@ -2031,22 +2063,16 @@ function createFormControl(props = {}) {
2031
2063
  submitCount: keepStateOptions.keepSubmitCount
2032
2064
  ? _formState.submitCount
2033
2065
  : 0,
2034
- isDirty: keepStateOptions.keepDirty
2066
+ isDirty: keepStateOptions.keepDirty || keepStateOptions.keepDirtyValues
2035
2067
  ? _formState.isDirty
2036
- : keepStateOptions.keepDefaultValues
2037
- ? !deepEqual(formValues, _defaultValues)
2038
- : false,
2039
- isSubmitted: keepStateOptions.keepIsSubmitted
2040
- ? _formState.isSubmitted
2041
- : false,
2042
- dirtyFields: keepStateOptions.keepDirty
2068
+ : !!(keepStateOptions.keepDefaultValues &&
2069
+ !deepEqual(formValues, _defaultValues)),
2070
+ isSubmitted: !!keepStateOptions.keepIsSubmitted,
2071
+ dirtyFields: keepStateOptions.keepDirty || keepStateOptions.keepDirtyValues
2043
2072
  ? _formState.dirtyFields
2044
- : (keepStateOptions.keepDefaultValues && formValues
2045
- ? Object.entries(formValues).reduce((previous, [key, value]) => ({
2046
- ...previous,
2047
- [key]: value !== get(_defaultValues, key),
2048
- }), {})
2049
- : {}),
2073
+ : keepStateOptions.keepDefaultValues && formValues
2074
+ ? getDirtyFields(_defaultValues, formValues)
2075
+ : {},
2050
2076
  touchedFields: keepStateOptions.keepTouched
2051
2077
  ? _formState.touchedFields
2052
2078
  : {},