react-hook-form 7.20.0 → 7.20.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -12,7 +12,7 @@ var isObject = (value) => !isNullOrUndefined(value) &&
12
12
  isObjectType(value) &&
13
13
  !isDateObject(value);
14
14
 
15
- var getControllerValue = (event) => isObject(event) && event.target
15
+ var getEventValue = (event) => isObject(event) && event.target
16
16
  ? isCheckBoxInput(event.target)
17
17
  ? event.target.checked
18
18
  : event.target.value
@@ -155,7 +155,7 @@ function useFormState(props) {
155
155
 
156
156
  var isString = (value) => typeof value === 'string';
157
157
 
158
- function generateWatchOutput(names, _names, formValues, isGlobal) {
158
+ var generateWatchOutput = (names, _names, formValues, isGlobal) => {
159
159
  const isArray = Array.isArray(names);
160
160
  if (isString(names)) {
161
161
  isGlobal && _names.watch.add(names);
@@ -167,7 +167,18 @@ function generateWatchOutput(names, _names, formValues, isGlobal) {
167
167
  }
168
168
  isGlobal && (_names.watchAll = true);
169
169
  return formValues;
170
- }
170
+ };
171
+
172
+ var isFunction = (value) => typeof value === 'function';
173
+
174
+ var objectHasFunction = (data) => {
175
+ for (const key in data) {
176
+ if (isFunction(data[key])) {
177
+ return true;
178
+ }
179
+ }
180
+ return false;
181
+ };
171
182
 
172
183
  function useWatch(props) {
173
184
  const methods = useFormContext();
@@ -180,7 +191,8 @@ function useWatch(props) {
180
191
  callback: (formState) => {
181
192
  if (shouldSubscribeByName(_name.current, formState.name, exact)) {
182
193
  const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
183
- updateValue(isUndefined(_name.current)
194
+ updateValue(isUndefined(_name.current) ||
195
+ (isObject(fieldValues) && !objectHasFunction(fieldValues))
184
196
  ? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
185
197
  ? [...fieldValues]
186
198
  : fieldValues);
@@ -238,7 +250,7 @@ function useController(props) {
238
250
  onChange: (event) => {
239
251
  registerProps.onChange({
240
252
  target: {
241
- value: getControllerValue(event),
253
+ value: getEventValue(event),
242
254
  name: name,
243
255
  },
244
256
  type: EVENTS.CHANGE,
@@ -436,44 +448,44 @@ const useFieldArray = (props) => {
436
448
  const append$1 = (value, options) => {
437
449
  const appendValue = convertToArrayPayload(value);
438
450
  const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(appendValue, keyName));
451
+ setFields(updatedFieldArrayValuesWithKey);
439
452
  control._updateFieldArray(name, append, {
440
453
  argA: fillEmptyArray(value),
441
454
  }, updateValues(updatedFieldArrayValuesWithKey));
442
- setFields(updatedFieldArrayValuesWithKey);
443
455
  control._names.focus = getFocusFieldName(name, updatedFieldArrayValuesWithKey.length - appendValue.length, options);
444
456
  };
445
457
  const prepend$1 = (value, options) => {
446
458
  const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(convertToArrayPayload(value), keyName));
459
+ setFields(updatedFieldArrayValuesWithKey);
447
460
  control._updateFieldArray(name, prepend, {
448
461
  argA: fillEmptyArray(value),
449
462
  }, updateValues(updatedFieldArrayValuesWithKey));
450
- setFields(updatedFieldArrayValuesWithKey);
451
463
  control._names.focus = getFocusFieldName(name, 0, options);
452
464
  };
453
465
  const remove = (index) => {
454
466
  const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index);
467
+ setFields(updatedFieldArrayValuesWithKey);
455
468
  control._updateFieldArray(name, removeArrayAt, {
456
469
  argA: index,
457
470
  }, updateValues(updatedFieldArrayValuesWithKey));
458
- setFields(updatedFieldArrayValuesWithKey);
459
471
  };
460
472
  const insert$1 = (index, value, options) => {
461
473
  const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index, mapIds(convertToArrayPayload(value), keyName));
474
+ setFields(updatedFieldArrayValuesWithKey);
462
475
  control._updateFieldArray(name, insert, {
463
476
  argA: index,
464
477
  argB: fillEmptyArray(value),
465
478
  }, updateValues(updatedFieldArrayValuesWithKey));
466
- setFields(updatedFieldArrayValuesWithKey);
467
479
  control._names.focus = getFocusFieldName(name, index, options);
468
480
  };
469
481
  const swap = (indexA, indexB) => {
470
482
  const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
471
483
  swapArrayAt(updatedFieldArrayValuesWithKey, indexA, indexB);
484
+ setFields(updatedFieldArrayValuesWithKey);
472
485
  control._updateFieldArray(name, swapArrayAt, {
473
486
  argA: indexA,
474
487
  argB: indexB,
475
488
  }, updateValues(updatedFieldArrayValuesWithKey), false);
476
- setFields(updatedFieldArrayValuesWithKey);
477
489
  };
478
490
  const move = (from, to) => {
479
491
  const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
@@ -488,16 +500,16 @@ const useFieldArray = (props) => {
488
500
  const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
489
501
  const updatedFieldArrayValues = updateAt(updatedFieldArrayValuesWithKey, index, value);
490
502
  _fieldIds.current = mapIds(updatedFieldArrayValues, keyName);
503
+ setFields(_fieldIds.current);
491
504
  control._updateFieldArray(name, updateAt, {
492
505
  argA: index,
493
506
  argB: value,
494
507
  }, updateValues(_fieldIds.current), true, false);
495
- setFields(_fieldIds.current);
496
508
  };
497
509
  const replace = (value) => {
498
510
  const updatedFieldArrayValuesWithKey = mapIds(convertToArrayPayload(value), keyName);
499
- control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
500
511
  setFields(updatedFieldArrayValuesWithKey);
512
+ control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
501
513
  };
502
514
  React.useEffect(() => {
503
515
  control._stateFlags.action = false;
@@ -543,8 +555,6 @@ const useFieldArray = (props) => {
543
555
  };
544
556
  };
545
557
 
546
- var isFunction = (value) => typeof value === 'function';
547
-
548
558
  function cloneObject(data) {
549
559
  let copy;
550
560
  const isArray = Array.isArray(data);
@@ -696,6 +706,47 @@ function unset(object, path) {
696
706
  return object;
697
707
  }
698
708
 
709
+ function markFieldsDirty(data, fields = {}) {
710
+ const isParentNodeArray = Array.isArray(data);
711
+ if (isObject(data) || isParentNodeArray) {
712
+ for (const key in data) {
713
+ if (Array.isArray(data[key]) ||
714
+ (isObject(data[key]) && !objectHasFunction(data[key]))) {
715
+ fields[key] = Array.isArray(data[key]) ? [] : {};
716
+ markFieldsDirty(data[key], fields[key]);
717
+ }
718
+ else if (!isNullOrUndefined(data[key])) {
719
+ fields[key] = true;
720
+ }
721
+ }
722
+ }
723
+ return fields;
724
+ }
725
+ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues) {
726
+ const isParentNodeArray = Array.isArray(data);
727
+ if (isObject(data) || isParentNodeArray) {
728
+ for (const key in data) {
729
+ if (Array.isArray(data[key]) ||
730
+ (isObject(data[key]) && !objectHasFunction(data[key]))) {
731
+ if (isUndefined(formValues) ||
732
+ isPrimitive(dirtyFieldsFromValues[key])) {
733
+ dirtyFieldsFromValues[key] = Array.isArray(data[key])
734
+ ? markFieldsDirty(data[key], [])
735
+ : Object.assign({}, markFieldsDirty(data[key]));
736
+ }
737
+ else {
738
+ getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
739
+ }
740
+ }
741
+ else {
742
+ dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
743
+ }
744
+ }
745
+ }
746
+ return dirtyFieldsFromValues;
747
+ }
748
+ var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
749
+
699
750
  const defaultResult = {
700
751
  value: false,
701
752
  isValid: false,
@@ -818,49 +869,6 @@ function schemaErrorLookup(errors, _fields, name) {
818
869
  };
819
870
  }
820
871
 
821
- function deepMerge(target, source) {
822
- if (isPrimitive(target) || isPrimitive(source)) {
823
- return source;
824
- }
825
- for (const key in source) {
826
- const targetValue = target[key];
827
- const sourceValue = source[key];
828
- try {
829
- target[key] =
830
- (isObject(targetValue) && isObject(sourceValue)) ||
831
- (Array.isArray(targetValue) && Array.isArray(sourceValue))
832
- ? deepMerge(targetValue, sourceValue)
833
- : sourceValue;
834
- }
835
- catch (_a) { }
836
- }
837
- return target;
838
- }
839
-
840
- function setDirtyFields(values, defaultValues, dirtyFields, parentNode, parentName) {
841
- let index = -1;
842
- while (++index < values.length) {
843
- for (const key in values[index]) {
844
- if (Array.isArray(values[index][key])) {
845
- !dirtyFields[index] && (dirtyFields[index] = {});
846
- dirtyFields[index][key] = [];
847
- setDirtyFields(values[index][key], get(defaultValues[index] || {}, key, []), dirtyFields[index][key], dirtyFields[index], key);
848
- }
849
- else {
850
- !isNullOrUndefined(defaultValues) &&
851
- deepEqual(get(defaultValues[index] || {}, key), values[index][key])
852
- ? set(dirtyFields[index] || {}, key)
853
- : (dirtyFields[index] = Object.assign(Object.assign({}, dirtyFields[index]), { [key]: true }));
854
- }
855
- }
856
- parentNode &&
857
- !dirtyFields.length &&
858
- delete parentNode[parentName];
859
- }
860
- return dirtyFields;
861
- }
862
- var setFieldArrayDirtyFields = (values, defaultValues, dirtyFields) => deepMerge(setDirtyFields(values, defaultValues, dirtyFields.slice(0, values.length)), setDirtyFields(defaultValues, values, dirtyFields.slice(0, values.length)));
863
-
864
872
  var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
865
873
  if (mode.isOnAll) {
866
874
  return false;
@@ -877,8 +885,6 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
877
885
  return true;
878
886
  };
879
887
 
880
- var unsetEmptyArray = (ref, name) => !compact(get(ref, name, [])).length && unset(ref, name);
881
-
882
888
  var isMessage = (value) => isString(value) || React.isValidElement(value);
883
889
 
884
890
  var isRegex = (value) => value instanceof RegExp;
@@ -908,7 +914,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
908
914
  return {};
909
915
  }
910
916
  const inputRef = refs ? refs[0] : ref;
911
- const setCustomValidty = (message) => {
917
+ const setCustomValidity = (message) => {
912
918
  if (shouldUseNativeValidation && inputRef.reportValidity) {
913
919
  inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
914
920
  inputRef.reportValidity();
@@ -938,7 +944,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
938
944
  if (value) {
939
945
  error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.required, message, ref: inputRef }, appendErrorsCurry(INPUT_VALIDATION_RULES.required, message));
940
946
  if (!validateAllFieldCriteria) {
941
- setCustomValidty(message);
947
+ setCustomValidity(message);
942
948
  return error;
943
949
  }
944
950
  }
@@ -969,7 +975,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
969
975
  if (exceedMax || exceedMin) {
970
976
  getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
971
977
  if (!validateAllFieldCriteria) {
972
- setCustomValidty(error[name].message);
978
+ setCustomValidity(error[name].message);
973
979
  return error;
974
980
  }
975
981
  }
@@ -984,7 +990,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
984
990
  if (exceedMax || exceedMin) {
985
991
  getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
986
992
  if (!validateAllFieldCriteria) {
987
- setCustomValidty(error[name].message);
993
+ setCustomValidity(error[name].message);
988
994
  return error;
989
995
  }
990
996
  }
@@ -995,7 +1001,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
995
1001
  error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.pattern, message,
996
1002
  ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message));
997
1003
  if (!validateAllFieldCriteria) {
998
- setCustomValidty(message);
1004
+ setCustomValidity(message);
999
1005
  return error;
1000
1006
  }
1001
1007
  }
@@ -1007,7 +1013,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
1007
1013
  if (validateError) {
1008
1014
  error[name] = Object.assign(Object.assign({}, validateError), appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message));
1009
1015
  if (!validateAllFieldCriteria) {
1010
- setCustomValidty(validateError.message);
1016
+ setCustomValidity(validateError.message);
1011
1017
  return error;
1012
1018
  }
1013
1019
  }
@@ -1021,7 +1027,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
1021
1027
  const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
1022
1028
  if (validateError) {
1023
1029
  validationResult = Object.assign(Object.assign({}, validateError), appendErrorsCurry(key, validateError.message));
1024
- setCustomValidty(validateError.message);
1030
+ setCustomValidity(validateError.message);
1025
1031
  if (validateAllFieldCriteria) {
1026
1032
  error[name] = validationResult;
1027
1033
  }
@@ -1035,7 +1041,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
1035
1041
  }
1036
1042
  }
1037
1043
  }
1038
- setCustomValidty(true);
1044
+ setCustomValidity(true);
1039
1045
  return error;
1040
1046
  };
1041
1047
 
@@ -1122,16 +1128,14 @@ function createFormControl(props = {}) {
1122
1128
  if (Array.isArray(get(_formState.errors, name))) {
1123
1129
  const errors = method(get(_formState.errors, name), args.argA, args.argB);
1124
1130
  shouldSetValues && set(_formState.errors, name, errors);
1125
- unsetEmptyArray(_formState.errors, name);
1126
1131
  }
1127
1132
  if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
1128
1133
  const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
1129
1134
  shouldSetValues &&
1130
1135
  set(_formState.touchedFields, name, touchedFields);
1131
- unsetEmptyArray(_formState.touchedFields, name);
1132
1136
  }
1133
1137
  if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
1134
- updateFieldArrayDirty(name, values);
1138
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1135
1139
  }
1136
1140
  _subjects.state.next({
1137
1141
  isDirty: _getDirty(name, values),
@@ -1189,8 +1193,6 @@ function createFormControl(props = {}) {
1189
1193
  isFieldDirty && shouldRender && _subjects.state.next(output);
1190
1194
  return isFieldDirty ? output : {};
1191
1195
  };
1192
- const updateFieldArrayDirty = (name, value) => (set(_formState.dirtyFields, name, setFieldArrayDirtyFields(value, get(_defaultValues, name, []), get(_formState.dirtyFields, name, []))),
1193
- unsetEmptyArray(_formState.dirtyFields, name));
1194
1196
  const shouldRenderByError = async (shouldSkipRender, name, isValid, error, fieldState) => {
1195
1197
  const previousFieldError = get(_formState.errors, name);
1196
1198
  const shouldUpdateValid = _proxyFormState.isValid && _formState.isValid !== isValid;
@@ -1302,10 +1304,7 @@ function createFormControl(props = {}) {
1302
1304
  isWeb && isHTMLElement(fieldReference.ref) && isNullOrUndefined(value)
1303
1305
  ? ''
1304
1306
  : value;
1305
- if (isFileInput(fieldReference.ref) && !isString(fieldValue)) {
1306
- fieldReference.ref.files = fieldValue;
1307
- }
1308
- else if (isMultipleSelect(fieldReference.ref)) {
1307
+ if (isMultipleSelect(fieldReference.ref)) {
1309
1308
  [...fieldReference.ref.options].forEach((selectRef) => (selectRef.selected = fieldValue.includes(selectRef.value)));
1310
1309
  }
1311
1310
  else if (fieldReference.refs) {
@@ -1320,7 +1319,7 @@ function createFormControl(props = {}) {
1320
1319
  fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
1321
1320
  }
1322
1321
  }
1323
- else {
1322
+ else if (!isFileInput(fieldReference.ref)) {
1324
1323
  fieldReference.ref.value = fieldValue;
1325
1324
  }
1326
1325
  }
@@ -1353,7 +1352,7 @@ function createFormControl(props = {}) {
1353
1352
  });
1354
1353
  if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
1355
1354
  options.shouldDirty) {
1356
- updateFieldArrayDirty(name, value);
1355
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1357
1356
  _subjects.state.next({
1358
1357
  name,
1359
1358
  dirtyFields: _formState.dirtyFields,
@@ -1378,7 +1377,9 @@ function createFormControl(props = {}) {
1378
1377
  if (field) {
1379
1378
  let error;
1380
1379
  let isValid;
1381
- const fieldValue = target.type ? getFieldValue(field._f) : target.value;
1380
+ const fieldValue = target.type
1381
+ ? getFieldValue(field._f)
1382
+ : getEventValue(event);
1382
1383
  const isBlurEvent = event.type === EVENTS.BLUR;
1383
1384
  const shouldSkipValidation = (!hasValidation(field._f) &&
1384
1385
  !_options.resolver &&