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/README.md +6 -0
- package/dist/controller.d.ts +2 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +379 -398
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/types/controller.d.ts +15 -16
- package/dist/types/form.d.ts +5 -6
- package/dist/types/utils.d.ts +2 -5
- package/dist/useController.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
@@ -65,10 +65,9 @@ var omit = (source, key) => {
|
|
65
65
|
return copy;
|
66
66
|
};
|
67
67
|
|
68
|
-
const
|
69
|
-
|
70
|
-
const
|
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.
|
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
|
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.
|
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 =
|
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.
|
389
|
-
control._updateFieldArray(
|
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.
|
396
|
-
control._updateFieldArray(
|
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.
|
403
|
-
control._updateFieldArray(
|
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.
|
409
|
-
control._updateFieldArray(
|
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.
|
415
|
+
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
417
416
|
swapArrayAt(updatedFieldArrayValuesWithKey, indexA, indexB);
|
418
|
-
control._updateFieldArray(
|
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.
|
423
|
+
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
425
424
|
moveArrayAt(updatedFieldArrayValuesWithKey, from, to);
|
426
|
-
control._updateFieldArray(
|
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.
|
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(
|
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(
|
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.
|
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 ((
|
530
|
-
(isObject(
|
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
|
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 =
|
992
|
-
let _formValues =
|
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
|
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
|
1023
|
-
const
|
1024
|
-
const
|
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(
|
1027
|
-
|
1026
|
+
clearTimeout(timer);
|
1027
|
+
timer = window.setTimeout(() => callback(...args), wait);
|
1028
1028
|
};
|
1029
|
-
const isFieldWatched = (name) =>
|
1030
|
-
_names.
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
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
|
1039
|
-
|
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
|
-
|
1043
|
-
|
1044
|
-
|
1130
|
+
delayErrorCallback =
|
1131
|
+
delayErrorCallback || debounce(updateErrors, props.delayError);
|
1132
|
+
delayErrorCallback(name, error);
|
1045
1133
|
}
|
1046
1134
|
else {
|
1047
|
-
clearTimeout(
|
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(
|
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
|
-
|
1061
|
-
if (_proxyFormState.isValidating && !
|
1148
|
+
validateFields[name]--;
|
1149
|
+
if (_proxyFormState.isValidating && !validateFields[name]) {
|
1062
1150
|
_subjects.state.next({
|
1063
1151
|
isValidating: false,
|
1064
1152
|
});
|
1065
|
-
|
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
|
1073
|
-
if (
|
1074
|
-
set(_formValues, name, getFieldValueAs(value,
|
1234
|
+
const fieldReference = field._f;
|
1235
|
+
if (fieldReference) {
|
1236
|
+
set(_formValues, name, getFieldValueAs(value, fieldReference));
|
1075
1237
|
fieldValue =
|
1076
|
-
isWeb && isHTMLElement(
|
1238
|
+
isWeb && isHTMLElement(fieldReference.ref) && isNullOrUndefined(value)
|
1077
1239
|
? ''
|
1078
1240
|
: value;
|
1079
|
-
if (
|
1080
|
-
|
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 (
|
1086
|
-
if (isCheckBoxInput(
|
1087
|
-
|
1088
|
-
?
|
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
|
-
: (
|
1250
|
+
: (fieldReference.refs[0].checked = !!fieldValue);
|
1092
1251
|
}
|
1093
1252
|
else {
|
1094
|
-
|
1253
|
+
fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
|
1095
1254
|
}
|
1096
1255
|
}
|
1097
1256
|
else {
|
1098
|
-
|
1257
|
+
fieldReference.ref.value = fieldValue;
|
1099
1258
|
}
|
1100
|
-
|
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
|
-
|
1267
|
+
updateTouchAndDirty(name, fieldValue, options.shouldTouch);
|
1110
1268
|
options.shouldValidate && trigger(name);
|
1111
1269
|
};
|
1112
|
-
const
|
1113
|
-
const
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
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
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
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
|
-
|
1162
|
-
|
1163
|
-
|
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
|
-
|
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
|
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
|
-
|
1209
|
-
|
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
|
-
|
1346
|
+
validateFields[name] = validateFields[name] ? +1 : 1;
|
1228
1347
|
_proxyFormState.isValidating &&
|
1229
1348
|
_subjects.state.next({
|
1230
1349
|
isValidating: true,
|
1231
1350
|
});
|
1232
|
-
if (
|
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),
|
1367
|
+
error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1249
1368
|
isValid = await _updateValid(true);
|
1250
1369
|
}
|
1251
|
-
|
1252
|
-
|
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 (
|
1391
|
-
const
|
1392
|
-
isValid = isEmptyObject(
|
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(
|
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
|
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
|
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
|
-
|
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 = (
|
1430
|
+
const watch = (name, defaultValue) => isFunction(name)
|
1440
1431
|
? _subjects.watch.subscribe({
|
1441
|
-
next: (info) =>
|
1432
|
+
next: (info) => name(_getWatch(undefined, defaultValue), info),
|
1442
1433
|
})
|
1443
|
-
: _getWatch(
|
1434
|
+
: _getWatch(name, defaultValue, true);
|
1444
1435
|
const unregister = (name, options = {}) => {
|
1445
|
-
for (const
|
1446
|
-
_names.mount.delete(
|
1447
|
-
_names.array.delete(
|
1448
|
-
if (get(_fields,
|
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,
|
1451
|
-
unset(_formValues,
|
1441
|
+
unset(_fields, fieldName);
|
1442
|
+
unset(_formValues, fieldName);
|
1452
1443
|
}
|
1453
|
-
!options.keepError && unset(_formState.errors,
|
1454
|
-
!options.keepDirty && unset(_formState.dirtyFields,
|
1455
|
-
!options.keepTouched && unset(_formState.touchedFields,
|
1456
|
-
!
|
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,
|
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:
|
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
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
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
|
-
|
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
|
1502
|
+
const shouldUnregister = _options.shouldUnregister || options.shouldUnregister;
|
1517
1503
|
if (field._f) {
|
1518
1504
|
field._f.mount = false;
|
1519
1505
|
}
|
1520
|
-
|
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 (
|
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
|
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
|
-
|
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
|
1562
|
+
const cloneUpdatedValues = cloneObject(updatedValues);
|
1577
1563
|
if (!keepStateOptions.keepValues) {
|
1578
|
-
_formValues = props.shouldUnregister ? {} :
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
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
|
-
|
1639
|
+
_getDirty,
|
1662
1640
|
_updateValid,
|
1663
|
-
|
1641
|
+
_removeUnmounted,
|
1664
1642
|
_updateFieldArray,
|
1665
|
-
|
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
|
-
|
1706
|
-
|
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.
|
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.
|
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
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
?
|
1787
|
-
|
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.
|
1776
|
+
control._removeUnmounted();
|
1796
1777
|
});
|
1797
1778
|
return value;
|
1798
1779
|
}
|