react-hook-form 7.16.1 → 7.17.2
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 +18 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +439 -451
- 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/logic/getFocusFieldName.d.ts +1 -1
- package/dist/types/controller.d.ts +6 -8
- package/dist/types/fields.d.ts +2 -2
- package/dist/types/form.d.ts +8 -9
- package/dist/types/utils.d.ts +16 -8
- package/dist/useSubscribe.d.ts +3 -2
- package/dist/utils/Subject.d.ts +3 -2
- package/package.json +10 -10
- package/CHANGELOG.md +0 -1133
- package/dist/logic/getMultipleSelectValue.d.ts +0 -2
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) {
|
@@ -104,27 +103,33 @@ var shouldRenderFormState = (formStateData, _proxyFormState, isRoot) => {
|
|
104
103
|
|
105
104
|
var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value];
|
106
105
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
if (_subscription.current) {
|
112
|
-
_unSubscribe.current && _unSubscribe.current.unsubscribe();
|
113
|
-
_subscription.current = _unSubscribe.current = undefined;
|
114
|
-
}
|
106
|
+
const tearDown = (_unsubscribe) => {
|
107
|
+
if (_unsubscribe.current) {
|
108
|
+
_unsubscribe.current.unsubscribe();
|
109
|
+
_unsubscribe.current = undefined;
|
115
110
|
}
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
}
|
111
|
+
};
|
112
|
+
const updateSubscriptionProps = ({ _unsubscribe, props }) => () => {
|
113
|
+
if (props.disabled) {
|
114
|
+
tearDown(_unsubscribe);
|
115
|
+
}
|
116
|
+
else if (!_unsubscribe.current) {
|
117
|
+
_unsubscribe.current = props.subject.subscribe({
|
118
|
+
next: props.callback,
|
119
|
+
});
|
125
120
|
}
|
126
|
-
|
127
|
-
|
121
|
+
};
|
122
|
+
function useSubscribe(props) {
|
123
|
+
const _unsubscribe = React.useRef();
|
124
|
+
const _updateSubscription = React.useRef(() => { });
|
125
|
+
_updateSubscription.current = updateSubscriptionProps({
|
126
|
+
_unsubscribe,
|
127
|
+
props,
|
128
|
+
});
|
129
|
+
!props.skipEarlySubscription && _updateSubscription.current();
|
130
|
+
React.useEffect(() => {
|
131
|
+
_updateSubscription.current();
|
132
|
+
return () => tearDown(_unsubscribe);
|
128
133
|
}, []);
|
129
134
|
}
|
130
135
|
|
@@ -167,7 +172,7 @@ function useController(props) {
|
|
167
172
|
useSubscribe({
|
168
173
|
subject: control._subjects.control,
|
169
174
|
callback: (data) => (!data.name || _name.current === data.name) &&
|
170
|
-
setInputStateValue(get(data.values,
|
175
|
+
setInputStateValue(get(data.values, _name.current)),
|
171
176
|
});
|
172
177
|
const registerProps = control.register(name, Object.assign(Object.assign({}, props.rules), { value }));
|
173
178
|
const updateMounted = React.useCallback((name, value) => {
|
@@ -179,7 +184,7 @@ function useController(props) {
|
|
179
184
|
React.useEffect(() => {
|
180
185
|
updateMounted(name, true);
|
181
186
|
return () => {
|
182
|
-
const _shouldUnregisterField = control.
|
187
|
+
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
183
188
|
if (isNameInFieldArray(control._names.array, name)
|
184
189
|
? _shouldUnregisterField && !control._stateFlags.action
|
185
190
|
: _shouldUnregisterField) {
|
@@ -289,9 +294,10 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
289
294
|
}
|
290
295
|
};
|
291
296
|
|
292
|
-
var getFocusFieldName = (name, index, options) => options
|
293
|
-
? options.focusName ||
|
294
|
-
|
297
|
+
var getFocusFieldName = (name, index, options = {}) => options.shouldFocus || isUndefined(options.shouldFocus)
|
298
|
+
? options.focusName ||
|
299
|
+
`${name}.${isUndefined(options.focusIndex) ? index : options.focusIndex}.`
|
300
|
+
: '';
|
295
301
|
|
296
302
|
var mapCurrentIds = (values, _fieldIds, keyName) => values.map((value, index) => {
|
297
303
|
const output = _fieldIds.current[index];
|
@@ -333,7 +339,7 @@ var moveArrayAt = (data, from, to) => {
|
|
333
339
|
return [];
|
334
340
|
};
|
335
341
|
|
336
|
-
var
|
342
|
+
var omitKeys = (fields, keyName) => fields.map((field = {}) => omit(field, keyName));
|
337
343
|
|
338
344
|
function prepend(data, value) {
|
339
345
|
return [...convertToArrayPayload(value), ...convertToArrayPayload(data)];
|
@@ -364,81 +370,84 @@ var updateAt = (fieldValues, index, value) => {
|
|
364
370
|
const useFieldArray = (props) => {
|
365
371
|
const methods = useFormContext();
|
366
372
|
const { control = methods.control, name, keyName = 'id', shouldUnregister, } = props;
|
367
|
-
const [fields, setFields] = React.useState(mapIds(control.
|
373
|
+
const [fields, setFields] = React.useState(mapIds(control._getFieldArray(name), keyName));
|
368
374
|
const _fieldIds = React.useRef(fields);
|
375
|
+
const _name = React.useRef(name);
|
376
|
+
_name.current = name;
|
377
|
+
_fieldIds.current = fields;
|
378
|
+
control._names.array.add(name);
|
369
379
|
useSubscribe({
|
370
380
|
callback: ({ values, name: fieldArrayName }) => {
|
371
|
-
if (fieldArrayName ===
|
372
|
-
setFields(mapIds(get(values,
|
381
|
+
if (fieldArrayName === _name.current || !fieldArrayName) {
|
382
|
+
setFields(mapIds(get(values, _name.current), keyName));
|
373
383
|
}
|
374
384
|
},
|
375
385
|
subject: control._subjects.array,
|
386
|
+
skipEarlySubscription: true,
|
376
387
|
});
|
377
|
-
_fieldIds.current = fields;
|
378
|
-
control._names.array.add(name);
|
379
388
|
const updateValues = React.useCallback((updatedFieldArrayValuesWithKey) => {
|
380
|
-
const updatedFieldArrayValues =
|
389
|
+
const updatedFieldArrayValues = omitKeys(updatedFieldArrayValuesWithKey, keyName);
|
381
390
|
set(control._formValues, name, updatedFieldArrayValues);
|
382
391
|
setFields(updatedFieldArrayValuesWithKey);
|
383
392
|
return updatedFieldArrayValues;
|
384
393
|
}, [control, name, keyName]);
|
385
394
|
const append$1 = (value, options) => {
|
386
395
|
const appendValue = convertToArrayPayload(value);
|
387
|
-
const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control.
|
388
|
-
control._updateFieldArray(
|
396
|
+
const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(appendValue, keyName));
|
397
|
+
control._updateFieldArray(name, append, {
|
389
398
|
argA: fillEmptyArray(value),
|
390
399
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
391
400
|
control._names.focus = getFocusFieldName(name, updatedFieldArrayValuesWithKey.length - appendValue.length, options);
|
392
401
|
};
|
393
402
|
const prepend$1 = (value, options) => {
|
394
|
-
const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control.
|
395
|
-
control._updateFieldArray(
|
403
|
+
const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(convertToArrayPayload(value), keyName));
|
404
|
+
control._updateFieldArray(name, prepend, {
|
396
405
|
argA: fillEmptyArray(value),
|
397
406
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
398
407
|
control._names.focus = getFocusFieldName(name, 0, options);
|
399
408
|
};
|
400
409
|
const remove = (index) => {
|
401
|
-
const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control.
|
402
|
-
control._updateFieldArray(
|
410
|
+
const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index);
|
411
|
+
control._updateFieldArray(name, removeArrayAt, {
|
403
412
|
argA: index,
|
404
413
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
405
414
|
};
|
406
415
|
const insert$1 = (index, value, options) => {
|
407
|
-
const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control.
|
408
|
-
control._updateFieldArray(
|
416
|
+
const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index, mapIds(convertToArrayPayload(value), keyName));
|
417
|
+
control._updateFieldArray(name, insert, {
|
409
418
|
argA: index,
|
410
419
|
argB: fillEmptyArray(value),
|
411
420
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
412
421
|
control._names.focus = getFocusFieldName(name, index, options);
|
413
422
|
};
|
414
423
|
const swap = (indexA, indexB) => {
|
415
|
-
const updatedFieldArrayValuesWithKey = mapCurrentIds(control.
|
424
|
+
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
416
425
|
swapArrayAt(updatedFieldArrayValuesWithKey, indexA, indexB);
|
417
|
-
control._updateFieldArray(
|
426
|
+
control._updateFieldArray(name, swapArrayAt, {
|
418
427
|
argA: indexA,
|
419
428
|
argB: indexB,
|
420
429
|
}, updateValues(updatedFieldArrayValuesWithKey), false);
|
421
430
|
};
|
422
431
|
const move = (from, to) => {
|
423
|
-
const updatedFieldArrayValuesWithKey = mapCurrentIds(control.
|
432
|
+
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
424
433
|
moveArrayAt(updatedFieldArrayValuesWithKey, from, to);
|
425
|
-
control._updateFieldArray(
|
434
|
+
control._updateFieldArray(name, moveArrayAt, {
|
426
435
|
argA: from,
|
427
436
|
argB: to,
|
428
437
|
}, updateValues(updatedFieldArrayValuesWithKey), false);
|
429
438
|
};
|
430
439
|
const update = (index, value) => {
|
431
|
-
const updatedFieldArrayValuesWithKey = mapCurrentIds(control.
|
440
|
+
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
432
441
|
const updatedFieldArrayValues = updateAt(updatedFieldArrayValuesWithKey, index, value);
|
433
442
|
_fieldIds.current = mapIds(updatedFieldArrayValues, keyName);
|
434
|
-
control._updateFieldArray(
|
443
|
+
control._updateFieldArray(name, updateAt, {
|
435
444
|
argA: index,
|
436
445
|
argB: value,
|
437
446
|
}, updateValues(_fieldIds.current), true, false);
|
438
447
|
};
|
439
448
|
const replace = (value) => {
|
440
449
|
const updatedFieldArrayValuesWithKey = mapIds(convertToArrayPayload(value), keyName);
|
441
|
-
control._updateFieldArray(
|
450
|
+
control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
|
442
451
|
};
|
443
452
|
React.useEffect(() => {
|
444
453
|
control._stateFlags.action = false;
|
@@ -465,7 +474,7 @@ const useFieldArray = (props) => {
|
|
465
474
|
React.useEffect(() => {
|
466
475
|
!get(control._formValues, name) && set(control._formValues, name, []);
|
467
476
|
return () => {
|
468
|
-
if (control.
|
477
|
+
if (control._options.shouldUnregister || shouldUnregister) {
|
469
478
|
control.unregister(name);
|
470
479
|
}
|
471
480
|
};
|
@@ -483,6 +492,8 @@ const useFieldArray = (props) => {
|
|
483
492
|
};
|
484
493
|
};
|
485
494
|
|
495
|
+
var isFunction = (value) => typeof value === 'function';
|
496
|
+
|
486
497
|
function cloneObject(data) {
|
487
498
|
let copy;
|
488
499
|
const isArray = Array.isArray(data);
|
@@ -495,6 +506,10 @@ function cloneObject(data) {
|
|
495
506
|
else if (isArray || isObject(data)) {
|
496
507
|
copy = isArray ? [] : {};
|
497
508
|
for (const key in data) {
|
509
|
+
if (isFunction(data[key])) {
|
510
|
+
copy = data;
|
511
|
+
break;
|
512
|
+
}
|
498
513
|
copy[key] = cloneObject(data[key]);
|
499
514
|
}
|
500
515
|
}
|
@@ -507,12 +522,12 @@ function cloneObject(data) {
|
|
507
522
|
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
508
523
|
|
509
524
|
function deepEqual(object1, object2) {
|
510
|
-
if (isPrimitive(object1) ||
|
511
|
-
isPrimitive(object2) ||
|
512
|
-
isDateObject(object1) ||
|
513
|
-
isDateObject(object2)) {
|
525
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
514
526
|
return object1 === object2;
|
515
527
|
}
|
528
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
529
|
+
return object1.getTime() === object2.getTime();
|
530
|
+
}
|
516
531
|
const keys1 = Object.keys(object1);
|
517
532
|
const keys2 = Object.keys(object2);
|
518
533
|
if (keys1.length !== keys2.length) {
|
@@ -525,8 +540,9 @@ function deepEqual(object1, object2) {
|
|
525
540
|
}
|
526
541
|
if (key !== 'ref') {
|
527
542
|
const val2 = object2[key];
|
528
|
-
if ((
|
529
|
-
(isObject(
|
543
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
544
|
+
(isObject(val1) && isObject(val2)) ||
|
545
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
530
546
|
? !deepEqual(val1, val2)
|
531
547
|
: val1 !== val2) {
|
532
548
|
return false;
|
@@ -546,10 +562,6 @@ var getValidationModes = (mode) => ({
|
|
546
562
|
|
547
563
|
var isBoolean = (value) => typeof value === 'boolean';
|
548
564
|
|
549
|
-
var isFileInput = (element) => element.type === 'file';
|
550
|
-
|
551
|
-
var isFunction = (value) => typeof value === 'function';
|
552
|
-
|
553
565
|
var isHTMLElement = (value) => value instanceof HTMLElement;
|
554
566
|
|
555
567
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
@@ -651,6 +663,8 @@ function unset(object, path) {
|
|
651
663
|
return object;
|
652
664
|
}
|
653
665
|
|
666
|
+
var isFileInput = (element) => element.type === 'file';
|
667
|
+
|
654
668
|
const defaultResult = {
|
655
669
|
value: false,
|
656
670
|
isValid: false,
|
@@ -688,10 +702,6 @@ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isU
|
|
688
702
|
? setValueAs(value)
|
689
703
|
: value;
|
690
704
|
|
691
|
-
var getMultipleSelectValue = (options) => [...options]
|
692
|
-
.filter(({ selected }) => selected)
|
693
|
-
.map(({ value }) => value);
|
694
|
-
|
695
705
|
const defaultReturn = {
|
696
706
|
isValid: false,
|
697
707
|
value: null,
|
@@ -717,7 +727,7 @@ function getFieldValue(_f) {
|
|
717
727
|
return getRadioValue(_f.refs).value;
|
718
728
|
}
|
719
729
|
if (isMultipleSelect(ref)) {
|
720
|
-
return
|
730
|
+
return [...ref.selectedOptions].map(({ value }) => value);
|
721
731
|
}
|
722
732
|
if (isCheckBoxInput(ref)) {
|
723
733
|
return getCheckboxValue(_f.refs).value;
|
@@ -976,8 +986,7 @@ const defaultOptions = {
|
|
976
986
|
};
|
977
987
|
const isWindowUndefined = typeof window === 'undefined';
|
978
988
|
function createFormControl(props = {}) {
|
979
|
-
let
|
980
|
-
let _delayCallback;
|
989
|
+
let _options = Object.assign(Object.assign({}, defaultOptions), props);
|
981
990
|
let _formState = {
|
982
991
|
isDirty: false,
|
983
992
|
isValidating: false,
|
@@ -991,8 +1000,8 @@ function createFormControl(props = {}) {
|
|
991
1000
|
errors: {},
|
992
1001
|
};
|
993
1002
|
let _fields = {};
|
994
|
-
let _defaultValues =
|
995
|
-
let _formValues =
|
1003
|
+
let _defaultValues = _options.defaultValues || {};
|
1004
|
+
let _formValues = _options.shouldUnregister
|
996
1005
|
? {}
|
997
1006
|
: cloneObject(_defaultValues);
|
998
1007
|
let _stateFlags = {
|
@@ -1000,14 +1009,15 @@ function createFormControl(props = {}) {
|
|
1000
1009
|
mount: false,
|
1001
1010
|
watch: false,
|
1002
1011
|
};
|
1003
|
-
let _timer = 0;
|
1004
1012
|
let _names = {
|
1005
1013
|
mount: new Set(),
|
1006
1014
|
unMount: new Set(),
|
1007
1015
|
array: new Set(),
|
1008
1016
|
watch: new Set(),
|
1009
1017
|
};
|
1010
|
-
let
|
1018
|
+
let delayErrorCallback;
|
1019
|
+
let timer = 0;
|
1020
|
+
let validateFields = {};
|
1011
1021
|
const _proxyFormState = {
|
1012
1022
|
isDirty: false,
|
1013
1023
|
dirtyFields: false,
|
@@ -1022,37 +1032,125 @@ function createFormControl(props = {}) {
|
|
1022
1032
|
array: new Subject(),
|
1023
1033
|
state: new Subject(),
|
1024
1034
|
};
|
1025
|
-
const
|
1026
|
-
const
|
1027
|
-
const
|
1035
|
+
const validationModeBeforeSubmit = getValidationModes(_options.mode);
|
1036
|
+
const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
1037
|
+
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
1028
1038
|
const debounce = (callback, wait) => (...args) => {
|
1029
|
-
clearTimeout(
|
1030
|
-
|
1039
|
+
clearTimeout(timer);
|
1040
|
+
timer = window.setTimeout(() => callback(...args), wait);
|
1041
|
+
};
|
1042
|
+
const isFieldWatched = (name, isBlurEvent) => !isBlurEvent &&
|
1043
|
+
(_names.watchAll ||
|
1044
|
+
_names.watch.has(name) ||
|
1045
|
+
_names.watch.has((name.match(/\w+/) || [])[0]));
|
1046
|
+
const _updateValid = async (shouldSkipRender) => {
|
1047
|
+
let isValid = false;
|
1048
|
+
if (_proxyFormState.isValid) {
|
1049
|
+
isValid = _options.resolver
|
1050
|
+
? isEmptyObject((await executeResolver()).errors)
|
1051
|
+
: await executeBuildInValidation(_fields, true);
|
1052
|
+
if (!shouldSkipRender && isValid !== _formState.isValid) {
|
1053
|
+
_formState.isValid = isValid;
|
1054
|
+
_subjects.state.next({
|
1055
|
+
isValid,
|
1056
|
+
});
|
1057
|
+
}
|
1058
|
+
}
|
1059
|
+
return isValid;
|
1031
1060
|
};
|
1032
|
-
const
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1061
|
+
const _updateFieldArray = (name, method, args, values = [], shouldSetValues = true, shouldSetFields = true) => {
|
1062
|
+
_stateFlags.action = true;
|
1063
|
+
if (shouldSetFields && get(_fields, name)) {
|
1064
|
+
const fieldValues = method(get(_fields, name), args.argA, args.argB);
|
1065
|
+
shouldSetValues && set(_fields, name, fieldValues);
|
1066
|
+
}
|
1067
|
+
if (Array.isArray(get(_formState.errors, name))) {
|
1068
|
+
const errors = method(get(_formState.errors, name), args.argA, args.argB);
|
1069
|
+
shouldSetValues && set(_formState.errors, name, errors);
|
1070
|
+
unsetEmptyArray(_formState.errors, name);
|
1071
|
+
}
|
1072
|
+
if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
|
1073
|
+
const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
1074
|
+
shouldSetValues &&
|
1075
|
+
set(_formState.touchedFields, name, touchedFields);
|
1076
|
+
unsetEmptyArray(_formState.touchedFields, name);
|
1077
|
+
}
|
1078
|
+
if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
|
1079
|
+
updateFieldArrayDirty(name, values);
|
1080
|
+
}
|
1037
1081
|
_subjects.state.next({
|
1082
|
+
isDirty: _getDirty(name, values),
|
1083
|
+
dirtyFields: _formState.dirtyFields,
|
1038
1084
|
errors: _formState.errors,
|
1085
|
+
isValid: _formState.isValid,
|
1039
1086
|
});
|
1040
1087
|
};
|
1041
|
-
const
|
1042
|
-
|
1088
|
+
const updateErrors = (name, error) => (set(_formState.errors, name, error),
|
1089
|
+
_subjects.state.next({
|
1090
|
+
errors: _formState.errors,
|
1091
|
+
}));
|
1092
|
+
const updateValidAndValue = (name, shouldSkipSetValueAs, ref) => {
|
1093
|
+
const field = get(_fields, name);
|
1094
|
+
if (field) {
|
1095
|
+
const defaultValue = get(_formValues, name, get(_defaultValues, name));
|
1096
|
+
isUndefined(defaultValue) ||
|
1097
|
+
(ref && ref.defaultChecked) ||
|
1098
|
+
shouldSkipSetValueAs
|
1099
|
+
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
1100
|
+
: setFieldValue(name, defaultValue);
|
1101
|
+
}
|
1102
|
+
_stateFlags.mount && _updateValid();
|
1103
|
+
};
|
1104
|
+
const updateTouchAndDirty = (name, fieldValue, isCurrentTouched, shouldRender = true) => {
|
1105
|
+
let isFieldDirty = false;
|
1106
|
+
const output = {
|
1107
|
+
name,
|
1108
|
+
};
|
1109
|
+
const isPreviousFieldTouched = get(_formState.touchedFields, name);
|
1110
|
+
if (_proxyFormState.isDirty) {
|
1111
|
+
const isPreviousFormDirty = _formState.isDirty;
|
1112
|
+
_formState.isDirty = output.isDirty = _getDirty();
|
1113
|
+
isFieldDirty = isPreviousFormDirty !== output.isDirty;
|
1114
|
+
}
|
1115
|
+
if (_proxyFormState.dirtyFields && !isCurrentTouched) {
|
1116
|
+
const isPreviousFieldDirty = get(_formState.dirtyFields, name);
|
1117
|
+
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
1118
|
+
isCurrentFieldPristine
|
1119
|
+
? unset(_formState.dirtyFields, name)
|
1120
|
+
: set(_formState.dirtyFields, name, true);
|
1121
|
+
output.dirtyFields = _formState.dirtyFields;
|
1122
|
+
isFieldDirty =
|
1123
|
+
isFieldDirty ||
|
1124
|
+
isPreviousFieldDirty !== get(_formState.dirtyFields, name);
|
1125
|
+
}
|
1126
|
+
if (isCurrentTouched && !isPreviousFieldTouched) {
|
1127
|
+
set(_formState.touchedFields, name, isCurrentTouched);
|
1128
|
+
output.touchedFields = _formState.touchedFields;
|
1129
|
+
isFieldDirty =
|
1130
|
+
isFieldDirty ||
|
1131
|
+
(_proxyFormState.touchedFields &&
|
1132
|
+
isPreviousFieldTouched !== isCurrentTouched);
|
1133
|
+
}
|
1134
|
+
isFieldDirty && shouldRender && _subjects.state.next(output);
|
1135
|
+
return isFieldDirty ? output : {};
|
1136
|
+
};
|
1137
|
+
const updateFieldArrayDirty = (name, value) => (set(_formState.dirtyFields, name, setFieldArrayDirtyFields(value, get(_defaultValues, name, []), get(_formState.dirtyFields, name, []))),
|
1138
|
+
unsetEmptyArray(_formState.dirtyFields, name));
|
1139
|
+
const shouldRenderByError = async (shouldSkipRender, name, isValid, error, fieldState) => {
|
1140
|
+
const previousFieldError = get(_formState.errors, name);
|
1043
1141
|
const shouldUpdateValid = _proxyFormState.isValid && _formState.isValid !== isValid;
|
1044
1142
|
if (props.delayError && error) {
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1143
|
+
delayErrorCallback =
|
1144
|
+
delayErrorCallback || debounce(updateErrors, props.delayError);
|
1145
|
+
delayErrorCallback(name, error);
|
1048
1146
|
}
|
1049
1147
|
else {
|
1050
|
-
clearTimeout(
|
1148
|
+
clearTimeout(timer);
|
1051
1149
|
error
|
1052
1150
|
? set(_formState.errors, name, error)
|
1053
1151
|
: unset(_formState.errors, name);
|
1054
1152
|
}
|
1055
|
-
if (((error ? !deepEqual(
|
1153
|
+
if (((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
|
1056
1154
|
!isEmptyObject(fieldState) ||
|
1057
1155
|
shouldUpdateValid) &&
|
1058
1156
|
!shouldSkipRender) {
|
@@ -1060,138 +1158,169 @@ function createFormControl(props = {}) {
|
|
1060
1158
|
_formState = Object.assign(Object.assign({}, _formState), updatedFormState);
|
1061
1159
|
_subjects.state.next(updatedFormState);
|
1062
1160
|
}
|
1063
|
-
|
1064
|
-
if (_proxyFormState.isValidating && !
|
1161
|
+
validateFields[name]--;
|
1162
|
+
if (_proxyFormState.isValidating && !validateFields[name]) {
|
1065
1163
|
_subjects.state.next({
|
1066
1164
|
isValidating: false,
|
1067
1165
|
});
|
1068
|
-
|
1166
|
+
validateFields = {};
|
1069
1167
|
}
|
1070
1168
|
};
|
1169
|
+
const executeResolver = async (name) => _options.resolver
|
1170
|
+
? await _options.resolver(Object.assign({}, _formValues), _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
|
1171
|
+
: {};
|
1172
|
+
const executeResolverValidation = async (names) => {
|
1173
|
+
const { errors } = await executeResolver();
|
1174
|
+
if (names) {
|
1175
|
+
for (const name of names) {
|
1176
|
+
const error = get(errors, name);
|
1177
|
+
error
|
1178
|
+
? set(_formState.errors, name, error)
|
1179
|
+
: unset(_formState.errors, name);
|
1180
|
+
}
|
1181
|
+
}
|
1182
|
+
else {
|
1183
|
+
_formState.errors = errors;
|
1184
|
+
}
|
1185
|
+
return errors;
|
1186
|
+
};
|
1187
|
+
const executeBuildInValidation = async (fields, shouldOnlyCheckValid, context = {
|
1188
|
+
valid: true,
|
1189
|
+
}) => {
|
1190
|
+
for (const name in fields) {
|
1191
|
+
const field = fields[name];
|
1192
|
+
if (field) {
|
1193
|
+
const fieldReference = field._f;
|
1194
|
+
const fieldValue = omit(field, '_f');
|
1195
|
+
if (fieldReference) {
|
1196
|
+
const fieldError = await validateField(field, get(_formValues, fieldReference.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation);
|
1197
|
+
if (fieldError[fieldReference.name]) {
|
1198
|
+
context.valid = false;
|
1199
|
+
if (shouldOnlyCheckValid) {
|
1200
|
+
break;
|
1201
|
+
}
|
1202
|
+
}
|
1203
|
+
if (!shouldOnlyCheckValid) {
|
1204
|
+
fieldError[fieldReference.name]
|
1205
|
+
? set(_formState.errors, fieldReference.name, fieldError[fieldReference.name])
|
1206
|
+
: unset(_formState.errors, fieldReference.name);
|
1207
|
+
}
|
1208
|
+
}
|
1209
|
+
fieldValue &&
|
1210
|
+
(await executeBuildInValidation(fieldValue, shouldOnlyCheckValid, context));
|
1211
|
+
}
|
1212
|
+
}
|
1213
|
+
return context.valid;
|
1214
|
+
};
|
1215
|
+
const _removeUnmounted = () => {
|
1216
|
+
for (const name of _names.unMount) {
|
1217
|
+
const field = get(_fields, name);
|
1218
|
+
field &&
|
1219
|
+
(field._f.refs ? field._f.refs.every(live) : live(field._f.ref)) &&
|
1220
|
+
unregister(name);
|
1221
|
+
}
|
1222
|
+
_names.unMount = new Set();
|
1223
|
+
};
|
1224
|
+
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
1225
|
+
!deepEqual(getValues(), _defaultValues));
|
1226
|
+
const _getWatch = (names, defaultValue, isGlobal) => {
|
1227
|
+
const fieldValues = Object.assign({}, (_stateFlags.mount
|
1228
|
+
? _formValues
|
1229
|
+
: isUndefined(defaultValue)
|
1230
|
+
? _defaultValues
|
1231
|
+
: isString(names)
|
1232
|
+
? { [names]: defaultValue }
|
1233
|
+
: defaultValue));
|
1234
|
+
if (names) {
|
1235
|
+
const result = convertToArrayPayload(names).map((fieldName) => (isGlobal && _names.watch.add(fieldName),
|
1236
|
+
get(fieldValues, fieldName)));
|
1237
|
+
return Array.isArray(names) ? result : result[0];
|
1238
|
+
}
|
1239
|
+
isGlobal && (_names.watchAll = true);
|
1240
|
+
return fieldValues;
|
1241
|
+
};
|
1242
|
+
const _getFieldArray = (name) => get(_stateFlags.mount ? _formValues : _defaultValues, name, []);
|
1071
1243
|
const setFieldValue = (name, value, options = {}, shouldRender) => {
|
1072
1244
|
const field = get(_fields, name);
|
1073
1245
|
let fieldValue = value;
|
1074
1246
|
if (field) {
|
1075
|
-
const
|
1076
|
-
if (
|
1077
|
-
set(_formValues, name, getFieldValueAs(value,
|
1247
|
+
const fieldReference = field._f;
|
1248
|
+
if (fieldReference) {
|
1249
|
+
set(_formValues, name, getFieldValueAs(value, fieldReference));
|
1078
1250
|
fieldValue =
|
1079
|
-
isWeb && isHTMLElement(
|
1251
|
+
isWeb && isHTMLElement(fieldReference.ref) && isNullOrUndefined(value)
|
1080
1252
|
? ''
|
1081
1253
|
: value;
|
1082
|
-
if (
|
1083
|
-
|
1254
|
+
if (isMultipleSelect(fieldReference.ref)) {
|
1255
|
+
[...fieldReference.ref.options].forEach((selectRef) => (selectRef.selected = fieldValue.includes(selectRef.value)));
|
1084
1256
|
}
|
1085
|
-
else if (
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
if (isCheckBoxInput(_f.ref)) {
|
1090
|
-
_f.refs.length > 1
|
1091
|
-
? _f.refs.forEach((checkboxRef) => (checkboxRef.checked = Array.isArray(fieldValue)
|
1257
|
+
else if (fieldReference.refs) {
|
1258
|
+
if (isCheckBoxInput(fieldReference.ref)) {
|
1259
|
+
fieldReference.refs.length > 1
|
1260
|
+
? fieldReference.refs.forEach((checkboxRef) => (checkboxRef.checked = Array.isArray(fieldValue)
|
1092
1261
|
? !!fieldValue.find((data) => data === checkboxRef.value)
|
1093
1262
|
: fieldValue === checkboxRef.value))
|
1094
|
-
: (
|
1263
|
+
: (fieldReference.refs[0].checked = !!fieldValue);
|
1095
1264
|
}
|
1096
1265
|
else {
|
1097
|
-
|
1266
|
+
fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
|
1098
1267
|
}
|
1099
1268
|
}
|
1100
1269
|
else {
|
1101
|
-
|
1270
|
+
fieldReference.ref.value = fieldValue;
|
1102
1271
|
}
|
1103
|
-
|
1272
|
+
shouldRender &&
|
1104
1273
|
_subjects.control.next({
|
1105
1274
|
values: _formValues,
|
1106
1275
|
name,
|
1107
1276
|
});
|
1108
|
-
}
|
1109
1277
|
}
|
1110
1278
|
}
|
1111
1279
|
(options.shouldDirty || options.shouldTouch) &&
|
1112
|
-
|
1280
|
+
updateTouchAndDirty(name, fieldValue, options.shouldTouch);
|
1113
1281
|
options.shouldValidate && trigger(name);
|
1114
1282
|
};
|
1115
|
-
const
|
1116
|
-
const
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
if (_proxyFormState.dirtyFields && !isCurrentTouched) {
|
1127
|
-
const isPreviousFieldDirty = get(_formState.dirtyFields, name);
|
1128
|
-
const isCurrentFieldDirty = !deepEqual(get(_defaultValues, name), inputValue);
|
1129
|
-
isCurrentFieldDirty
|
1130
|
-
? set(_formState.dirtyFields, name, true)
|
1131
|
-
: unset(_formState.dirtyFields, name);
|
1132
|
-
state.dirtyFields = _formState.dirtyFields;
|
1133
|
-
isChanged =
|
1134
|
-
isChanged || isPreviousFieldDirty !== get(_formState.dirtyFields, name);
|
1283
|
+
const setValues = (name, value, options) => {
|
1284
|
+
for (const fieldKey in value) {
|
1285
|
+
const fieldValue = value[fieldKey];
|
1286
|
+
const fieldName = `${name}.${fieldKey}`;
|
1287
|
+
const field = get(_fields, fieldName);
|
1288
|
+
(_names.array.has(name) ||
|
1289
|
+
!isPrimitive(fieldValue) ||
|
1290
|
+
(field && !field._f)) &&
|
1291
|
+
!isDateObject(fieldValue)
|
1292
|
+
? setValues(fieldName, fieldValue, options)
|
1293
|
+
: setFieldValue(fieldName, fieldValue, options, true);
|
1135
1294
|
}
|
1136
|
-
const isPreviousFieldTouched = get(_formState.touchedFields, name);
|
1137
|
-
if (isCurrentTouched && !isPreviousFieldTouched) {
|
1138
|
-
set(_formState.touchedFields, name, isCurrentTouched);
|
1139
|
-
state.touchedFields = _formState.touchedFields;
|
1140
|
-
isChanged =
|
1141
|
-
isChanged ||
|
1142
|
-
(_proxyFormState.touchedFields &&
|
1143
|
-
isPreviousFieldTouched !== isCurrentTouched);
|
1144
|
-
}
|
1145
|
-
isChanged && shouldRender && _subjects.state.next(state);
|
1146
|
-
return isChanged ? state : {};
|
1147
|
-
};
|
1148
|
-
const executeResolver = async (name) => {
|
1149
|
-
return formOptions.resolver
|
1150
|
-
? await formOptions.resolver(Object.assign({}, _formValues), formOptions.context, getResolverOptions(name || _names.mount, _fields, formOptions.criteriaMode, formOptions.shouldUseNativeValidation))
|
1151
|
-
: {};
|
1152
1295
|
};
|
1153
|
-
const
|
1154
|
-
const
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1296
|
+
const setValue = (name, value, options = {}) => {
|
1297
|
+
const field = get(_fields, name);
|
1298
|
+
const isFieldArray = _names.array.has(name);
|
1299
|
+
set(_formValues, name, value);
|
1300
|
+
if (isFieldArray) {
|
1301
|
+
_subjects.array.next({
|
1302
|
+
name,
|
1303
|
+
values: _formValues,
|
1304
|
+
});
|
1305
|
+
if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
|
1306
|
+
options.shouldDirty) {
|
1307
|
+
updateFieldArrayDirty(name, value);
|
1308
|
+
_subjects.state.next({
|
1309
|
+
name,
|
1310
|
+
dirtyFields: _formState.dirtyFields,
|
1311
|
+
isDirty: _getDirty(name, value),
|
1312
|
+
});
|
1161
1313
|
}
|
1162
1314
|
}
|
1163
1315
|
else {
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
};
|
1168
|
-
const validateForm = async (_fields, shouldCheckValid, context = {
|
1169
|
-
valid: true,
|
1170
|
-
}) => {
|
1171
|
-
for (const name in _fields) {
|
1172
|
-
const field = _fields[name];
|
1173
|
-
if (field) {
|
1174
|
-
const _f = field._f;
|
1175
|
-
const fieldValue = omit(field, '_f');
|
1176
|
-
if (_f) {
|
1177
|
-
const fieldError = await validateField(field, get(_formValues, _f.name), isValidateAllFieldCriteria, formOptions.shouldUseNativeValidation);
|
1178
|
-
if (fieldError[_f.name]) {
|
1179
|
-
context.valid = false;
|
1180
|
-
if (shouldCheckValid) {
|
1181
|
-
break;
|
1182
|
-
}
|
1183
|
-
}
|
1184
|
-
if (!shouldCheckValid) {
|
1185
|
-
fieldError[_f.name]
|
1186
|
-
? set(_formState.errors, _f.name, fieldError[_f.name])
|
1187
|
-
: unset(_formState.errors, _f.name);
|
1188
|
-
}
|
1189
|
-
}
|
1190
|
-
fieldValue &&
|
1191
|
-
(await validateForm(fieldValue, shouldCheckValid, context));
|
1192
|
-
}
|
1316
|
+
field && !field._f && !isNullOrUndefined(value)
|
1317
|
+
? setValues(name, value, options)
|
1318
|
+
: setFieldValue(name, value, options, true);
|
1193
1319
|
}
|
1194
|
-
|
1320
|
+
isFieldWatched(name) && _subjects.state.next({});
|
1321
|
+
_subjects.watch.next({
|
1322
|
+
name,
|
1323
|
+
});
|
1195
1324
|
};
|
1196
1325
|
const handleChange = async (event) => {
|
1197
1326
|
const target = event.target;
|
@@ -1200,22 +1329,22 @@ function createFormControl(props = {}) {
|
|
1200
1329
|
if (field) {
|
1201
1330
|
let error;
|
1202
1331
|
let isValid;
|
1203
|
-
const
|
1332
|
+
const fieldValue = target.type ? getFieldValue(field._f) : target.value;
|
1204
1333
|
const isBlurEvent = event.type === EVENTS.BLUR;
|
1205
|
-
|
1206
|
-
|
1334
|
+
const shouldSkipValidation = (!hasValidation(field._f) &&
|
1335
|
+
!_options.resolver &&
|
1336
|
+
!get(_formState.errors, name) &&
|
1337
|
+
!field._f.deps) ||
|
1338
|
+
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
|
1339
|
+
const isWatched = isFieldWatched(name, isBlurEvent);
|
1340
|
+
if (isBlurEvent) {
|
1341
|
+
field._f.onBlur && field._f.onBlur(event);
|
1207
1342
|
}
|
1208
1343
|
else if (field._f.onChange) {
|
1209
1344
|
field._f.onChange(event);
|
1210
1345
|
}
|
1211
|
-
|
1212
|
-
|
1213
|
-
!get(_formState.errors, name) &&
|
1214
|
-
!field._f.deps) ||
|
1215
|
-
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, reValidateMode, validationMode);
|
1216
|
-
const isWatched = !isBlurEvent && isFieldWatched(name);
|
1217
|
-
set(_formValues, name, inputValue);
|
1218
|
-
const fieldState = updateTouchAndDirtyState(name, inputValue, isBlurEvent, false);
|
1346
|
+
set(_formValues, name, fieldValue);
|
1347
|
+
const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
|
1219
1348
|
const shouldRender = !isEmptyObject(fieldState) || isWatched;
|
1220
1349
|
!isBlurEvent &&
|
1221
1350
|
_subjects.watch.next({
|
@@ -1227,12 +1356,12 @@ function createFormControl(props = {}) {
|
|
1227
1356
|
_subjects.state.next(Object.assign({ name }, (isWatched ? {} : fieldState))));
|
1228
1357
|
}
|
1229
1358
|
!isBlurEvent && isWatched && _subjects.state.next({});
|
1230
|
-
|
1359
|
+
validateFields[name] = validateFields[name] ? +1 : 1;
|
1231
1360
|
_proxyFormState.isValidating &&
|
1232
1361
|
_subjects.state.next({
|
1233
1362
|
isValidating: true,
|
1234
1363
|
});
|
1235
|
-
if (
|
1364
|
+
if (_options.resolver) {
|
1236
1365
|
const { errors } = await executeResolver([name]);
|
1237
1366
|
error = get(errors, name);
|
1238
1367
|
if (isCheckBoxInput(target) && !error) {
|
@@ -1248,170 +1377,42 @@ function createFormControl(props = {}) {
|
|
1248
1377
|
isValid = isEmptyObject(errors);
|
1249
1378
|
}
|
1250
1379
|
else {
|
1251
|
-
error = (await validateField(field, get(_formValues, name),
|
1380
|
+
error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1252
1381
|
isValid = await _updateValid(true);
|
1253
1382
|
}
|
1254
|
-
|
1255
|
-
|
1256
|
-
}
|
1257
|
-
shouldRenderBaseOnError(false, name, isValid, error, fieldState);
|
1383
|
+
field._f.deps && trigger(field._f.deps);
|
1384
|
+
shouldRenderByError(false, name, isValid, error, fieldState);
|
1258
1385
|
}
|
1259
1386
|
};
|
1260
|
-
const _updateValidAndInputValue = (name, shouldSkipValueAs, ref) => {
|
1261
|
-
const field = get(_fields, name);
|
1262
|
-
if (field) {
|
1263
|
-
const fieldValue = get(_formValues, name);
|
1264
|
-
const defaultValue = isUndefined(fieldValue)
|
1265
|
-
? get(_defaultValues, name)
|
1266
|
-
: fieldValue;
|
1267
|
-
if (isUndefined(defaultValue) ||
|
1268
|
-
(ref && ref.defaultChecked) ||
|
1269
|
-
shouldSkipValueAs) {
|
1270
|
-
set(_formValues, name, shouldSkipValueAs ? defaultValue : getFieldValue(field._f));
|
1271
|
-
}
|
1272
|
-
else {
|
1273
|
-
setFieldValue(name, defaultValue);
|
1274
|
-
}
|
1275
|
-
}
|
1276
|
-
_stateFlags.mount && _updateValid();
|
1277
|
-
};
|
1278
|
-
const _getIsDirty = (name, data) => {
|
1279
|
-
name && data && set(_formValues, name, data);
|
1280
|
-
return !deepEqual(Object.assign({}, getValues()), _defaultValues);
|
1281
|
-
};
|
1282
|
-
const _updateValid = async (skipRender) => {
|
1283
|
-
let isValid = false;
|
1284
|
-
if (_proxyFormState.isValid) {
|
1285
|
-
isValid = formOptions.resolver
|
1286
|
-
? isEmptyObject((await executeResolver()).errors)
|
1287
|
-
: await validateForm(_fields, true);
|
1288
|
-
if (!skipRender && isValid !== _formState.isValid) {
|
1289
|
-
_formState.isValid = isValid;
|
1290
|
-
_subjects.state.next({
|
1291
|
-
isValid,
|
1292
|
-
});
|
1293
|
-
}
|
1294
|
-
}
|
1295
|
-
return isValid;
|
1296
|
-
};
|
1297
|
-
const setValues = (name, value, options) => Object.entries(value).forEach(([fieldKey, fieldValue]) => {
|
1298
|
-
const fieldName = `${name}.${fieldKey}`;
|
1299
|
-
const field = get(_fields, fieldName);
|
1300
|
-
(_names.array.has(name) ||
|
1301
|
-
!isPrimitive(fieldValue) ||
|
1302
|
-
(field && !field._f)) &&
|
1303
|
-
!isDateObject(fieldValue)
|
1304
|
-
? setValues(fieldName, fieldValue, options)
|
1305
|
-
: setFieldValue(fieldName, fieldValue, options, true);
|
1306
|
-
});
|
1307
|
-
const _getWatch = (fieldNames, defaultValue, isMounted, isGlobal) => {
|
1308
|
-
const fieldValues = Object.assign({}, (isMounted || _stateFlags.mount
|
1309
|
-
? _formValues
|
1310
|
-
: isUndefined(defaultValue)
|
1311
|
-
? _defaultValues
|
1312
|
-
: isString(fieldNames)
|
1313
|
-
? { [fieldNames]: defaultValue }
|
1314
|
-
: defaultValue));
|
1315
|
-
if (!fieldNames) {
|
1316
|
-
isGlobal && (_names.watchAll = true);
|
1317
|
-
return fieldValues;
|
1318
|
-
}
|
1319
|
-
const result = [];
|
1320
|
-
for (const fieldName of convertToArrayPayload(fieldNames)) {
|
1321
|
-
isGlobal && _names.watch.add(fieldName);
|
1322
|
-
result.push(get(fieldValues, fieldName));
|
1323
|
-
}
|
1324
|
-
return Array.isArray(fieldNames) ? result : result[0];
|
1325
|
-
};
|
1326
|
-
const _updateFieldArray = (keyName, name, method, args, values = [], shouldSet = true, shouldSetFields = true) => {
|
1327
|
-
let output;
|
1328
|
-
_stateFlags.action = true;
|
1329
|
-
if (shouldSetFields && get(_fields, name)) {
|
1330
|
-
output = method(get(_fields, name), args.argA, args.argB);
|
1331
|
-
shouldSet && set(_fields, name, output);
|
1332
|
-
}
|
1333
|
-
if (Array.isArray(get(_formState.errors, name))) {
|
1334
|
-
const output = method(get(_formState.errors, name), args.argA, args.argB);
|
1335
|
-
shouldSet && set(_formState.errors, name, output);
|
1336
|
-
unsetEmptyArray(_formState.errors, name);
|
1337
|
-
}
|
1338
|
-
if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
|
1339
|
-
const output = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
1340
|
-
shouldSet && set(_formState.touchedFields, name, output);
|
1341
|
-
unsetEmptyArray(_formState.touchedFields, name);
|
1342
|
-
}
|
1343
|
-
if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
|
1344
|
-
set(_formState.dirtyFields, name, setFieldArrayDirtyFields(omitKey(values, keyName), get(_defaultValues, name, []), get(_formState.dirtyFields, name, [])));
|
1345
|
-
values &&
|
1346
|
-
set(_formState.dirtyFields, name, setFieldArrayDirtyFields(omitKey(values, keyName), get(_defaultValues, name, []), get(_formState.dirtyFields, name, [])));
|
1347
|
-
unsetEmptyArray(_formState.dirtyFields, name);
|
1348
|
-
}
|
1349
|
-
_subjects.state.next({
|
1350
|
-
isDirty: _getIsDirty(name, omitKey(values, keyName)),
|
1351
|
-
dirtyFields: _formState.dirtyFields,
|
1352
|
-
errors: _formState.errors,
|
1353
|
-
isValid: _formState.isValid,
|
1354
|
-
});
|
1355
|
-
};
|
1356
|
-
const _getFieldArrayValue = (name) => get(_stateFlags.mount ? _formValues : _defaultValues, name, []);
|
1357
|
-
const setValue = (name, value, options = {}) => {
|
1358
|
-
const field = get(_fields, name);
|
1359
|
-
const isFieldArray = _names.array.has(name);
|
1360
|
-
set(_formValues, name, value);
|
1361
|
-
if (isFieldArray) {
|
1362
|
-
_subjects.array.next({
|
1363
|
-
name,
|
1364
|
-
values: _formValues,
|
1365
|
-
});
|
1366
|
-
if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
|
1367
|
-
options.shouldDirty) {
|
1368
|
-
set(_formState.dirtyFields, name, setFieldArrayDirtyFields(value, get(_defaultValues, name, []), get(_formState.dirtyFields, name, [])));
|
1369
|
-
_subjects.state.next({
|
1370
|
-
name,
|
1371
|
-
dirtyFields: _formState.dirtyFields,
|
1372
|
-
isDirty: _getIsDirty(name, value),
|
1373
|
-
});
|
1374
|
-
}
|
1375
|
-
}
|
1376
|
-
else {
|
1377
|
-
field && !field._f && !isNullOrUndefined(value)
|
1378
|
-
? setValues(name, value, options)
|
1379
|
-
: setFieldValue(name, value, options, true);
|
1380
|
-
}
|
1381
|
-
isFieldWatched(name) && _subjects.state.next({});
|
1382
|
-
_subjects.watch.next({
|
1383
|
-
name,
|
1384
|
-
});
|
1385
|
-
};
|
1386
1387
|
const trigger = async (name, options = {}) => {
|
1387
|
-
const fieldNames = convertToArrayPayload(name);
|
1388
1388
|
let isValid;
|
1389
|
+
let validationResult;
|
1390
|
+
const fieldNames = convertToArrayPayload(name);
|
1389
1391
|
_subjects.state.next({
|
1390
1392
|
isValidating: true,
|
1391
1393
|
});
|
1392
|
-
if (
|
1393
|
-
const
|
1394
|
-
isValid =
|
1395
|
-
|
1396
|
-
|
1394
|
+
if (_options.resolver) {
|
1395
|
+
const errors = await executeResolverValidation(isUndefined(name) ? name : fieldNames);
|
1396
|
+
isValid = isEmptyObject(errors);
|
1397
|
+
validationResult = name
|
1398
|
+
? !fieldNames.some((name) => get(errors, name))
|
1399
|
+
: isValid;
|
1400
|
+
}
|
1401
|
+
else if (name) {
|
1402
|
+
validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
|
1403
|
+
const field = get(_fields, fieldName);
|
1404
|
+
return await executeBuildInValidation(field && field._f ? { [fieldName]: field } : field);
|
1405
|
+
}))).every(Boolean);
|
1406
|
+
_updateValid();
|
1397
1407
|
}
|
1398
1408
|
else {
|
1399
|
-
|
1400
|
-
isValid = (await Promise.all(fieldNames.map(async (fieldName) => {
|
1401
|
-
const field = get(_fields, fieldName);
|
1402
|
-
return await validateForm(field && field._f ? { [fieldName]: field } : field);
|
1403
|
-
}))).every(Boolean);
|
1404
|
-
_updateValid();
|
1405
|
-
}
|
1406
|
-
else {
|
1407
|
-
isValid = await validateForm(_fields);
|
1408
|
-
}
|
1409
|
+
validationResult = isValid = await executeBuildInValidation(_fields);
|
1409
1410
|
}
|
1410
|
-
_subjects.state.next(Object.assign(Object.assign({}, (isString(name) ? {
|
1411
|
-
|
1411
|
+
_subjects.state.next(Object.assign(Object.assign({}, (!isString(name) || isValid !== _formState.isValid ? {} : { name })), { errors: _formState.errors, isValid, isValidating: false }));
|
1412
|
+
options.shouldFocus &&
|
1413
|
+
!validationResult &&
|
1412
1414
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), name ? fieldNames : _names.mount);
|
1413
|
-
|
1414
|
-
return isValid;
|
1415
|
+
return validationResult;
|
1415
1416
|
};
|
1416
1417
|
const getValues = (fieldNames) => {
|
1417
1418
|
const values = Object.assign(Object.assign({}, _defaultValues), (_stateFlags.mount ? _formValues : {}));
|
@@ -1439,88 +1440,83 @@ function createFormControl(props = {}) {
|
|
1439
1440
|
});
|
1440
1441
|
options && options.shouldFocus && ref && ref.focus && ref.focus();
|
1441
1442
|
};
|
1442
|
-
const watch = (
|
1443
|
+
const watch = (name, defaultValue) => isFunction(name)
|
1443
1444
|
? _subjects.watch.subscribe({
|
1444
|
-
next: (info) =>
|
1445
|
+
next: (info) => name(_getWatch(undefined, defaultValue), info),
|
1445
1446
|
})
|
1446
|
-
: _getWatch(
|
1447
|
+
: _getWatch(name, defaultValue, true);
|
1447
1448
|
const unregister = (name, options = {}) => {
|
1448
|
-
for (const
|
1449
|
-
_names.mount.delete(
|
1450
|
-
_names.array.delete(
|
1451
|
-
if (get(_fields,
|
1449
|
+
for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
|
1450
|
+
_names.mount.delete(fieldName);
|
1451
|
+
_names.array.delete(fieldName);
|
1452
|
+
if (get(_fields, fieldName)) {
|
1452
1453
|
if (!options.keepValue) {
|
1453
|
-
unset(_fields,
|
1454
|
-
unset(_formValues,
|
1454
|
+
unset(_fields, fieldName);
|
1455
|
+
unset(_formValues, fieldName);
|
1455
1456
|
}
|
1456
|
-
!options.keepError && unset(_formState.errors,
|
1457
|
-
!options.keepDirty && unset(_formState.dirtyFields,
|
1458
|
-
!options.keepTouched && unset(_formState.touchedFields,
|
1459
|
-
!
|
1457
|
+
!options.keepError && unset(_formState.errors, fieldName);
|
1458
|
+
!options.keepDirty && unset(_formState.dirtyFields, fieldName);
|
1459
|
+
!options.keepTouched && unset(_formState.touchedFields, fieldName);
|
1460
|
+
!_options.shouldUnregister &&
|
1460
1461
|
!options.keepDefaultValue &&
|
1461
|
-
unset(_defaultValues,
|
1462
|
+
unset(_defaultValues, fieldName);
|
1462
1463
|
}
|
1463
1464
|
}
|
1464
1465
|
_subjects.watch.next({});
|
1465
|
-
_subjects.state.next(Object.assign(Object.assign({}, _formState), (!options.keepDirty ? {} : { isDirty:
|
1466
|
+
_subjects.state.next(Object.assign(Object.assign({}, _formState), (!options.keepDirty ? {} : { isDirty: _getDirty() })));
|
1466
1467
|
!options.keepIsValid && _updateValid();
|
1467
1468
|
};
|
1468
|
-
const registerFieldRef = (name, fieldRef, options) => {
|
1469
|
-
register(name, options);
|
1470
|
-
let field = get(_fields, name);
|
1471
|
-
const ref = isUndefined(fieldRef.value)
|
1472
|
-
? fieldRef.querySelectorAll
|
1473
|
-
? fieldRef.querySelectorAll('input,select,textarea')[0] ||
|
1474
|
-
fieldRef
|
1475
|
-
: fieldRef
|
1476
|
-
: fieldRef;
|
1477
|
-
const isRadioOrCheckbox = isRadioOrCheckboxFunction(ref);
|
1478
|
-
if (ref === field._f.ref ||
|
1479
|
-
(isRadioOrCheckbox &&
|
1480
|
-
compact(field._f.refs || []).find((option) => option === ref))) {
|
1481
|
-
return;
|
1482
|
-
}
|
1483
|
-
field = {
|
1484
|
-
_f: isRadioOrCheckbox
|
1485
|
-
? Object.assign(Object.assign({}, field._f), { refs: [
|
1486
|
-
...compact(field._f.refs || []).filter((ref) => isHTMLElement(ref) && document.contains(ref)),
|
1487
|
-
ref,
|
1488
|
-
], ref: { type: ref.type, name } }) : Object.assign(Object.assign({}, field._f), { ref }),
|
1489
|
-
};
|
1490
|
-
set(_fields, name, field);
|
1491
|
-
(!options || !options.disabled) &&
|
1492
|
-
_updateValidAndInputValue(name, false, ref);
|
1493
|
-
};
|
1494
1469
|
const register = (name, options = {}) => {
|
1495
1470
|
const field = get(_fields, name);
|
1496
1471
|
set(_fields, name, {
|
1497
1472
|
_f: Object.assign(Object.assign(Object.assign({}, (field && field._f ? field._f : { ref: { name } })), { name, mount: true }), options),
|
1498
1473
|
});
|
1499
1474
|
_names.mount.add(name);
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
}
|
1508
|
-
!field && _updateValidAndInputValue(name, true);
|
1475
|
+
!isUndefined(options.value) && set(_formValues, name, options.value);
|
1476
|
+
field
|
1477
|
+
? isBoolean(options.disabled) &&
|
1478
|
+
set(_formValues, name, options.disabled
|
1479
|
+
? undefined
|
1480
|
+
: get(_formValues, name, getFieldValue(field._f)))
|
1481
|
+
: updateValidAndValue(name, true);
|
1509
1482
|
return isWindowUndefined
|
1510
1483
|
? { name: name }
|
1511
1484
|
: Object.assign(Object.assign({ name }, (isBoolean(options.disabled)
|
1512
1485
|
? { disabled: options.disabled }
|
1513
1486
|
: {})), { onChange: handleChange, onBlur: handleChange, ref: (ref) => {
|
1514
1487
|
if (ref) {
|
1515
|
-
|
1488
|
+
register(name, options);
|
1489
|
+
let field = get(_fields, name);
|
1490
|
+
const fieldRef = isUndefined(ref.value)
|
1491
|
+
? ref.querySelectorAll
|
1492
|
+
? ref.querySelectorAll('input,select,textarea')[0] ||
|
1493
|
+
ref
|
1494
|
+
: ref
|
1495
|
+
: ref;
|
1496
|
+
const isRadioOrCheckbox = isRadioOrCheckboxFunction(fieldRef);
|
1497
|
+
if (fieldRef === field._f.ref ||
|
1498
|
+
(isRadioOrCheckbox &&
|
1499
|
+
compact(field._f.refs || []).find((option) => option === fieldRef))) {
|
1500
|
+
return;
|
1501
|
+
}
|
1502
|
+
field = {
|
1503
|
+
_f: isRadioOrCheckbox
|
1504
|
+
? Object.assign(Object.assign({}, field._f), { refs: [
|
1505
|
+
...compact(field._f.refs || []).filter((ref) => isHTMLElement(ref) && document.contains(ref)),
|
1506
|
+
fieldRef,
|
1507
|
+
], ref: { type: fieldRef.type, name } }) : Object.assign(Object.assign({}, field._f), { ref: fieldRef }),
|
1508
|
+
};
|
1509
|
+
set(_fields, name, field);
|
1510
|
+
(!options || !options.disabled) &&
|
1511
|
+
updateValidAndValue(name, false, fieldRef);
|
1516
1512
|
}
|
1517
1513
|
else {
|
1518
1514
|
const field = get(_fields, name, {});
|
1519
|
-
const
|
1515
|
+
const shouldUnregister = _options.shouldUnregister || options.shouldUnregister;
|
1520
1516
|
if (field._f) {
|
1521
1517
|
field._f.mount = false;
|
1522
1518
|
}
|
1523
|
-
|
1519
|
+
shouldUnregister &&
|
1524
1520
|
!(isNameInFieldArray(_names.array, name) && _stateFlags.action) &&
|
1525
1521
|
_names.unMount.add(name);
|
1526
1522
|
}
|
@@ -1537,13 +1533,13 @@ function createFormControl(props = {}) {
|
|
1537
1533
|
isSubmitting: true,
|
1538
1534
|
});
|
1539
1535
|
try {
|
1540
|
-
if (
|
1536
|
+
if (_options.resolver) {
|
1541
1537
|
const { errors, values } = await executeResolver();
|
1542
1538
|
_formState.errors = errors;
|
1543
1539
|
fieldValues = values;
|
1544
1540
|
}
|
1545
1541
|
else {
|
1546
|
-
await
|
1542
|
+
await executeBuildInValidation(_fields);
|
1547
1543
|
}
|
1548
1544
|
if (isEmptyObject(_formState.errors) &&
|
1549
1545
|
Object.keys(_formState.errors).every((name) => get(fieldValues, name))) {
|
@@ -1555,7 +1551,7 @@ function createFormControl(props = {}) {
|
|
1555
1551
|
}
|
1556
1552
|
else {
|
1557
1553
|
onInvalid && (await onInvalid(_formState.errors, e));
|
1558
|
-
|
1554
|
+
_options.shouldFocusError &&
|
1559
1555
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
|
1560
1556
|
}
|
1561
1557
|
}
|
@@ -1575,39 +1571,37 @@ function createFormControl(props = {}) {
|
|
1575
1571
|
}
|
1576
1572
|
};
|
1577
1573
|
const reset = (formValues, keepStateOptions = {}) => {
|
1574
|
+
const hasUpdatedFormValues = !isEmptyObject(formValues);
|
1578
1575
|
const updatedValues = formValues || _defaultValues;
|
1579
|
-
const
|
1580
|
-
if (!keepStateOptions.
|
1581
|
-
|
1576
|
+
const cloneUpdatedValues = cloneObject(updatedValues);
|
1577
|
+
if (!keepStateOptions.keepDefaultValues) {
|
1578
|
+
_defaultValues = updatedValues;
|
1582
1579
|
}
|
1583
|
-
if (
|
1584
|
-
|
1585
|
-
const
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1580
|
+
if (!keepStateOptions.keepValues) {
|
1581
|
+
if (isWeb) {
|
1582
|
+
for (const name of _names.mount) {
|
1583
|
+
const field = get(_fields, name);
|
1584
|
+
if (field && field._f) {
|
1585
|
+
const fieldReference = Array.isArray(field._f.refs)
|
1586
|
+
? field._f.refs[0]
|
1587
|
+
: field._f.ref;
|
1588
|
+
try {
|
1589
|
+
isHTMLElement(fieldReference) &&
|
1590
|
+
fieldReference.closest('form').reset();
|
1591
|
+
break;
|
1592
|
+
}
|
1593
|
+
catch (_a) { }
|
1593
1594
|
}
|
1594
|
-
catch (_a) { }
|
1595
1595
|
}
|
1596
1596
|
}
|
1597
|
-
|
1598
|
-
if (!keepStateOptions.keepDefaultValues) {
|
1599
|
-
_defaultValues = Object.assign({}, updatedValues);
|
1600
|
-
}
|
1601
|
-
if (!keepStateOptions.keepValues) {
|
1597
|
+
_formValues = props.shouldUnregister ? {} : cloneUpdatedValues;
|
1602
1598
|
_fields = {};
|
1603
1599
|
_subjects.control.next({
|
1604
|
-
values:
|
1605
|
-
? _defaultValues
|
1606
|
-
: Object.assign({}, updatedValues),
|
1600
|
+
values: hasUpdatedFormValues ? cloneUpdatedValues : _defaultValues,
|
1607
1601
|
});
|
1608
1602
|
_subjects.watch.next({});
|
1609
1603
|
_subjects.array.next({
|
1610
|
-
values,
|
1604
|
+
values: cloneUpdatedValues,
|
1611
1605
|
});
|
1612
1606
|
}
|
1613
1607
|
_names = {
|
@@ -1647,27 +1641,17 @@ function createFormControl(props = {}) {
|
|
1647
1641
|
_stateFlags.watch = !!props.shouldUnregister;
|
1648
1642
|
};
|
1649
1643
|
const setFocus = (name) => get(_fields, name)._f.ref.focus();
|
1650
|
-
const _removeFields = () => {
|
1651
|
-
for (const name of _names.unMount) {
|
1652
|
-
const field = get(_fields, name);
|
1653
|
-
field &&
|
1654
|
-
(field._f.refs ? field._f.refs.every(live) : live(field._f.ref)) &&
|
1655
|
-
unregister(name);
|
1656
|
-
}
|
1657
|
-
_names.unMount = new Set();
|
1658
|
-
};
|
1659
1644
|
return {
|
1660
1645
|
control: {
|
1661
1646
|
register,
|
1662
1647
|
unregister,
|
1663
1648
|
_getWatch,
|
1664
|
-
|
1649
|
+
_getDirty,
|
1665
1650
|
_updateValid,
|
1666
|
-
|
1651
|
+
_removeUnmounted,
|
1667
1652
|
_updateFieldArray,
|
1668
|
-
|
1653
|
+
_getFieldArray,
|
1669
1654
|
_subjects,
|
1670
|
-
_shouldUnregister: formOptions.shouldUnregister,
|
1671
1655
|
_proxyFormState,
|
1672
1656
|
get _fields() {
|
1673
1657
|
return _fields;
|
@@ -1705,8 +1689,11 @@ function createFormControl(props = {}) {
|
|
1705
1689
|
set _formState(value) {
|
1706
1690
|
_formState = value;
|
1707
1691
|
},
|
1708
|
-
|
1709
|
-
|
1692
|
+
get _options() {
|
1693
|
+
return _options;
|
1694
|
+
},
|
1695
|
+
set _options(value) {
|
1696
|
+
_options = Object.assign(Object.assign({}, _options), value);
|
1710
1697
|
},
|
1711
1698
|
},
|
1712
1699
|
trigger,
|
@@ -1738,7 +1725,7 @@ function useForm(props = {}) {
|
|
1738
1725
|
errors: {},
|
1739
1726
|
});
|
1740
1727
|
if (_formControl.current) {
|
1741
|
-
_formControl.current.control.
|
1728
|
+
_formControl.current.control._options = props;
|
1742
1729
|
}
|
1743
1730
|
else {
|
1744
1731
|
_formControl.current = Object.assign(Object.assign({}, createFormControl(props)), { formState });
|
@@ -1762,7 +1749,7 @@ function useForm(props = {}) {
|
|
1762
1749
|
control._stateFlags.watch = false;
|
1763
1750
|
control._subjects.state.next({});
|
1764
1751
|
}
|
1765
|
-
control.
|
1752
|
+
control._removeUnmounted();
|
1766
1753
|
});
|
1767
1754
|
_formControl.current.formState = getProxyFormState(formState, control._proxyFormState);
|
1768
1755
|
return _formControl.current;
|
@@ -1783,11 +1770,12 @@ function useWatch(props) {
|
|
1783
1770
|
currentName &&
|
1784
1771
|
(name.startsWith(currentName) ||
|
1785
1772
|
currentName.startsWith(name)))) {
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
?
|
1790
|
-
|
1773
|
+
control._stateFlags.mount = true;
|
1774
|
+
const fieldValues = control._getWatch(_name.current, defaultValue);
|
1775
|
+
updateValue(isObject(fieldValues)
|
1776
|
+
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
1777
|
+
? [...fieldValues]
|
1778
|
+
: fieldValues);
|
1791
1779
|
}
|
1792
1780
|
},
|
1793
1781
|
});
|
@@ -1795,7 +1783,7 @@ function useWatch(props) {
|
|
1795
1783
|
? control._getWatch(name)
|
1796
1784
|
: defaultValue);
|
1797
1785
|
React.useEffect(() => {
|
1798
|
-
control.
|
1786
|
+
control._removeUnmounted();
|
1799
1787
|
});
|
1800
1788
|
return value;
|
1801
1789
|
}
|