react-hook-form 7.17.0 → 7.17.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.
package/dist/index.esm.js CHANGED
@@ -65,10 +65,9 @@ var omit = (source, key) => {
65
65
  return copy;
66
66
  };
67
67
 
68
- const FormContext = React.createContext(null);
69
- FormContext.displayName = 'RHFContext';
70
- const useFormContext = () => React.useContext(FormContext);
71
- const FormProvider = (props) => (React.createElement(FormContext.Provider, { value: omit(props, 'children') }, props.children));
68
+ const HookFormContext = React.createContext(null);
69
+ const useFormContext = () => React.useContext(HookFormContext);
70
+ const FormProvider = (props) => (React.createElement(HookFormContext.Provider, { value: omit(props, 'children') }, props.children));
72
71
 
73
72
  var getProxyFormState = (formState, _proxyFormState, localProxyFormState, isRoot = true) => {
74
73
  function createGetter(prop) {
@@ -179,7 +178,7 @@ function useController(props) {
179
178
  React.useEffect(() => {
180
179
  updateMounted(name, true);
181
180
  return () => {
182
- const _shouldUnregisterField = control._shouldUnregister || shouldUnregister;
181
+ const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
183
182
  if (isNameInFieldArray(control._names.array, name)
184
183
  ? _shouldUnregisterField && !control._stateFlags.action
185
184
  : _shouldUnregisterField) {
@@ -334,7 +333,7 @@ var moveArrayAt = (data, from, to) => {
334
333
  return [];
335
334
  };
336
335
 
337
- var omitKey = (fields, keyName) => fields.map((field = {}) => omit(field, keyName));
336
+ var omitKeys = (fields, keyName) => fields.map((field = {}) => omit(field, keyName));
338
337
 
339
338
  function prepend(data, value) {
340
339
  return [...convertToArrayPayload(value), ...convertToArrayPayload(data)];
@@ -365,8 +364,10 @@ var updateAt = (fieldValues, index, value) => {
365
364
  const useFieldArray = (props) => {
366
365
  const methods = useFormContext();
367
366
  const { control = methods.control, name, keyName = 'id', shouldUnregister, } = props;
368
- const [fields, setFields] = React.useState(mapIds(control._getFieldArrayValue(name), keyName));
367
+ const [fields, setFields] = React.useState(mapIds(control._getFieldArray(name), keyName));
369
368
  const _fieldIds = React.useRef(fields);
369
+ _fieldIds.current = fields;
370
+ control._names.array.add(name);
370
371
  useSubscribe({
371
372
  callback: ({ values, name: fieldArrayName }) => {
372
373
  if (fieldArrayName === name || !fieldArrayName) {
@@ -375,71 +376,69 @@ const useFieldArray = (props) => {
375
376
  },
376
377
  subject: control._subjects.array,
377
378
  });
378
- _fieldIds.current = fields;
379
- control._names.array.add(name);
380
379
  const updateValues = React.useCallback((updatedFieldArrayValuesWithKey) => {
381
- const updatedFieldArrayValues = omitKey(updatedFieldArrayValuesWithKey, keyName);
380
+ const updatedFieldArrayValues = omitKeys(updatedFieldArrayValuesWithKey, keyName);
382
381
  set(control._formValues, name, updatedFieldArrayValues);
383
382
  setFields(updatedFieldArrayValuesWithKey);
384
383
  return updatedFieldArrayValues;
385
384
  }, [control, name, keyName]);
386
385
  const append$1 = (value, options) => {
387
386
  const appendValue = convertToArrayPayload(value);
388
- const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName), mapIds(appendValue, keyName));
389
- control._updateFieldArray(keyName, name, append, {
387
+ const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(appendValue, keyName));
388
+ control._updateFieldArray(name, append, {
390
389
  argA: fillEmptyArray(value),
391
390
  }, updateValues(updatedFieldArrayValuesWithKey));
392
391
  control._names.focus = getFocusFieldName(name, updatedFieldArrayValuesWithKey.length - appendValue.length, options);
393
392
  };
394
393
  const prepend$1 = (value, options) => {
395
- const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName), mapIds(convertToArrayPayload(value), keyName));
396
- control._updateFieldArray(keyName, name, prepend, {
394
+ const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(convertToArrayPayload(value), keyName));
395
+ control._updateFieldArray(name, prepend, {
397
396
  argA: fillEmptyArray(value),
398
397
  }, updateValues(updatedFieldArrayValuesWithKey));
399
398
  control._names.focus = getFocusFieldName(name, 0, options);
400
399
  };
401
400
  const remove = (index) => {
402
- const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName), index);
403
- control._updateFieldArray(keyName, name, removeArrayAt, {
401
+ const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index);
402
+ control._updateFieldArray(name, removeArrayAt, {
404
403
  argA: index,
405
404
  }, updateValues(updatedFieldArrayValuesWithKey));
406
405
  };
407
406
  const insert$1 = (index, value, options) => {
408
- const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName), index, mapIds(convertToArrayPayload(value), keyName));
409
- control._updateFieldArray(keyName, name, insert, {
407
+ const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index, mapIds(convertToArrayPayload(value), keyName));
408
+ control._updateFieldArray(name, insert, {
410
409
  argA: index,
411
410
  argB: fillEmptyArray(value),
412
411
  }, updateValues(updatedFieldArrayValuesWithKey));
413
412
  control._names.focus = getFocusFieldName(name, index, options);
414
413
  };
415
414
  const swap = (indexA, indexB) => {
416
- const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName);
415
+ const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
417
416
  swapArrayAt(updatedFieldArrayValuesWithKey, indexA, indexB);
418
- control._updateFieldArray(keyName, name, swapArrayAt, {
417
+ control._updateFieldArray(name, swapArrayAt, {
419
418
  argA: indexA,
420
419
  argB: indexB,
421
420
  }, updateValues(updatedFieldArrayValuesWithKey), false);
422
421
  };
423
422
  const move = (from, to) => {
424
- const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName);
423
+ const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
425
424
  moveArrayAt(updatedFieldArrayValuesWithKey, from, to);
426
- control._updateFieldArray(keyName, name, moveArrayAt, {
425
+ control._updateFieldArray(name, moveArrayAt, {
427
426
  argA: from,
428
427
  argB: to,
429
428
  }, updateValues(updatedFieldArrayValuesWithKey), false);
430
429
  };
431
430
  const update = (index, value) => {
432
- const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArrayValue(name), _fieldIds, keyName);
431
+ const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
433
432
  const updatedFieldArrayValues = updateAt(updatedFieldArrayValuesWithKey, index, value);
434
433
  _fieldIds.current = mapIds(updatedFieldArrayValues, keyName);
435
- control._updateFieldArray(keyName, name, updateAt, {
434
+ control._updateFieldArray(name, updateAt, {
436
435
  argA: index,
437
436
  argB: value,
438
437
  }, updateValues(_fieldIds.current), true, false);
439
438
  };
440
439
  const replace = (value) => {
441
440
  const updatedFieldArrayValuesWithKey = mapIds(convertToArrayPayload(value), keyName);
442
- control._updateFieldArray(keyName, name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
441
+ control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
443
442
  };
444
443
  React.useEffect(() => {
445
444
  control._stateFlags.action = false;
@@ -466,7 +465,7 @@ const useFieldArray = (props) => {
466
465
  React.useEffect(() => {
467
466
  !get(control._formValues, name) && set(control._formValues, name, []);
468
467
  return () => {
469
- if (control._shouldUnregister || shouldUnregister) {
468
+ if (control._options.shouldUnregister || shouldUnregister) {
470
469
  control.unregister(name);
471
470
  }
472
471
  };
@@ -508,12 +507,12 @@ function cloneObject(data) {
508
507
  var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
509
508
 
510
509
  function deepEqual(object1, object2) {
511
- if (isPrimitive(object1) ||
512
- isPrimitive(object2) ||
513
- isDateObject(object1) ||
514
- isDateObject(object2)) {
510
+ if (isPrimitive(object1) || isPrimitive(object2)) {
515
511
  return object1 === object2;
516
512
  }
513
+ if (isDateObject(object1) && isDateObject(object2)) {
514
+ return object1.getTime() === object2.getTime();
515
+ }
517
516
  const keys1 = Object.keys(object1);
518
517
  const keys2 = Object.keys(object2);
519
518
  if (keys1.length !== keys2.length) {
@@ -526,8 +525,9 @@ function deepEqual(object1, object2) {
526
525
  }
527
526
  if (key !== 'ref') {
528
527
  const val2 = object2[key];
529
- if ((isObject(val1) || Array.isArray(val1)) &&
530
- (isObject(val2) || Array.isArray(val2))
528
+ if ((isDateObject(val1) && isDateObject(val2)) ||
529
+ (isObject(val1) && isObject(val2)) ||
530
+ (Array.isArray(val1) && Array.isArray(val2))
531
531
  ? !deepEqual(val1, val2)
532
532
  : val1 !== val2) {
533
533
  return false;
@@ -547,8 +547,6 @@ var getValidationModes = (mode) => ({
547
547
 
548
548
  var isBoolean = (value) => typeof value === 'boolean';
549
549
 
550
- var isFileInput = (element) => element.type === 'file';
551
-
552
550
  var isFunction = (value) => typeof value === 'function';
553
551
 
554
552
  var isHTMLElement = (value) => value instanceof HTMLElement;
@@ -652,6 +650,8 @@ function unset(object, path) {
652
650
  return object;
653
651
  }
654
652
 
653
+ var isFileInput = (element) => element.type === 'file';
654
+
655
655
  const defaultResult = {
656
656
  value: false,
657
657
  isValid: false,
@@ -973,8 +973,7 @@ const defaultOptions = {
973
973
  };
974
974
  const isWindowUndefined = typeof window === 'undefined';
975
975
  function createFormControl(props = {}) {
976
- let formOptions = Object.assign(Object.assign({}, defaultOptions), props);
977
- let _delayCallback;
976
+ let _options = Object.assign(Object.assign({}, defaultOptions), props);
978
977
  let _formState = {
979
978
  isDirty: false,
980
979
  isValidating: false,
@@ -988,8 +987,8 @@ function createFormControl(props = {}) {
988
987
  errors: {},
989
988
  };
990
989
  let _fields = {};
991
- let _defaultValues = formOptions.defaultValues || {};
992
- let _formValues = formOptions.shouldUnregister
990
+ let _defaultValues = _options.defaultValues || {};
991
+ let _formValues = _options.shouldUnregister
993
992
  ? {}
994
993
  : cloneObject(_defaultValues);
995
994
  let _stateFlags = {
@@ -997,14 +996,15 @@ function createFormControl(props = {}) {
997
996
  mount: false,
998
997
  watch: false,
999
998
  };
1000
- let _timer = 0;
1001
999
  let _names = {
1002
1000
  mount: new Set(),
1003
1001
  unMount: new Set(),
1004
1002
  array: new Set(),
1005
1003
  watch: new Set(),
1006
1004
  };
1007
- let _validateCount = {};
1005
+ let delayErrorCallback;
1006
+ let timer = 0;
1007
+ let validateFields = {};
1008
1008
  const _proxyFormState = {
1009
1009
  isDirty: false,
1010
1010
  dirtyFields: false,
@@ -1019,37 +1019,125 @@ function createFormControl(props = {}) {
1019
1019
  array: new Subject(),
1020
1020
  state: new Subject(),
1021
1021
  };
1022
- const validationMode = getValidationModes(formOptions.mode);
1023
- const reValidateMode = getValidationModes(formOptions.reValidateMode);
1024
- const isValidateAllFieldCriteria = formOptions.criteriaMode === VALIDATION_MODE.all;
1022
+ const validationModeBeforeSubmit = getValidationModes(_options.mode);
1023
+ const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1024
+ const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
1025
1025
  const debounce = (callback, wait) => (...args) => {
1026
- clearTimeout(_timer);
1027
- _timer = window.setTimeout(() => callback(...args), wait);
1026
+ clearTimeout(timer);
1027
+ timer = window.setTimeout(() => callback(...args), wait);
1028
1028
  };
1029
- const isFieldWatched = (name) => _names.watchAll ||
1030
- _names.watch.has(name) ||
1031
- _names.watch.has((name.match(/\w+/) || [])[0]);
1032
- const updateErrorState = (name, error) => {
1033
- set(_formState.errors, name, error);
1029
+ const isFieldWatched = (name, isBlurEvent) => !isBlurEvent &&
1030
+ (_names.watchAll ||
1031
+ _names.watch.has(name) ||
1032
+ _names.watch.has((name.match(/\w+/) || [])[0]));
1033
+ const _updateValid = async (shouldSkipRender) => {
1034
+ let isValid = false;
1035
+ if (_proxyFormState.isValid) {
1036
+ isValid = _options.resolver
1037
+ ? isEmptyObject((await executeResolver()).errors)
1038
+ : await executeBuildInValidation(_fields, true);
1039
+ if (!shouldSkipRender && isValid !== _formState.isValid) {
1040
+ _formState.isValid = isValid;
1041
+ _subjects.state.next({
1042
+ isValid,
1043
+ });
1044
+ }
1045
+ }
1046
+ return isValid;
1047
+ };
1048
+ const _updateFieldArray = (name, method, args, values = [], shouldSetValues = true, shouldSetFields = true) => {
1049
+ _stateFlags.action = true;
1050
+ if (shouldSetFields && get(_fields, name)) {
1051
+ const fieldValues = method(get(_fields, name), args.argA, args.argB);
1052
+ shouldSetValues && set(_fields, name, fieldValues);
1053
+ }
1054
+ if (Array.isArray(get(_formState.errors, name))) {
1055
+ const errors = method(get(_formState.errors, name), args.argA, args.argB);
1056
+ shouldSetValues && set(_formState.errors, name, errors);
1057
+ unsetEmptyArray(_formState.errors, name);
1058
+ }
1059
+ if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
1060
+ const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
1061
+ shouldSetValues &&
1062
+ set(_formState.touchedFields, name, touchedFields);
1063
+ unsetEmptyArray(_formState.touchedFields, name);
1064
+ }
1065
+ if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
1066
+ updateFieldArrayDirty(name, values);
1067
+ }
1034
1068
  _subjects.state.next({
1069
+ isDirty: _getDirty(name, values),
1070
+ dirtyFields: _formState.dirtyFields,
1035
1071
  errors: _formState.errors,
1072
+ isValid: _formState.isValid,
1036
1073
  });
1037
1074
  };
1038
- const shouldRenderBaseOnError = async (shouldSkipRender, name, isValid, error, fieldState) => {
1039
- const previousError = get(_formState.errors, name);
1075
+ const updateErrors = (name, error) => (set(_formState.errors, name, error),
1076
+ _subjects.state.next({
1077
+ errors: _formState.errors,
1078
+ }));
1079
+ const updateValidAndValue = (name, shouldSkipSetValueAs, ref) => {
1080
+ const field = get(_fields, name);
1081
+ if (field) {
1082
+ const defaultValue = get(_formValues, name, get(_defaultValues, name));
1083
+ isUndefined(defaultValue) ||
1084
+ (ref && ref.defaultChecked) ||
1085
+ shouldSkipSetValueAs
1086
+ ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
1087
+ : setFieldValue(name, defaultValue);
1088
+ }
1089
+ _stateFlags.mount && _updateValid();
1090
+ };
1091
+ const updateTouchAndDirty = (name, fieldValue, isCurrentTouched, shouldRender = true) => {
1092
+ let isFieldDirty = false;
1093
+ const output = {
1094
+ name,
1095
+ };
1096
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1097
+ if (_proxyFormState.isDirty) {
1098
+ const isPreviousFormDirty = _formState.isDirty;
1099
+ _formState.isDirty = output.isDirty = _getDirty();
1100
+ isFieldDirty = isPreviousFormDirty !== output.isDirty;
1101
+ }
1102
+ if (_proxyFormState.dirtyFields && !isCurrentTouched) {
1103
+ const isPreviousFieldDirty = get(_formState.dirtyFields, name);
1104
+ const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1105
+ isCurrentFieldPristine
1106
+ ? unset(_formState.dirtyFields, name)
1107
+ : set(_formState.dirtyFields, name, true);
1108
+ output.dirtyFields = _formState.dirtyFields;
1109
+ isFieldDirty =
1110
+ isFieldDirty ||
1111
+ isPreviousFieldDirty !== get(_formState.dirtyFields, name);
1112
+ }
1113
+ if (isCurrentTouched && !isPreviousFieldTouched) {
1114
+ set(_formState.touchedFields, name, isCurrentTouched);
1115
+ output.touchedFields = _formState.touchedFields;
1116
+ isFieldDirty =
1117
+ isFieldDirty ||
1118
+ (_proxyFormState.touchedFields &&
1119
+ isPreviousFieldTouched !== isCurrentTouched);
1120
+ }
1121
+ isFieldDirty && shouldRender && _subjects.state.next(output);
1122
+ return isFieldDirty ? output : {};
1123
+ };
1124
+ const updateFieldArrayDirty = (name, value) => (set(_formState.dirtyFields, name, setFieldArrayDirtyFields(value, get(_defaultValues, name, []), get(_formState.dirtyFields, name, []))),
1125
+ unsetEmptyArray(_formState.dirtyFields, name));
1126
+ const shouldRenderByError = async (shouldSkipRender, name, isValid, error, fieldState) => {
1127
+ const previousFieldError = get(_formState.errors, name);
1040
1128
  const shouldUpdateValid = _proxyFormState.isValid && _formState.isValid !== isValid;
1041
1129
  if (props.delayError && error) {
1042
- _delayCallback =
1043
- _delayCallback || debounce(updateErrorState, props.delayError);
1044
- _delayCallback(name, error);
1130
+ delayErrorCallback =
1131
+ delayErrorCallback || debounce(updateErrors, props.delayError);
1132
+ delayErrorCallback(name, error);
1045
1133
  }
1046
1134
  else {
1047
- clearTimeout(_timer);
1135
+ clearTimeout(timer);
1048
1136
  error
1049
1137
  ? set(_formState.errors, name, error)
1050
1138
  : unset(_formState.errors, name);
1051
1139
  }
1052
- if (((error ? !deepEqual(previousError, error) : previousError) ||
1140
+ if (((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
1053
1141
  !isEmptyObject(fieldState) ||
1054
1142
  shouldUpdateValid) &&
1055
1143
  !shouldSkipRender) {
@@ -1057,138 +1145,169 @@ function createFormControl(props = {}) {
1057
1145
  _formState = Object.assign(Object.assign({}, _formState), updatedFormState);
1058
1146
  _subjects.state.next(updatedFormState);
1059
1147
  }
1060
- _validateCount[name]--;
1061
- if (_proxyFormState.isValidating && !_validateCount[name]) {
1148
+ validateFields[name]--;
1149
+ if (_proxyFormState.isValidating && !validateFields[name]) {
1062
1150
  _subjects.state.next({
1063
1151
  isValidating: false,
1064
1152
  });
1065
- _validateCount = {};
1153
+ validateFields = {};
1154
+ }
1155
+ };
1156
+ const executeResolver = async (name) => _options.resolver
1157
+ ? await _options.resolver(Object.assign({}, _formValues), _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
1158
+ : {};
1159
+ const executeResolverValidation = async (names) => {
1160
+ const { errors } = await executeResolver();
1161
+ if (names) {
1162
+ for (const name of names) {
1163
+ const error = get(errors, name);
1164
+ error
1165
+ ? set(_formState.errors, name, error)
1166
+ : unset(_formState.errors, name);
1167
+ }
1066
1168
  }
1169
+ else {
1170
+ _formState.errors = errors;
1171
+ }
1172
+ return errors;
1173
+ };
1174
+ const executeBuildInValidation = async (fields, shouldOnlyCheckValid, context = {
1175
+ valid: true,
1176
+ }) => {
1177
+ for (const name in fields) {
1178
+ const field = fields[name];
1179
+ if (field) {
1180
+ const fieldReference = field._f;
1181
+ const fieldValue = omit(field, '_f');
1182
+ if (fieldReference) {
1183
+ const fieldError = await validateField(field, get(_formValues, fieldReference.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation);
1184
+ if (fieldError[fieldReference.name]) {
1185
+ context.valid = false;
1186
+ if (shouldOnlyCheckValid) {
1187
+ break;
1188
+ }
1189
+ }
1190
+ if (!shouldOnlyCheckValid) {
1191
+ fieldError[fieldReference.name]
1192
+ ? set(_formState.errors, fieldReference.name, fieldError[fieldReference.name])
1193
+ : unset(_formState.errors, fieldReference.name);
1194
+ }
1195
+ }
1196
+ fieldValue &&
1197
+ (await executeBuildInValidation(fieldValue, shouldOnlyCheckValid, context));
1198
+ }
1199
+ }
1200
+ return context.valid;
1201
+ };
1202
+ const _removeUnmounted = () => {
1203
+ for (const name of _names.unMount) {
1204
+ const field = get(_fields, name);
1205
+ field &&
1206
+ (field._f.refs ? field._f.refs.every(live) : live(field._f.ref)) &&
1207
+ unregister(name);
1208
+ }
1209
+ _names.unMount = new Set();
1210
+ };
1211
+ const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
1212
+ !deepEqual(getValues(), _defaultValues));
1213
+ const _getWatch = (names, defaultValue, isGlobal) => {
1214
+ const fieldValues = Object.assign({}, (_stateFlags.mount
1215
+ ? _formValues
1216
+ : isUndefined(defaultValue)
1217
+ ? _defaultValues
1218
+ : isString(names)
1219
+ ? { [names]: defaultValue }
1220
+ : defaultValue));
1221
+ if (names) {
1222
+ const result = convertToArrayPayload(names).map((fieldName) => (isGlobal && _names.watch.add(fieldName),
1223
+ get(fieldValues, fieldName)));
1224
+ return Array.isArray(names) ? result : result[0];
1225
+ }
1226
+ isGlobal && (_names.watchAll = true);
1227
+ return fieldValues;
1067
1228
  };
1229
+ const _getFieldArray = (name) => get(_stateFlags.mount ? _formValues : _defaultValues, name, []);
1068
1230
  const setFieldValue = (name, value, options = {}, shouldRender) => {
1069
1231
  const field = get(_fields, name);
1070
1232
  let fieldValue = value;
1071
1233
  if (field) {
1072
- const _f = field._f;
1073
- if (_f) {
1074
- set(_formValues, name, getFieldValueAs(value, _f));
1234
+ const fieldReference = field._f;
1235
+ if (fieldReference) {
1236
+ set(_formValues, name, getFieldValueAs(value, fieldReference));
1075
1237
  fieldValue =
1076
- isWeb && isHTMLElement(_f.ref) && isNullOrUndefined(value)
1238
+ isWeb && isHTMLElement(fieldReference.ref) && isNullOrUndefined(value)
1077
1239
  ? ''
1078
1240
  : value;
1079
- if (isFileInput(_f.ref) && !isString(fieldValue)) {
1080
- _f.ref.files = fieldValue;
1081
- }
1082
- else if (isMultipleSelect(_f.ref)) {
1083
- [..._f.ref.options].forEach((selectRef) => (selectRef.selected = fieldValue.includes(selectRef.value)));
1241
+ if (isMultipleSelect(fieldReference.ref)) {
1242
+ [...fieldReference.ref.options].forEach((selectRef) => (selectRef.selected = fieldValue.includes(selectRef.value)));
1084
1243
  }
1085
- else if (_f.refs) {
1086
- if (isCheckBoxInput(_f.ref)) {
1087
- _f.refs.length > 1
1088
- ? _f.refs.forEach((checkboxRef) => (checkboxRef.checked = Array.isArray(fieldValue)
1244
+ else if (fieldReference.refs) {
1245
+ if (isCheckBoxInput(fieldReference.ref)) {
1246
+ fieldReference.refs.length > 1
1247
+ ? fieldReference.refs.forEach((checkboxRef) => (checkboxRef.checked = Array.isArray(fieldValue)
1089
1248
  ? !!fieldValue.find((data) => data === checkboxRef.value)
1090
1249
  : fieldValue === checkboxRef.value))
1091
- : (_f.refs[0].checked = !!fieldValue);
1250
+ : (fieldReference.refs[0].checked = !!fieldValue);
1092
1251
  }
1093
1252
  else {
1094
- _f.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
1253
+ fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
1095
1254
  }
1096
1255
  }
1097
1256
  else {
1098
- _f.ref.value = fieldValue;
1257
+ fieldReference.ref.value = fieldValue;
1099
1258
  }
1100
- if (shouldRender) {
1259
+ shouldRender &&
1101
1260
  _subjects.control.next({
1102
1261
  values: _formValues,
1103
1262
  name,
1104
1263
  });
1105
- }
1106
1264
  }
1107
1265
  }
1108
1266
  (options.shouldDirty || options.shouldTouch) &&
1109
- updateTouchAndDirtyState(name, fieldValue, options.shouldTouch);
1267
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch);
1110
1268
  options.shouldValidate && trigger(name);
1111
1269
  };
1112
- const updateTouchAndDirtyState = (name, inputValue, isCurrentTouched, shouldRender = true) => {
1113
- const state = {
1114
- name,
1115
- };
1116
- let isChanged = false;
1117
- if (_proxyFormState.isDirty) {
1118
- const previousIsDirty = _formState.isDirty;
1119
- _formState.isDirty = _getIsDirty();
1120
- state.isDirty = _formState.isDirty;
1121
- isChanged = previousIsDirty !== state.isDirty;
1122
- }
1123
- if (_proxyFormState.dirtyFields && !isCurrentTouched) {
1124
- const isPreviousFieldDirty = get(_formState.dirtyFields, name);
1125
- const isCurrentFieldDirty = !deepEqual(get(_defaultValues, name), inputValue);
1126
- isCurrentFieldDirty
1127
- ? set(_formState.dirtyFields, name, true)
1128
- : unset(_formState.dirtyFields, name);
1129
- state.dirtyFields = _formState.dirtyFields;
1130
- isChanged =
1131
- isChanged || isPreviousFieldDirty !== get(_formState.dirtyFields, name);
1132
- }
1133
- const isPreviousFieldTouched = get(_formState.touchedFields, name);
1134
- if (isCurrentTouched && !isPreviousFieldTouched) {
1135
- set(_formState.touchedFields, name, isCurrentTouched);
1136
- state.touchedFields = _formState.touchedFields;
1137
- isChanged =
1138
- isChanged ||
1139
- (_proxyFormState.touchedFields &&
1140
- isPreviousFieldTouched !== isCurrentTouched);
1270
+ const setValues = (name, value, options) => {
1271
+ for (const fieldKey in value) {
1272
+ const fieldValue = value[fieldKey];
1273
+ const fieldName = `${name}.${fieldKey}`;
1274
+ const field = get(_fields, fieldName);
1275
+ (_names.array.has(name) ||
1276
+ !isPrimitive(fieldValue) ||
1277
+ (field && !field._f)) &&
1278
+ !isDateObject(fieldValue)
1279
+ ? setValues(fieldName, fieldValue, options)
1280
+ : setFieldValue(fieldName, fieldValue, options, true);
1141
1281
  }
1142
- isChanged && shouldRender && _subjects.state.next(state);
1143
- return isChanged ? state : {};
1144
1282
  };
1145
- const executeResolver = async (name) => {
1146
- return formOptions.resolver
1147
- ? await formOptions.resolver(Object.assign({}, _formValues), formOptions.context, getResolverOptions(name || _names.mount, _fields, formOptions.criteriaMode, formOptions.shouldUseNativeValidation))
1148
- : {};
1149
- };
1150
- const executeResolverValidation = async (names) => {
1151
- const { errors } = await executeResolver();
1152
- if (names) {
1153
- for (const name of names) {
1154
- const error = get(errors, name);
1155
- error
1156
- ? set(_formState.errors, name, error)
1157
- : unset(_formState.errors, name);
1283
+ const setValue = (name, value, options = {}) => {
1284
+ const field = get(_fields, name);
1285
+ const isFieldArray = _names.array.has(name);
1286
+ set(_formValues, name, value);
1287
+ if (isFieldArray) {
1288
+ _subjects.array.next({
1289
+ name,
1290
+ values: _formValues,
1291
+ });
1292
+ if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
1293
+ options.shouldDirty) {
1294
+ updateFieldArrayDirty(name, value);
1295
+ _subjects.state.next({
1296
+ name,
1297
+ dirtyFields: _formState.dirtyFields,
1298
+ isDirty: _getDirty(name, value),
1299
+ });
1158
1300
  }
1159
1301
  }
1160
1302
  else {
1161
- _formState.errors = errors;
1162
- }
1163
- return errors;
1164
- };
1165
- const validateForm = async (_fields, shouldCheckValid, context = {
1166
- valid: true,
1167
- }) => {
1168
- for (const name in _fields) {
1169
- const field = _fields[name];
1170
- if (field) {
1171
- const _f = field._f;
1172
- const fieldValue = omit(field, '_f');
1173
- if (_f) {
1174
- const fieldError = await validateField(field, get(_formValues, _f.name), isValidateAllFieldCriteria, formOptions.shouldUseNativeValidation);
1175
- if (fieldError[_f.name]) {
1176
- context.valid = false;
1177
- if (shouldCheckValid) {
1178
- break;
1179
- }
1180
- }
1181
- if (!shouldCheckValid) {
1182
- fieldError[_f.name]
1183
- ? set(_formState.errors, _f.name, fieldError[_f.name])
1184
- : unset(_formState.errors, _f.name);
1185
- }
1186
- }
1187
- fieldValue &&
1188
- (await validateForm(fieldValue, shouldCheckValid, context));
1189
- }
1303
+ field && !field._f && !isNullOrUndefined(value)
1304
+ ? setValues(name, value, options)
1305
+ : setFieldValue(name, value, options, true);
1190
1306
  }
1191
- return context.valid;
1307
+ isFieldWatched(name) && _subjects.state.next({});
1308
+ _subjects.watch.next({
1309
+ name,
1310
+ });
1192
1311
  };
1193
1312
  const handleChange = async (event) => {
1194
1313
  const target = event.target;
@@ -1197,22 +1316,22 @@ function createFormControl(props = {}) {
1197
1316
  if (field) {
1198
1317
  let error;
1199
1318
  let isValid;
1200
- const inputValue = target.type ? getFieldValue(field._f) : target.value;
1319
+ const fieldValue = target.type ? getFieldValue(field._f) : target.value;
1201
1320
  const isBlurEvent = event.type === EVENTS.BLUR;
1321
+ const shouldSkipValidation = (!hasValidation(field._f) &&
1322
+ !_options.resolver &&
1323
+ !get(_formState.errors, name) &&
1324
+ !field._f.deps) ||
1325
+ skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1326
+ const isWatched = isFieldWatched(name, isBlurEvent);
1202
1327
  if (isBlurEvent && field._f.onBlur) {
1203
1328
  field._f.onBlur(event);
1204
1329
  }
1205
1330
  else if (field._f.onChange) {
1206
1331
  field._f.onChange(event);
1207
1332
  }
1208
- const shouldSkipValidation = (!hasValidation(field._f) &&
1209
- !formOptions.resolver &&
1210
- !get(_formState.errors, name) &&
1211
- !field._f.deps) ||
1212
- skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, reValidateMode, validationMode);
1213
- const isWatched = !isBlurEvent && isFieldWatched(name);
1214
- set(_formValues, name, inputValue);
1215
- const fieldState = updateTouchAndDirtyState(name, inputValue, isBlurEvent, false);
1333
+ set(_formValues, name, fieldValue);
1334
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
1216
1335
  const shouldRender = !isEmptyObject(fieldState) || isWatched;
1217
1336
  !isBlurEvent &&
1218
1337
  _subjects.watch.next({
@@ -1224,12 +1343,12 @@ function createFormControl(props = {}) {
1224
1343
  _subjects.state.next(Object.assign({ name }, (isWatched ? {} : fieldState))));
1225
1344
  }
1226
1345
  !isBlurEvent && isWatched && _subjects.state.next({});
1227
- _validateCount[name] = _validateCount[name] ? +1 : 1;
1346
+ validateFields[name] = validateFields[name] ? +1 : 1;
1228
1347
  _proxyFormState.isValidating &&
1229
1348
  _subjects.state.next({
1230
1349
  isValidating: true,
1231
1350
  });
1232
- if (formOptions.resolver) {
1351
+ if (_options.resolver) {
1233
1352
  const { errors } = await executeResolver([name]);
1234
1353
  error = get(errors, name);
1235
1354
  if (isCheckBoxInput(target) && !error) {
@@ -1245,169 +1364,41 @@ function createFormControl(props = {}) {
1245
1364
  isValid = isEmptyObject(errors);
1246
1365
  }
1247
1366
  else {
1248
- error = (await validateField(field, get(_formValues, name), isValidateAllFieldCriteria, formOptions.shouldUseNativeValidation))[name];
1367
+ error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1249
1368
  isValid = await _updateValid(true);
1250
1369
  }
1251
- if (field._f.deps) {
1252
- trigger(field._f.deps);
1253
- }
1254
- shouldRenderBaseOnError(false, name, isValid, error, fieldState);
1370
+ field._f.deps && trigger(field._f.deps);
1371
+ shouldRenderByError(false, name, isValid, error, fieldState);
1255
1372
  }
1256
1373
  };
1257
- const _updateValidAndInputValue = (name, shouldSkipValueAs, ref) => {
1258
- const field = get(_fields, name);
1259
- if (field) {
1260
- const fieldValue = get(_formValues, name);
1261
- const defaultValue = isUndefined(fieldValue)
1262
- ? get(_defaultValues, name)
1263
- : fieldValue;
1264
- if (isUndefined(defaultValue) ||
1265
- (ref && ref.defaultChecked) ||
1266
- shouldSkipValueAs) {
1267
- set(_formValues, name, shouldSkipValueAs ? defaultValue : getFieldValue(field._f));
1268
- }
1269
- else {
1270
- setFieldValue(name, defaultValue);
1271
- }
1272
- }
1273
- _stateFlags.mount && _updateValid();
1274
- };
1275
- const _getIsDirty = (name, data) => {
1276
- name && data && set(_formValues, name, data);
1277
- return !deepEqual(Object.assign({}, getValues()), _defaultValues);
1278
- };
1279
- const _updateValid = async (skipRender) => {
1280
- let isValid = false;
1281
- if (_proxyFormState.isValid) {
1282
- isValid = formOptions.resolver
1283
- ? isEmptyObject((await executeResolver()).errors)
1284
- : await validateForm(_fields, true);
1285
- if (!skipRender && isValid !== _formState.isValid) {
1286
- _formState.isValid = isValid;
1287
- _subjects.state.next({
1288
- isValid,
1289
- });
1290
- }
1291
- }
1292
- return isValid;
1293
- };
1294
- const setValues = (name, value, options) => Object.entries(value).forEach(([fieldKey, fieldValue]) => {
1295
- const fieldName = `${name}.${fieldKey}`;
1296
- const field = get(_fields, fieldName);
1297
- (_names.array.has(name) ||
1298
- !isPrimitive(fieldValue) ||
1299
- (field && !field._f)) &&
1300
- !isDateObject(fieldValue)
1301
- ? setValues(fieldName, fieldValue, options)
1302
- : setFieldValue(fieldName, fieldValue, options, true);
1303
- });
1304
- const _getWatch = (fieldNames, defaultValue, isMounted, isGlobal) => {
1305
- const fieldValues = Object.assign({}, (isMounted || _stateFlags.mount
1306
- ? _formValues
1307
- : isUndefined(defaultValue)
1308
- ? _defaultValues
1309
- : isString(fieldNames)
1310
- ? { [fieldNames]: defaultValue }
1311
- : defaultValue));
1312
- if (!fieldNames) {
1313
- isGlobal && (_names.watchAll = true);
1314
- return fieldValues;
1315
- }
1316
- const result = [];
1317
- for (const fieldName of convertToArrayPayload(fieldNames)) {
1318
- isGlobal && _names.watch.add(fieldName);
1319
- result.push(get(fieldValues, fieldName));
1320
- }
1321
- return Array.isArray(fieldNames) ? result : result[0];
1322
- };
1323
- const _updateFieldArray = (keyName, name, method, args, values = [], shouldSet = true, shouldSetFields = true) => {
1324
- let output;
1325
- _stateFlags.action = true;
1326
- if (shouldSetFields && get(_fields, name)) {
1327
- output = method(get(_fields, name), args.argA, args.argB);
1328
- shouldSet && set(_fields, name, output);
1329
- }
1330
- if (Array.isArray(get(_formState.errors, name))) {
1331
- const output = method(get(_formState.errors, name), args.argA, args.argB);
1332
- shouldSet && set(_formState.errors, name, output);
1333
- unsetEmptyArray(_formState.errors, name);
1334
- }
1335
- if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
1336
- const output = method(get(_formState.touchedFields, name), args.argA, args.argB);
1337
- shouldSet && set(_formState.touchedFields, name, output);
1338
- unsetEmptyArray(_formState.touchedFields, name);
1339
- }
1340
- if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
1341
- set(_formState.dirtyFields, name, setFieldArrayDirtyFields(omitKey(values, keyName), get(_defaultValues, name, []), get(_formState.dirtyFields, name, [])));
1342
- values &&
1343
- set(_formState.dirtyFields, name, setFieldArrayDirtyFields(omitKey(values, keyName), get(_defaultValues, name, []), get(_formState.dirtyFields, name, [])));
1344
- unsetEmptyArray(_formState.dirtyFields, name);
1345
- }
1346
- _subjects.state.next({
1347
- isDirty: _getIsDirty(name, omitKey(values, keyName)),
1348
- dirtyFields: _formState.dirtyFields,
1349
- errors: _formState.errors,
1350
- isValid: _formState.isValid,
1351
- });
1352
- };
1353
- const _getFieldArrayValue = (name) => get(_stateFlags.mount ? _formValues : _defaultValues, name, []);
1354
- const setValue = (name, value, options = {}) => {
1355
- const field = get(_fields, name);
1356
- const isFieldArray = _names.array.has(name);
1357
- set(_formValues, name, value);
1358
- if (isFieldArray) {
1359
- _subjects.array.next({
1360
- name,
1361
- values: _formValues,
1362
- });
1363
- if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
1364
- options.shouldDirty) {
1365
- set(_formState.dirtyFields, name, setFieldArrayDirtyFields(value, get(_defaultValues, name, []), get(_formState.dirtyFields, name, [])));
1366
- _subjects.state.next({
1367
- name,
1368
- dirtyFields: _formState.dirtyFields,
1369
- isDirty: _getIsDirty(name, value),
1370
- });
1371
- }
1372
- }
1373
- else {
1374
- field && !field._f && !isNullOrUndefined(value)
1375
- ? setValues(name, value, options)
1376
- : setFieldValue(name, value, options, true);
1377
- }
1378
- isFieldWatched(name) && _subjects.state.next({});
1379
- _subjects.watch.next({
1380
- name,
1381
- });
1382
- };
1383
1374
  const trigger = async (name, options = {}) => {
1384
- const fieldNames = convertToArrayPayload(name);
1385
1375
  let isValid;
1386
1376
  let validationResult;
1377
+ const fieldNames = convertToArrayPayload(name);
1387
1378
  _subjects.state.next({
1388
1379
  isValidating: true,
1389
1380
  });
1390
- if (formOptions.resolver) {
1391
- const schemaResult = await executeResolverValidation(isUndefined(name) ? name : fieldNames);
1392
- isValid = isEmptyObject(schemaResult);
1381
+ if (_options.resolver) {
1382
+ const errors = await executeResolverValidation(isUndefined(name) ? name : fieldNames);
1383
+ isValid = isEmptyObject(errors);
1393
1384
  validationResult = name
1394
- ? !fieldNames.some((name) => get(schemaResult, name))
1385
+ ? !fieldNames.some((name) => get(errors, name))
1395
1386
  : isValid;
1396
1387
  }
1397
1388
  else if (name) {
1398
1389
  validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1399
1390
  const field = get(_fields, fieldName);
1400
- return await validateForm(field && field._f ? { [fieldName]: field } : field);
1391
+ return await executeBuildInValidation(field && field._f ? { [fieldName]: field } : field);
1401
1392
  }))).every(Boolean);
1402
1393
  _updateValid();
1403
1394
  }
1404
1395
  else {
1405
- validationResult = isValid = await validateForm(_fields);
1396
+ validationResult = isValid = await executeBuildInValidation(_fields);
1406
1397
  }
1407
1398
  _subjects.state.next(Object.assign(Object.assign({}, (!isString(name) || isValid !== _formState.isValid ? {} : { name })), { errors: _formState.errors, isValid, isValidating: false }));
1408
- if (options.shouldFocus && !validationResult) {
1399
+ options.shouldFocus &&
1400
+ !validationResult &&
1409
1401
  focusFieldBy(_fields, (key) => get(_formState.errors, key), name ? fieldNames : _names.mount);
1410
- }
1411
1402
  return validationResult;
1412
1403
  };
1413
1404
  const getValues = (fieldNames) => {
@@ -1436,88 +1427,83 @@ function createFormControl(props = {}) {
1436
1427
  });
1437
1428
  options && options.shouldFocus && ref && ref.focus && ref.focus();
1438
1429
  };
1439
- const watch = (fieldName, defaultValue) => isFunction(fieldName)
1430
+ const watch = (name, defaultValue) => isFunction(name)
1440
1431
  ? _subjects.watch.subscribe({
1441
- next: (info) => fieldName(_getWatch(undefined, defaultValue), info),
1432
+ next: (info) => name(_getWatch(undefined, defaultValue), info),
1442
1433
  })
1443
- : _getWatch(fieldName, defaultValue, false, true);
1434
+ : _getWatch(name, defaultValue, true);
1444
1435
  const unregister = (name, options = {}) => {
1445
- for (const inputName of name ? convertToArrayPayload(name) : _names.mount) {
1446
- _names.mount.delete(inputName);
1447
- _names.array.delete(inputName);
1448
- if (get(_fields, inputName)) {
1436
+ for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
1437
+ _names.mount.delete(fieldName);
1438
+ _names.array.delete(fieldName);
1439
+ if (get(_fields, fieldName)) {
1449
1440
  if (!options.keepValue) {
1450
- unset(_fields, inputName);
1451
- unset(_formValues, inputName);
1441
+ unset(_fields, fieldName);
1442
+ unset(_formValues, fieldName);
1452
1443
  }
1453
- !options.keepError && unset(_formState.errors, inputName);
1454
- !options.keepDirty && unset(_formState.dirtyFields, inputName);
1455
- !options.keepTouched && unset(_formState.touchedFields, inputName);
1456
- !formOptions.shouldUnregister &&
1444
+ !options.keepError && unset(_formState.errors, fieldName);
1445
+ !options.keepDirty && unset(_formState.dirtyFields, fieldName);
1446
+ !options.keepTouched && unset(_formState.touchedFields, fieldName);
1447
+ !_options.shouldUnregister &&
1457
1448
  !options.keepDefaultValue &&
1458
- unset(_defaultValues, inputName);
1449
+ unset(_defaultValues, fieldName);
1459
1450
  }
1460
1451
  }
1461
1452
  _subjects.watch.next({});
1462
- _subjects.state.next(Object.assign(Object.assign({}, _formState), (!options.keepDirty ? {} : { isDirty: _getIsDirty() })));
1453
+ _subjects.state.next(Object.assign(Object.assign({}, _formState), (!options.keepDirty ? {} : { isDirty: _getDirty() })));
1463
1454
  !options.keepIsValid && _updateValid();
1464
1455
  };
1465
- const registerFieldRef = (name, fieldRef, options) => {
1466
- register(name, options);
1467
- let field = get(_fields, name);
1468
- const ref = isUndefined(fieldRef.value)
1469
- ? fieldRef.querySelectorAll
1470
- ? fieldRef.querySelectorAll('input,select,textarea')[0] ||
1471
- fieldRef
1472
- : fieldRef
1473
- : fieldRef;
1474
- const isRadioOrCheckbox = isRadioOrCheckboxFunction(ref);
1475
- if (ref === field._f.ref ||
1476
- (isRadioOrCheckbox &&
1477
- compact(field._f.refs || []).find((option) => option === ref))) {
1478
- return;
1479
- }
1480
- field = {
1481
- _f: isRadioOrCheckbox
1482
- ? Object.assign(Object.assign({}, field._f), { refs: [
1483
- ...compact(field._f.refs || []).filter((ref) => isHTMLElement(ref) && document.contains(ref)),
1484
- ref,
1485
- ], ref: { type: ref.type, name } }) : Object.assign(Object.assign({}, field._f), { ref }),
1486
- };
1487
- set(_fields, name, field);
1488
- (!options || !options.disabled) &&
1489
- _updateValidAndInputValue(name, false, ref);
1490
- };
1491
1456
  const register = (name, options = {}) => {
1492
1457
  const field = get(_fields, name);
1493
1458
  set(_fields, name, {
1494
1459
  _f: Object.assign(Object.assign(Object.assign({}, (field && field._f ? field._f : { ref: { name } })), { name, mount: true }), options),
1495
1460
  });
1496
1461
  _names.mount.add(name);
1497
- if (!isUndefined(options.value)) {
1498
- set(_formValues, name, options.value);
1499
- }
1500
- if (field && isBoolean(options.disabled)) {
1501
- set(_formValues, name, options.disabled
1502
- ? undefined
1503
- : get(_formValues, name, getFieldValue(field._f)));
1504
- }
1505
- !field && _updateValidAndInputValue(name, true);
1462
+ !isUndefined(options.value) && set(_formValues, name, options.value);
1463
+ field
1464
+ ? isBoolean(options.disabled) &&
1465
+ set(_formValues, name, options.disabled
1466
+ ? undefined
1467
+ : get(_formValues, name, getFieldValue(field._f)))
1468
+ : updateValidAndValue(name, true);
1506
1469
  return isWindowUndefined
1507
1470
  ? { name: name }
1508
1471
  : Object.assign(Object.assign({ name }, (isBoolean(options.disabled)
1509
1472
  ? { disabled: options.disabled }
1510
1473
  : {})), { onChange: handleChange, onBlur: handleChange, ref: (ref) => {
1511
1474
  if (ref) {
1512
- registerFieldRef(name, ref, options);
1475
+ register(name, options);
1476
+ let field = get(_fields, name);
1477
+ const fieldRef = isUndefined(ref.value)
1478
+ ? ref.querySelectorAll
1479
+ ? ref.querySelectorAll('input,select,textarea')[0] ||
1480
+ ref
1481
+ : ref
1482
+ : ref;
1483
+ const isRadioOrCheckbox = isRadioOrCheckboxFunction(fieldRef);
1484
+ if (fieldRef === field._f.ref ||
1485
+ (isRadioOrCheckbox &&
1486
+ compact(field._f.refs || []).find((option) => option === fieldRef))) {
1487
+ return;
1488
+ }
1489
+ field = {
1490
+ _f: isRadioOrCheckbox
1491
+ ? Object.assign(Object.assign({}, field._f), { refs: [
1492
+ ...compact(field._f.refs || []).filter((ref) => isHTMLElement(ref) && document.contains(ref)),
1493
+ fieldRef,
1494
+ ], ref: { type: fieldRef.type, name } }) : Object.assign(Object.assign({}, field._f), { ref: fieldRef }),
1495
+ };
1496
+ set(_fields, name, field);
1497
+ (!options || !options.disabled) &&
1498
+ updateValidAndValue(name, false, fieldRef);
1513
1499
  }
1514
1500
  else {
1515
1501
  const field = get(_fields, name, {});
1516
- const _shouldUnregister = formOptions.shouldUnregister || options.shouldUnregister;
1502
+ const shouldUnregister = _options.shouldUnregister || options.shouldUnregister;
1517
1503
  if (field._f) {
1518
1504
  field._f.mount = false;
1519
1505
  }
1520
- _shouldUnregister &&
1506
+ shouldUnregister &&
1521
1507
  !(isNameInFieldArray(_names.array, name) && _stateFlags.action) &&
1522
1508
  _names.unMount.add(name);
1523
1509
  }
@@ -1534,13 +1520,13 @@ function createFormControl(props = {}) {
1534
1520
  isSubmitting: true,
1535
1521
  });
1536
1522
  try {
1537
- if (formOptions.resolver) {
1523
+ if (_options.resolver) {
1538
1524
  const { errors, values } = await executeResolver();
1539
1525
  _formState.errors = errors;
1540
1526
  fieldValues = values;
1541
1527
  }
1542
1528
  else {
1543
- await validateForm(_fields);
1529
+ await executeBuildInValidation(_fields);
1544
1530
  }
1545
1531
  if (isEmptyObject(_formState.errors) &&
1546
1532
  Object.keys(_formState.errors).every((name) => get(fieldValues, name))) {
@@ -1552,7 +1538,7 @@ function createFormControl(props = {}) {
1552
1538
  }
1553
1539
  else {
1554
1540
  onInvalid && (await onInvalid(_formState.errors, e));
1555
- formOptions.shouldFocusError &&
1541
+ _options.shouldFocusError &&
1556
1542
  focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
1557
1543
  }
1558
1544
  }
@@ -1573,22 +1559,23 @@ function createFormControl(props = {}) {
1573
1559
  };
1574
1560
  const reset = (formValues, keepStateOptions = {}) => {
1575
1561
  const updatedValues = formValues || _defaultValues;
1576
- const values = cloneObject(updatedValues);
1562
+ const cloneUpdatedValues = cloneObject(updatedValues);
1577
1563
  if (!keepStateOptions.keepValues) {
1578
- _formValues = props.shouldUnregister ? {} : values;
1579
- }
1580
- if (isWeb && !keepStateOptions.keepValues) {
1581
- for (const name of _names.mount) {
1582
- const field = get(_fields, name);
1583
- if (field && field._f) {
1584
- const inputRef = Array.isArray(field._f.refs)
1585
- ? field._f.refs[0]
1586
- : field._f.ref;
1587
- try {
1588
- isHTMLElement(inputRef) && inputRef.closest('form').reset();
1589
- break;
1564
+ _formValues = props.shouldUnregister ? {} : cloneUpdatedValues;
1565
+ if (isWeb) {
1566
+ for (const name of _names.mount) {
1567
+ const field = get(_fields, name);
1568
+ if (field && field._f) {
1569
+ const fieldReference = Array.isArray(field._f.refs)
1570
+ ? field._f.refs[0]
1571
+ : field._f.ref;
1572
+ try {
1573
+ isHTMLElement(fieldReference) &&
1574
+ fieldReference.closest('form').reset();
1575
+ break;
1576
+ }
1577
+ catch (_a) { }
1590
1578
  }
1591
- catch (_a) { }
1592
1579
  }
1593
1580
  }
1594
1581
  }
@@ -1604,7 +1591,7 @@ function createFormControl(props = {}) {
1604
1591
  });
1605
1592
  _subjects.watch.next({});
1606
1593
  _subjects.array.next({
1607
- values,
1594
+ values: cloneUpdatedValues,
1608
1595
  });
1609
1596
  }
1610
1597
  _names = {
@@ -1644,27 +1631,17 @@ function createFormControl(props = {}) {
1644
1631
  _stateFlags.watch = !!props.shouldUnregister;
1645
1632
  };
1646
1633
  const setFocus = (name) => get(_fields, name)._f.ref.focus();
1647
- const _removeFields = () => {
1648
- for (const name of _names.unMount) {
1649
- const field = get(_fields, name);
1650
- field &&
1651
- (field._f.refs ? field._f.refs.every(live) : live(field._f.ref)) &&
1652
- unregister(name);
1653
- }
1654
- _names.unMount = new Set();
1655
- };
1656
1634
  return {
1657
1635
  control: {
1658
1636
  register,
1659
1637
  unregister,
1660
1638
  _getWatch,
1661
- _getIsDirty,
1639
+ _getDirty,
1662
1640
  _updateValid,
1663
- _removeFields,
1641
+ _removeUnmounted,
1664
1642
  _updateFieldArray,
1665
- _getFieldArrayValue,
1643
+ _getFieldArray,
1666
1644
  _subjects,
1667
- _shouldUnregister: formOptions.shouldUnregister,
1668
1645
  _proxyFormState,
1669
1646
  get _fields() {
1670
1647
  return _fields;
@@ -1702,8 +1679,11 @@ function createFormControl(props = {}) {
1702
1679
  set _formState(value) {
1703
1680
  _formState = value;
1704
1681
  },
1705
- _updateProps: (options) => {
1706
- formOptions = Object.assign(Object.assign({}, defaultOptions), options);
1682
+ get _options() {
1683
+ return _options;
1684
+ },
1685
+ set _options(value) {
1686
+ _options = Object.assign(Object.assign({}, _options), value);
1707
1687
  },
1708
1688
  },
1709
1689
  trigger,
@@ -1735,7 +1715,7 @@ function useForm(props = {}) {
1735
1715
  errors: {},
1736
1716
  });
1737
1717
  if (_formControl.current) {
1738
- _formControl.current.control._updateProps(props);
1718
+ _formControl.current.control._options = props;
1739
1719
  }
1740
1720
  else {
1741
1721
  _formControl.current = Object.assign(Object.assign({}, createFormControl(props)), { formState });
@@ -1759,7 +1739,7 @@ function useForm(props = {}) {
1759
1739
  control._stateFlags.watch = false;
1760
1740
  control._subjects.state.next({});
1761
1741
  }
1762
- control._removeFields();
1742
+ control._removeUnmounted();
1763
1743
  });
1764
1744
  _formControl.current.formState = getProxyFormState(formState, control._proxyFormState);
1765
1745
  return _formControl.current;
@@ -1780,11 +1760,12 @@ function useWatch(props) {
1780
1760
  currentName &&
1781
1761
  (name.startsWith(currentName) ||
1782
1762
  currentName.startsWith(name)))) {
1783
- const result = control._getWatch(_name.current, defaultValue, true);
1784
- updateValue(isObject(result)
1785
- ? Object.assign({}, result) : Array.isArray(result)
1786
- ? [...result]
1787
- : result);
1763
+ control._stateFlags.mount = true;
1764
+ const fieldValues = control._getWatch(_name.current, defaultValue);
1765
+ updateValue(isObject(fieldValues)
1766
+ ? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
1767
+ ? [...fieldValues]
1768
+ : fieldValues);
1788
1769
  }
1789
1770
  },
1790
1771
  });
@@ -1792,7 +1773,7 @@ function useWatch(props) {
1792
1773
  ? control._getWatch(name)
1793
1774
  : defaultValue);
1794
1775
  React.useEffect(() => {
1795
- control._removeFields();
1776
+ control._removeUnmounted();
1796
1777
  });
1797
1778
  return value;
1798
1779
  }