react-hook-form 8.0.0-alpha.1 → 8.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +445 -317
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/focusFieldBy.d.ts.map +1 -1
- package/dist/logic/getNodeParentName.d.ts.map +1 -1
- package/dist/logic/getResolverOptions.d.ts +1 -1
- package/dist/logic/isNameInFieldArray.d.ts.map +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts +4 -0
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -0
- package/dist/logic/validateField.d.ts +1 -1
- package/dist/logic/validateField.d.ts.map +1 -1
- package/dist/types/controller.d.ts +0 -1
- package/dist/types/controller.d.ts.map +1 -1
- package/dist/types/errors.d.ts +1 -0
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +8 -5
- package/dist/types/fieldArray.d.ts.map +1 -1
- package/dist/types/form.d.ts +1 -2
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/validator.d.ts +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useFormContext.d.ts +1 -0
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/utils/compact.d.ts.map +1 -1
- package/dist/utils/unset.d.ts.map +1 -1
- package/package.json +28 -28
package/dist/index.esm.mjs
CHANGED
@@ -18,11 +18,11 @@ var getEventValue = (event) => isObject(event) && event.target
|
|
18
18
|
: event.target.value
|
19
19
|
: event;
|
20
20
|
|
21
|
-
var getNodeParentName = (name) => name.substring(0, name.search(
|
21
|
+
var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
|
22
22
|
|
23
|
-
var isNameInFieldArray = (names, name) =>
|
23
|
+
var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
|
24
24
|
|
25
|
-
var compact = (value) => value.filter(Boolean);
|
25
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
26
26
|
|
27
27
|
var isUndefined = (val) => val === undefined;
|
28
28
|
|
@@ -60,12 +60,6 @@ const INPUT_VALIDATION_RULES = {
|
|
60
60
|
validate: 'validate',
|
61
61
|
};
|
62
62
|
|
63
|
-
var omit = (source, key) => {
|
64
|
-
const copy = Object.assign({}, source);
|
65
|
-
delete copy[key];
|
66
|
-
return copy;
|
67
|
-
};
|
68
|
-
|
69
63
|
const HookFormContext = React.createContext(null);
|
70
64
|
/**
|
71
65
|
* This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
|
@@ -128,7 +122,10 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
128
122
|
* }
|
129
123
|
* ```
|
130
124
|
*/
|
131
|
-
const FormProvider = (props) =>
|
125
|
+
const FormProvider = (props) => {
|
126
|
+
const { children, ...data } = props;
|
127
|
+
return (React.createElement(HookFormContext.Provider, { value: data }, props.children));
|
128
|
+
};
|
132
129
|
|
133
130
|
var getProxyFormState = (formState, _proxyFormState, localProxyFormState, isRoot = true) => {
|
134
131
|
const result = {};
|
@@ -150,7 +147,7 @@ var getProxyFormState = (formState, _proxyFormState, localProxyFormState, isRoot
|
|
150
147
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
151
148
|
|
152
149
|
var shouldRenderFormState = (formStateData, _proxyFormState, isRoot) => {
|
153
|
-
const formState =
|
150
|
+
const { name, ...formState } = formStateData;
|
154
151
|
return (isEmptyObject(formState) ||
|
155
152
|
Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
|
156
153
|
Object.keys(formState).find((key) => _proxyFormState[key] ===
|
@@ -233,14 +230,20 @@ function useFormState(props) {
|
|
233
230
|
const callback = React.useCallback((value) => _mounted.current &&
|
234
231
|
shouldSubscribeByName(_name.current, value.name, exact) &&
|
235
232
|
shouldRenderFormState(value, _localProxyFormState.current) &&
|
236
|
-
updateFormState(
|
233
|
+
updateFormState({
|
234
|
+
...control._formState,
|
235
|
+
...value,
|
236
|
+
}), [control, exact]);
|
237
237
|
useSubscribe({
|
238
238
|
disabled,
|
239
239
|
callback,
|
240
240
|
subject: control._subjects.state,
|
241
241
|
});
|
242
|
-
React.useEffect(() =>
|
243
|
-
_mounted.current =
|
242
|
+
React.useEffect(() => {
|
243
|
+
_mounted.current = true;
|
244
|
+
return () => {
|
245
|
+
_mounted.current = false;
|
246
|
+
};
|
244
247
|
}, []);
|
245
248
|
return getProxyFormState(formState, control._proxyFormState, _localProxyFormState.current, false);
|
246
249
|
}
|
@@ -295,11 +298,12 @@ function useWatch(props) {
|
|
295
298
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
296
299
|
updateValue(isUndefined(_name.current) ||
|
297
300
|
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
298
|
-
?
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
301
|
+
? { ...fieldValues }
|
302
|
+
: Array.isArray(fieldValues)
|
303
|
+
? [...fieldValues]
|
304
|
+
: isUndefined(fieldValues)
|
305
|
+
? defaultValue
|
306
|
+
: fieldValues);
|
303
307
|
}
|
304
308
|
}, [control, exact, defaultValue]);
|
305
309
|
useSubscribe({
|
@@ -354,7 +358,10 @@ function useController(props) {
|
|
354
358
|
control,
|
355
359
|
name,
|
356
360
|
});
|
357
|
-
const _registerProps = React.useRef(control.register(name,
|
361
|
+
const _registerProps = React.useRef(control.register(name, {
|
362
|
+
...props.rules,
|
363
|
+
value: value,
|
364
|
+
}));
|
358
365
|
React.useEffect(() => {
|
359
366
|
const updateMounted = (name, value) => {
|
360
367
|
const field = get(control._fields, name);
|
@@ -455,7 +462,14 @@ function useController(props) {
|
|
455
462
|
const Controller = (props) => props.render(useController(props));
|
456
463
|
|
457
464
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
458
|
-
?
|
465
|
+
? {
|
466
|
+
...errors[name],
|
467
|
+
types: {
|
468
|
+
...(errors[name] && errors[name].types ? errors[name].types : {}),
|
469
|
+
[type]: message || true,
|
470
|
+
},
|
471
|
+
}
|
472
|
+
: {};
|
459
473
|
|
460
474
|
/**
|
461
475
|
* Function for joining two paths / path strings to a {@link TypedFieldPath}.
|
@@ -519,8 +533,7 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
519
533
|
for (const key of fieldsNames || Object.keys(fields)) {
|
520
534
|
const field = get(fields, key);
|
521
535
|
if (field) {
|
522
|
-
const _f = field
|
523
|
-
const current = omit(field, '_f');
|
536
|
+
const { _f, ...currentField } = field;
|
524
537
|
if (_f && callback(_f.name)) {
|
525
538
|
if (_f.ref.focus && isUndefined(_f.ref.focus())) {
|
526
539
|
break;
|
@@ -530,8 +543,8 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
530
543
|
break;
|
531
544
|
}
|
532
545
|
}
|
533
|
-
else if (isObject(
|
534
|
-
focusFieldBy(
|
546
|
+
else if (isObject(currentField)) {
|
547
|
+
focusFieldBy(currentField, callback);
|
535
548
|
}
|
536
549
|
}
|
537
550
|
}
|
@@ -556,6 +569,243 @@ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
|
|
556
569
|
[..._names.watch].some((watchName) => name.startsWith(watchName) &&
|
557
570
|
/^\.\w+/.test(name.slice(watchName.length))));
|
558
571
|
|
572
|
+
var updateFieldArrayRootError = (errors, error, name) => {
|
573
|
+
const fieldArrayErrors = compact(get(errors, name));
|
574
|
+
set(fieldArrayErrors, 'root', error[name]);
|
575
|
+
set(errors, name, fieldArrayErrors);
|
576
|
+
return errors;
|
577
|
+
};
|
578
|
+
|
579
|
+
var isBoolean = (value) => typeof value === 'boolean';
|
580
|
+
|
581
|
+
var isFileInput = (element) => element.type === 'file';
|
582
|
+
|
583
|
+
var isMessage = (value) => isString(value) || React.isValidElement(value);
|
584
|
+
|
585
|
+
var isRadioInput = (element) => element.type === 'radio';
|
586
|
+
|
587
|
+
var isRegex = (value) => value instanceof RegExp;
|
588
|
+
|
589
|
+
const defaultResult = {
|
590
|
+
value: false,
|
591
|
+
isValid: false,
|
592
|
+
};
|
593
|
+
const validResult = { value: true, isValid: true };
|
594
|
+
var getCheckboxValue = (options) => {
|
595
|
+
if (Array.isArray(options)) {
|
596
|
+
if (options.length > 1) {
|
597
|
+
const values = options
|
598
|
+
.filter((option) => option && option.checked && !option.disabled)
|
599
|
+
.map((option) => option.value);
|
600
|
+
return { value: values, isValid: !!values.length };
|
601
|
+
}
|
602
|
+
return options[0].checked && !options[0].disabled
|
603
|
+
? // @ts-expect-error expected to work in the browser
|
604
|
+
options[0].attributes && !isUndefined(options[0].attributes.value)
|
605
|
+
? isUndefined(options[0].value) || options[0].value === ''
|
606
|
+
? validResult
|
607
|
+
: { value: options[0].value, isValid: true }
|
608
|
+
: validResult
|
609
|
+
: defaultResult;
|
610
|
+
}
|
611
|
+
return defaultResult;
|
612
|
+
};
|
613
|
+
|
614
|
+
const defaultReturn = {
|
615
|
+
isValid: false,
|
616
|
+
value: null,
|
617
|
+
};
|
618
|
+
var getRadioValue = (options) => Array.isArray(options)
|
619
|
+
? options.reduce((previous, option) => option && option.checked && !option.disabled
|
620
|
+
? {
|
621
|
+
isValid: true,
|
622
|
+
value: option.value,
|
623
|
+
}
|
624
|
+
: previous, defaultReturn)
|
625
|
+
: defaultReturn;
|
626
|
+
|
627
|
+
function getValidateError(result, ref, type = 'validate') {
|
628
|
+
if (isMessage(result) ||
|
629
|
+
(Array.isArray(result) && result.every(isMessage)) ||
|
630
|
+
(isBoolean(result) && !result)) {
|
631
|
+
return {
|
632
|
+
type,
|
633
|
+
message: isMessage(result) ? result : '',
|
634
|
+
ref,
|
635
|
+
};
|
636
|
+
}
|
637
|
+
}
|
638
|
+
|
639
|
+
var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
|
640
|
+
? validationData
|
641
|
+
: {
|
642
|
+
value: validationData,
|
643
|
+
message: '',
|
644
|
+
};
|
645
|
+
|
646
|
+
var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
|
647
|
+
const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled, } = field._f;
|
648
|
+
if (!mount || disabled) {
|
649
|
+
return {};
|
650
|
+
}
|
651
|
+
const inputRef = refs ? refs[0] : ref;
|
652
|
+
const setCustomValidity = (message) => {
|
653
|
+
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
654
|
+
inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
|
655
|
+
inputRef.reportValidity();
|
656
|
+
}
|
657
|
+
};
|
658
|
+
const error = {};
|
659
|
+
const isRadio = isRadioInput(ref);
|
660
|
+
const isCheckBox = isCheckBoxInput(ref);
|
661
|
+
const isRadioOrCheckbox = isRadio || isCheckBox;
|
662
|
+
const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
|
663
|
+
inputValue === '' ||
|
664
|
+
(Array.isArray(inputValue) && !inputValue.length);
|
665
|
+
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
666
|
+
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
667
|
+
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
668
|
+
error[name] = {
|
669
|
+
type: exceedMax ? maxType : minType,
|
670
|
+
message,
|
671
|
+
ref,
|
672
|
+
...appendErrorsCurry(exceedMax ? maxType : minType, message),
|
673
|
+
};
|
674
|
+
};
|
675
|
+
if (isFieldArray
|
676
|
+
? Array.isArray(inputValue) && !inputValue.length
|
677
|
+
: required &&
|
678
|
+
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
679
|
+
(isBoolean(inputValue) && !inputValue) ||
|
680
|
+
(isCheckBox && !getCheckboxValue(refs).isValid) ||
|
681
|
+
(isRadio && !getRadioValue(refs).isValid))) {
|
682
|
+
const { value, message } = isMessage(required)
|
683
|
+
? { value: !!required, message: required }
|
684
|
+
: getValueAndMessage(required);
|
685
|
+
if (value) {
|
686
|
+
error[name] = {
|
687
|
+
type: INPUT_VALIDATION_RULES.required,
|
688
|
+
message,
|
689
|
+
ref: inputRef,
|
690
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
|
691
|
+
};
|
692
|
+
if (!validateAllFieldCriteria) {
|
693
|
+
setCustomValidity(message);
|
694
|
+
return error;
|
695
|
+
}
|
696
|
+
}
|
697
|
+
}
|
698
|
+
if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
|
699
|
+
let exceedMax;
|
700
|
+
let exceedMin;
|
701
|
+
const maxOutput = getValueAndMessage(max);
|
702
|
+
const minOutput = getValueAndMessage(min);
|
703
|
+
if (!isNaN(inputValue)) {
|
704
|
+
const valueNumber = ref.valueAsNumber || +inputValue;
|
705
|
+
if (!isNullOrUndefined(maxOutput.value)) {
|
706
|
+
exceedMax = valueNumber > maxOutput.value;
|
707
|
+
}
|
708
|
+
if (!isNullOrUndefined(minOutput.value)) {
|
709
|
+
exceedMin = valueNumber < minOutput.value;
|
710
|
+
}
|
711
|
+
}
|
712
|
+
else {
|
713
|
+
const valueDate = ref.valueAsDate || new Date(inputValue);
|
714
|
+
if (isString(maxOutput.value)) {
|
715
|
+
exceedMax = valueDate > new Date(maxOutput.value);
|
716
|
+
}
|
717
|
+
if (isString(minOutput.value)) {
|
718
|
+
exceedMin = valueDate < new Date(minOutput.value);
|
719
|
+
}
|
720
|
+
}
|
721
|
+
if (exceedMax || exceedMin) {
|
722
|
+
getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
|
723
|
+
if (!validateAllFieldCriteria) {
|
724
|
+
setCustomValidity(error[name].message);
|
725
|
+
return error;
|
726
|
+
}
|
727
|
+
}
|
728
|
+
}
|
729
|
+
if ((maxLength || minLength) &&
|
730
|
+
!isEmpty &&
|
731
|
+
(isString(inputValue) || (isFieldArray && Array.isArray(inputValue)))) {
|
732
|
+
const maxLengthOutput = getValueAndMessage(maxLength);
|
733
|
+
const minLengthOutput = getValueAndMessage(minLength);
|
734
|
+
const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
|
735
|
+
inputValue.length > maxLengthOutput.value;
|
736
|
+
const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
|
737
|
+
inputValue.length < minLengthOutput.value;
|
738
|
+
if (exceedMax || exceedMin) {
|
739
|
+
getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
|
740
|
+
if (!validateAllFieldCriteria) {
|
741
|
+
setCustomValidity(error[name].message);
|
742
|
+
return error;
|
743
|
+
}
|
744
|
+
}
|
745
|
+
}
|
746
|
+
if (pattern && !isEmpty && isString(inputValue)) {
|
747
|
+
const { value: patternValue, message } = getValueAndMessage(pattern);
|
748
|
+
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
749
|
+
error[name] = {
|
750
|
+
type: INPUT_VALIDATION_RULES.pattern,
|
751
|
+
message,
|
752
|
+
ref,
|
753
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
|
754
|
+
};
|
755
|
+
if (!validateAllFieldCriteria) {
|
756
|
+
setCustomValidity(message);
|
757
|
+
return error;
|
758
|
+
}
|
759
|
+
}
|
760
|
+
}
|
761
|
+
if (validate) {
|
762
|
+
if (isFunction(validate)) {
|
763
|
+
const result = await validate(inputValue);
|
764
|
+
const validateError = getValidateError(result, inputRef);
|
765
|
+
if (validateError) {
|
766
|
+
error[name] = {
|
767
|
+
...validateError,
|
768
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
|
769
|
+
};
|
770
|
+
if (!validateAllFieldCriteria) {
|
771
|
+
setCustomValidity(validateError.message);
|
772
|
+
return error;
|
773
|
+
}
|
774
|
+
}
|
775
|
+
}
|
776
|
+
else if (isObject(validate)) {
|
777
|
+
let validationResult = {};
|
778
|
+
for (const key in validate) {
|
779
|
+
if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
|
780
|
+
break;
|
781
|
+
}
|
782
|
+
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
783
|
+
if (validateError) {
|
784
|
+
validationResult = {
|
785
|
+
...validateError,
|
786
|
+
...appendErrorsCurry(key, validateError.message),
|
787
|
+
};
|
788
|
+
setCustomValidity(validateError.message);
|
789
|
+
if (validateAllFieldCriteria) {
|
790
|
+
error[name] = validationResult;
|
791
|
+
}
|
792
|
+
}
|
793
|
+
}
|
794
|
+
if (!isEmptyObject(validationResult)) {
|
795
|
+
error[name] = {
|
796
|
+
ref: inputRef,
|
797
|
+
...validationResult,
|
798
|
+
};
|
799
|
+
if (!validateAllFieldCriteria) {
|
800
|
+
return error;
|
801
|
+
}
|
802
|
+
}
|
803
|
+
}
|
804
|
+
}
|
805
|
+
setCustomValidity(true);
|
806
|
+
return error;
|
807
|
+
};
|
808
|
+
|
559
809
|
function append(data, value) {
|
560
810
|
return [...data, ...convertToArrayPayload(value)];
|
561
811
|
}
|
@@ -587,6 +837,14 @@ function cloneObject(data) {
|
|
587
837
|
|
588
838
|
var fillEmptyArray = (value) => Array.isArray(value) ? value.map(() => undefined) : undefined;
|
589
839
|
|
840
|
+
var getValidationModes = (mode) => ({
|
841
|
+
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
842
|
+
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
843
|
+
isOnChange: mode === VALIDATION_MODE.onChange,
|
844
|
+
isOnAll: mode === VALIDATION_MODE.all,
|
845
|
+
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
846
|
+
});
|
847
|
+
|
590
848
|
function insert(data, index, value) {
|
591
849
|
return [
|
592
850
|
...data.slice(0, index),
|
@@ -680,7 +938,9 @@ function useFieldArray(props) {
|
|
680
938
|
_name.current = name;
|
681
939
|
_fieldIds.current = fields;
|
682
940
|
control._names.array.add(name);
|
683
|
-
|
941
|
+
props.rules &&
|
942
|
+
control.register(name, props.rules);
|
943
|
+
const callback = React.useCallback(({ values, name: fieldArrayName, }) => {
|
684
944
|
if (fieldArrayName === _name.current || !fieldArrayName) {
|
685
945
|
const fieldValues = get(values, _name.current, []);
|
686
946
|
setFields(fieldValues);
|
@@ -761,13 +1021,14 @@ function useFieldArray(props) {
|
|
761
1021
|
}, false);
|
762
1022
|
};
|
763
1023
|
const update = (index, value) => {
|
1024
|
+
const updateValue = cloneObject(value);
|
764
1025
|
const updatedFieldArrayValues = updateAt(control._getFieldArray(name), index, value);
|
765
1026
|
ids.current = [...updatedFieldArrayValues].map((item, i) => !item || i === index ? generateId() : ids.current[i]);
|
766
1027
|
updateValues(updatedFieldArrayValues);
|
767
1028
|
setFields([...updatedFieldArrayValues]);
|
768
1029
|
control._updateFieldArray(name, updatedFieldArrayValues, updateAt, {
|
769
1030
|
argA: index,
|
770
|
-
argB:
|
1031
|
+
argB: updateValue,
|
771
1032
|
}, true, false);
|
772
1033
|
};
|
773
1034
|
const replace = (value) => {
|
@@ -781,15 +1042,30 @@ function useFieldArray(props) {
|
|
781
1042
|
control._stateFlags.action = false;
|
782
1043
|
isWatched(name, control._names) && control._subjects.state.next({});
|
783
1044
|
if (_actioned.current) {
|
784
|
-
control.
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
1045
|
+
if (control._options.resolver) {
|
1046
|
+
control._executeSchema([name]).then((result) => {
|
1047
|
+
const error = get(result.errors, name);
|
1048
|
+
if (error && error.type && !get(control._formState.errors, name)) {
|
1049
|
+
set(control._formState.errors, name, error);
|
1050
|
+
control._subjects.state.next({
|
1051
|
+
errors: control._formState.errors,
|
1052
|
+
});
|
1053
|
+
}
|
1054
|
+
});
|
1055
|
+
}
|
1056
|
+
else {
|
1057
|
+
const field = get(control._fields, name);
|
1058
|
+
const validationModeBeforeSubmit = getValidationModes(control._options.mode);
|
1059
|
+
if ((!validationModeBeforeSubmit.isOnSubmit ||
|
1060
|
+
control._formState.isSubmitted) &&
|
1061
|
+
field &&
|
1062
|
+
field._f) {
|
1063
|
+
validateField(field, get(control._formValues, name), control._options.criteriaMode === VALIDATION_MODE.all, control._options.shouldUseNativeValidation, true).then((error) => !isEmptyObject(error) &&
|
1064
|
+
control._subjects.state.next({
|
1065
|
+
errors: updateFieldArrayRootError(control._formState.errors, error, name),
|
1066
|
+
}));
|
791
1067
|
}
|
792
|
-
}
|
1068
|
+
}
|
793
1069
|
}
|
794
1070
|
control._subjects.watch.next({
|
795
1071
|
name,
|
@@ -816,7 +1092,10 @@ function useFieldArray(props) {
|
|
816
1092
|
insert: React.useCallback(insert$1, [updateValues, name, control]),
|
817
1093
|
update: React.useCallback(update, [updateValues, name, control]),
|
818
1094
|
replace: React.useCallback(replace, [updateValues, name, control]),
|
819
|
-
fields: React.useMemo(() => fields.map((field, index) => (
|
1095
|
+
fields: React.useMemo(() => fields.map((field, index) => ({
|
1096
|
+
...field,
|
1097
|
+
key: ids.current[index] || generateId(),
|
1098
|
+
})), [fields]),
|
820
1099
|
};
|
821
1100
|
}
|
822
1101
|
|
@@ -881,24 +1160,10 @@ function deepEqual(object1, object2) {
|
|
881
1160
|
return true;
|
882
1161
|
}
|
883
1162
|
|
884
|
-
var getValidationModes = (mode) => ({
|
885
|
-
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
886
|
-
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
887
|
-
isOnChange: mode === VALIDATION_MODE.onChange,
|
888
|
-
isOnAll: mode === VALIDATION_MODE.all,
|
889
|
-
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
890
|
-
});
|
891
|
-
|
892
|
-
var isBoolean = (value) => typeof value === 'boolean';
|
893
|
-
|
894
|
-
var isFileInput = (element) => element.type === 'file';
|
895
|
-
|
896
1163
|
var isHTMLElement = (value) => value instanceof HTMLElement;
|
897
1164
|
|
898
1165
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
899
1166
|
|
900
|
-
var isRadioInput = (element) => element.type === 'radio';
|
901
|
-
|
902
1167
|
var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
903
1168
|
|
904
1169
|
var isWeb = typeof window !== 'undefined' &&
|
@@ -915,6 +1180,14 @@ function baseGet(object, updatePath) {
|
|
915
1180
|
}
|
916
1181
|
return object;
|
917
1182
|
}
|
1183
|
+
function isEmptyArray(obj) {
|
1184
|
+
for (const key in obj) {
|
1185
|
+
if (!isUndefined(obj[key])) {
|
1186
|
+
return false;
|
1187
|
+
}
|
1188
|
+
}
|
1189
|
+
return true;
|
1190
|
+
}
|
918
1191
|
function unset(object, path) {
|
919
1192
|
const updatePath = isKey(path) ? [path] : stringToPath(path);
|
920
1193
|
const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
|
@@ -936,10 +1209,7 @@ function unset(object, path) {
|
|
936
1209
|
objectRef = objectRef ? objectRef[item] : object[item];
|
937
1210
|
if (currentPathsLength === index &&
|
938
1211
|
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
939
|
-
(Array.isArray(objectRef) &&
|
940
|
-
!objectRef.filter((data) => (isObject(data) && !isEmptyObject(data)) ||
|
941
|
-
isBoolean(data) ||
|
942
|
-
(Array.isArray(data) && data.length)).length))) {
|
1212
|
+
(Array.isArray(objectRef) && isEmptyArray(objectRef)))) {
|
943
1213
|
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
944
1214
|
}
|
945
1215
|
previousObjRef = objectRef;
|
@@ -974,7 +1244,7 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
|
|
974
1244
|
isPrimitive(dirtyFieldsFromValues[key])) {
|
975
1245
|
dirtyFieldsFromValues[key] = Array.isArray(data[key])
|
976
1246
|
? markFieldsDirty(data[key], [])
|
977
|
-
:
|
1247
|
+
: { ...markFieldsDirty(data[key]) };
|
978
1248
|
}
|
979
1249
|
else {
|
980
1250
|
getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
@@ -989,31 +1259,6 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
|
|
989
1259
|
}
|
990
1260
|
var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
|
991
1261
|
|
992
|
-
const defaultResult = {
|
993
|
-
value: false,
|
994
|
-
isValid: false,
|
995
|
-
};
|
996
|
-
const validResult = { value: true, isValid: true };
|
997
|
-
var getCheckboxValue = (options) => {
|
998
|
-
if (Array.isArray(options)) {
|
999
|
-
if (options.length > 1) {
|
1000
|
-
const values = options
|
1001
|
-
.filter((option) => option && option.checked && !option.disabled)
|
1002
|
-
.map((option) => option.value);
|
1003
|
-
return { value: values, isValid: !!values.length };
|
1004
|
-
}
|
1005
|
-
return options[0].checked && !options[0].disabled
|
1006
|
-
? // @ts-expect-error expected to work in the browser
|
1007
|
-
options[0].attributes && !isUndefined(options[0].attributes.value)
|
1008
|
-
? isUndefined(options[0].value) || options[0].value === ''
|
1009
|
-
? validResult
|
1010
|
-
: { value: options[0].value, isValid: true }
|
1011
|
-
: validResult
|
1012
|
-
: defaultResult;
|
1013
|
-
}
|
1014
|
-
return defaultResult;
|
1015
|
-
};
|
1016
|
-
|
1017
1262
|
var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value)
|
1018
1263
|
? value
|
1019
1264
|
: valueAsNumber
|
@@ -1026,19 +1271,6 @@ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isU
|
|
1026
1271
|
? setValueAs(value)
|
1027
1272
|
: value;
|
1028
1273
|
|
1029
|
-
const defaultReturn = {
|
1030
|
-
isValid: false,
|
1031
|
-
value: null,
|
1032
|
-
};
|
1033
|
-
var getRadioValue = (options) => Array.isArray(options)
|
1034
|
-
? options.reduce((previous, option) => option && option.checked && !option.disabled
|
1035
|
-
? {
|
1036
|
-
isValid: true,
|
1037
|
-
value: option.value,
|
1038
|
-
}
|
1039
|
-
: previous, defaultReturn)
|
1040
|
-
: defaultReturn;
|
1041
|
-
|
1042
1274
|
function getFieldValue(_f) {
|
1043
1275
|
const ref = _f.ref;
|
1044
1276
|
if (_f.refs ? _f.refs.every((ref) => ref.disabled) : ref.disabled) {
|
@@ -1073,8 +1305,6 @@ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeVal
|
|
1073
1305
|
};
|
1074
1306
|
};
|
1075
1307
|
|
1076
|
-
var isRegex = (value) => value instanceof RegExp;
|
1077
|
-
|
1078
1308
|
var getRuleValue = (rule) => isUndefined(rule)
|
1079
1309
|
? undefined
|
1080
1310
|
: isRegex(rule)
|
@@ -1141,171 +1371,16 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
1141
1371
|
|
1142
1372
|
var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
|
1143
1373
|
|
1144
|
-
var isMessage = (value) => isString(value) || React.isValidElement(value);
|
1145
|
-
|
1146
|
-
function getValidateError(result, ref, type = 'validate') {
|
1147
|
-
if (isMessage(result) ||
|
1148
|
-
(Array.isArray(result) && result.every(isMessage)) ||
|
1149
|
-
(isBoolean(result) && !result)) {
|
1150
|
-
return {
|
1151
|
-
type,
|
1152
|
-
message: isMessage(result) ? result : '',
|
1153
|
-
ref,
|
1154
|
-
};
|
1155
|
-
}
|
1156
|
-
}
|
1157
|
-
|
1158
|
-
var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
|
1159
|
-
? validationData
|
1160
|
-
: {
|
1161
|
-
value: validationData,
|
1162
|
-
message: '',
|
1163
|
-
};
|
1164
|
-
|
1165
|
-
var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUseNativeValidation) => {
|
1166
|
-
const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled, } = field._f;
|
1167
|
-
if (!mount || disabled) {
|
1168
|
-
return {};
|
1169
|
-
}
|
1170
|
-
const inputRef = refs ? refs[0] : ref;
|
1171
|
-
const setCustomValidity = (message) => {
|
1172
|
-
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
1173
|
-
inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
|
1174
|
-
inputRef.reportValidity();
|
1175
|
-
}
|
1176
|
-
};
|
1177
|
-
const error = {};
|
1178
|
-
const isRadio = isRadioInput(ref);
|
1179
|
-
const isCheckBox = isCheckBoxInput(ref);
|
1180
|
-
const isRadioOrCheckbox = isRadio || isCheckBox;
|
1181
|
-
const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
|
1182
|
-
inputValue === '' ||
|
1183
|
-
(Array.isArray(inputValue) && !inputValue.length);
|
1184
|
-
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
1185
|
-
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
1186
|
-
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
1187
|
-
error[name] = Object.assign({ type: exceedMax ? maxType : minType, message,
|
1188
|
-
ref }, appendErrorsCurry(exceedMax ? maxType : minType, message));
|
1189
|
-
};
|
1190
|
-
if (required &&
|
1191
|
-
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
1192
|
-
(isBoolean(inputValue) && !inputValue) ||
|
1193
|
-
(isCheckBox && !getCheckboxValue(refs).isValid) ||
|
1194
|
-
(isRadio && !getRadioValue(refs).isValid))) {
|
1195
|
-
const { value, message } = isMessage(required)
|
1196
|
-
? { value: !!required, message: required }
|
1197
|
-
: getValueAndMessage(required);
|
1198
|
-
if (value) {
|
1199
|
-
error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.required, message, ref: inputRef }, appendErrorsCurry(INPUT_VALIDATION_RULES.required, message));
|
1200
|
-
if (!validateAllFieldCriteria) {
|
1201
|
-
setCustomValidity(message);
|
1202
|
-
return error;
|
1203
|
-
}
|
1204
|
-
}
|
1205
|
-
}
|
1206
|
-
if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
|
1207
|
-
let exceedMax;
|
1208
|
-
let exceedMin;
|
1209
|
-
const maxOutput = getValueAndMessage(max);
|
1210
|
-
const minOutput = getValueAndMessage(min);
|
1211
|
-
if (!isNaN(inputValue)) {
|
1212
|
-
const valueNumber = ref.valueAsNumber || +inputValue;
|
1213
|
-
if (!isNullOrUndefined(maxOutput.value)) {
|
1214
|
-
exceedMax = valueNumber > maxOutput.value;
|
1215
|
-
}
|
1216
|
-
if (!isNullOrUndefined(minOutput.value)) {
|
1217
|
-
exceedMin = valueNumber < minOutput.value;
|
1218
|
-
}
|
1219
|
-
}
|
1220
|
-
else {
|
1221
|
-
const valueDate = ref.valueAsDate || new Date(inputValue);
|
1222
|
-
if (isString(maxOutput.value)) {
|
1223
|
-
exceedMax = valueDate > new Date(maxOutput.value);
|
1224
|
-
}
|
1225
|
-
if (isString(minOutput.value)) {
|
1226
|
-
exceedMin = valueDate < new Date(minOutput.value);
|
1227
|
-
}
|
1228
|
-
}
|
1229
|
-
if (exceedMax || exceedMin) {
|
1230
|
-
getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
|
1231
|
-
if (!validateAllFieldCriteria) {
|
1232
|
-
setCustomValidity(error[name].message);
|
1233
|
-
return error;
|
1234
|
-
}
|
1235
|
-
}
|
1236
|
-
}
|
1237
|
-
if ((maxLength || minLength) && !isEmpty && isString(inputValue)) {
|
1238
|
-
const maxLengthOutput = getValueAndMessage(maxLength);
|
1239
|
-
const minLengthOutput = getValueAndMessage(minLength);
|
1240
|
-
const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
|
1241
|
-
inputValue.length > maxLengthOutput.value;
|
1242
|
-
const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
|
1243
|
-
inputValue.length < minLengthOutput.value;
|
1244
|
-
if (exceedMax || exceedMin) {
|
1245
|
-
getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
|
1246
|
-
if (!validateAllFieldCriteria) {
|
1247
|
-
setCustomValidity(error[name].message);
|
1248
|
-
return error;
|
1249
|
-
}
|
1250
|
-
}
|
1251
|
-
}
|
1252
|
-
if (pattern && !isEmpty && isString(inputValue)) {
|
1253
|
-
const { value: patternValue, message } = getValueAndMessage(pattern);
|
1254
|
-
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
1255
|
-
error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.pattern, message,
|
1256
|
-
ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message));
|
1257
|
-
if (!validateAllFieldCriteria) {
|
1258
|
-
setCustomValidity(message);
|
1259
|
-
return error;
|
1260
|
-
}
|
1261
|
-
}
|
1262
|
-
}
|
1263
|
-
if (validate) {
|
1264
|
-
if (isFunction(validate)) {
|
1265
|
-
const result = await validate(inputValue);
|
1266
|
-
const validateError = getValidateError(result, inputRef);
|
1267
|
-
if (validateError) {
|
1268
|
-
error[name] = Object.assign(Object.assign({}, validateError), appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message));
|
1269
|
-
if (!validateAllFieldCriteria) {
|
1270
|
-
setCustomValidity(validateError.message);
|
1271
|
-
return error;
|
1272
|
-
}
|
1273
|
-
}
|
1274
|
-
}
|
1275
|
-
else if (isObject(validate)) {
|
1276
|
-
let validationResult = {};
|
1277
|
-
for (const key in validate) {
|
1278
|
-
if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
|
1279
|
-
break;
|
1280
|
-
}
|
1281
|
-
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
1282
|
-
if (validateError) {
|
1283
|
-
validationResult = Object.assign(Object.assign({}, validateError), appendErrorsCurry(key, validateError.message));
|
1284
|
-
setCustomValidity(validateError.message);
|
1285
|
-
if (validateAllFieldCriteria) {
|
1286
|
-
error[name] = validationResult;
|
1287
|
-
}
|
1288
|
-
}
|
1289
|
-
}
|
1290
|
-
if (!isEmptyObject(validationResult)) {
|
1291
|
-
error[name] = Object.assign({ ref: inputRef }, validationResult);
|
1292
|
-
if (!validateAllFieldCriteria) {
|
1293
|
-
return error;
|
1294
|
-
}
|
1295
|
-
}
|
1296
|
-
}
|
1297
|
-
}
|
1298
|
-
setCustomValidity(true);
|
1299
|
-
return error;
|
1300
|
-
};
|
1301
|
-
|
1302
1374
|
const defaultOptions = {
|
1303
1375
|
mode: VALIDATION_MODE.onSubmit,
|
1304
1376
|
reValidateMode: VALIDATION_MODE.onChange,
|
1305
1377
|
shouldFocusError: true,
|
1306
1378
|
};
|
1307
1379
|
function createFormControl(props = {}) {
|
1308
|
-
let _options =
|
1380
|
+
let _options = {
|
1381
|
+
...defaultOptions,
|
1382
|
+
...props,
|
1383
|
+
};
|
1309
1384
|
let _formState = {
|
1310
1385
|
isDirty: false,
|
1311
1386
|
isValidating: false,
|
@@ -1319,7 +1394,7 @@ function createFormControl(props = {}) {
|
|
1319
1394
|
errors: {},
|
1320
1395
|
};
|
1321
1396
|
let _fields = {};
|
1322
|
-
let _defaultValues = _options.defaultValues || {};
|
1397
|
+
let _defaultValues = cloneObject(_options.defaultValues) || {};
|
1323
1398
|
let _formValues = _options.shouldUnregister
|
1324
1399
|
? {}
|
1325
1400
|
: cloneObject(_defaultValues);
|
@@ -1372,21 +1447,22 @@ function createFormControl(props = {}) {
|
|
1372
1447
|
}
|
1373
1448
|
return isValid;
|
1374
1449
|
};
|
1375
|
-
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true,
|
1450
|
+
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
1376
1451
|
if (args && method) {
|
1377
1452
|
_stateFlags.action = true;
|
1378
|
-
if (
|
1453
|
+
if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
|
1379
1454
|
const fieldValues = method(get(_fields, name), args.argA, args.argB);
|
1380
1455
|
shouldSetValues && set(_fields, name, fieldValues);
|
1381
1456
|
}
|
1382
1457
|
if (_proxyFormState.errors &&
|
1383
|
-
|
1458
|
+
shouldUpdateFieldsAndState &&
|
1384
1459
|
Array.isArray(get(_formState.errors, name))) {
|
1385
1460
|
const errors = method(get(_formState.errors, name), args.argA, args.argB);
|
1386
1461
|
shouldSetValues && set(_formState.errors, name, errors);
|
1387
1462
|
unsetEmptyArray(_formState.errors, name);
|
1388
1463
|
}
|
1389
1464
|
if (_proxyFormState.touchedFields &&
|
1465
|
+
shouldUpdateFieldsAndState &&
|
1390
1466
|
Array.isArray(get(_formState.touchedFields, name))) {
|
1391
1467
|
const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
1392
1468
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
@@ -1472,8 +1548,16 @@ function createFormControl(props = {}) {
|
|
1472
1548
|
!isEmptyObject(fieldState) ||
|
1473
1549
|
shouldUpdateValid) &&
|
1474
1550
|
!shouldSkipRender) {
|
1475
|
-
const updatedFormState =
|
1476
|
-
|
1551
|
+
const updatedFormState = {
|
1552
|
+
...fieldState,
|
1553
|
+
...(shouldUpdateValid ? { isValid } : {}),
|
1554
|
+
errors: _formState.errors,
|
1555
|
+
name,
|
1556
|
+
};
|
1557
|
+
_formState = {
|
1558
|
+
..._formState,
|
1559
|
+
...updatedFormState,
|
1560
|
+
};
|
1477
1561
|
_subjects.state.next(updatedFormState);
|
1478
1562
|
}
|
1479
1563
|
validateFields[name]--;
|
@@ -1486,7 +1570,7 @@ function createFormControl(props = {}) {
|
|
1486
1570
|
}
|
1487
1571
|
};
|
1488
1572
|
const _executeSchema = async (name) => _options.resolver
|
1489
|
-
? await _options.resolver(
|
1573
|
+
? await _options.resolver({ ..._formValues }, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
|
1490
1574
|
: {};
|
1491
1575
|
const executeSchemaAndUpdateState = async (names) => {
|
1492
1576
|
const { errors } = await _executeSchema();
|
@@ -1509,21 +1593,22 @@ function createFormControl(props = {}) {
|
|
1509
1593
|
for (const name in fields) {
|
1510
1594
|
const field = fields[name];
|
1511
1595
|
if (field) {
|
1512
|
-
const
|
1513
|
-
|
1514
|
-
|
1515
|
-
const fieldError = await validateField(field, get(_formValues,
|
1516
|
-
if (fieldError[
|
1596
|
+
const { _f, ...fieldValue } = field;
|
1597
|
+
if (_f) {
|
1598
|
+
const isFieldArrayRoot = _names.array.has(_f.name);
|
1599
|
+
const fieldError = await validateField(field, get(_formValues, _f.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
|
1600
|
+
if (fieldError[_f.name]) {
|
1517
1601
|
context.valid = false;
|
1518
1602
|
if (shouldOnlyCheckValid) {
|
1519
1603
|
break;
|
1520
1604
|
}
|
1521
1605
|
}
|
1522
|
-
|
1523
|
-
fieldError
|
1524
|
-
?
|
1525
|
-
|
1526
|
-
|
1606
|
+
!shouldOnlyCheckValid &&
|
1607
|
+
(get(fieldError, _f.name)
|
1608
|
+
? isFieldArrayRoot
|
1609
|
+
? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
|
1610
|
+
: set(_formState.errors, _f.name, fieldError[_f.name])
|
1611
|
+
: unset(_formState.errors, _f.name));
|
1527
1612
|
}
|
1528
1613
|
fieldValue &&
|
1529
1614
|
(await executeBuildInValidation(fieldValue, shouldOnlyCheckValid, context));
|
@@ -1545,13 +1630,15 @@ function createFormControl(props = {}) {
|
|
1545
1630
|
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
1546
1631
|
!deepEqual(getValues(), _defaultValues));
|
1547
1632
|
const _getWatch = (names, defaultValue, isGlobal) => {
|
1548
|
-
const fieldValues =
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1633
|
+
const fieldValues = {
|
1634
|
+
...(_stateFlags.mount
|
1635
|
+
? _formValues
|
1636
|
+
: isUndefined(defaultValue)
|
1637
|
+
? _defaultValues
|
1638
|
+
: isString(names)
|
1639
|
+
? { [names]: defaultValue }
|
1640
|
+
: defaultValue),
|
1641
|
+
};
|
1555
1642
|
return generateWatchOutput(names, _names, fieldValues, isGlobal);
|
1556
1643
|
};
|
1557
1644
|
const _getFieldArray = (name) => compact(get(_stateFlags.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []));
|
@@ -1573,9 +1660,10 @@ function createFormControl(props = {}) {
|
|
1573
1660
|
else if (fieldReference.refs) {
|
1574
1661
|
if (isCheckBoxInput(fieldReference.ref)) {
|
1575
1662
|
fieldReference.refs.length > 1
|
1576
|
-
? fieldReference.refs.forEach((checkboxRef) =>
|
1577
|
-
|
1578
|
-
|
1663
|
+
? fieldReference.refs.forEach((checkboxRef) => !checkboxRef.disabled &&
|
1664
|
+
(checkboxRef.checked = Array.isArray(fieldValue)
|
1665
|
+
? !!fieldValue.find((data) => data === checkboxRef.value)
|
1666
|
+
: fieldValue === checkboxRef.value))
|
1579
1667
|
: fieldReference.refs[0] &&
|
1580
1668
|
(fieldReference.refs[0].checked = !!fieldValue);
|
1581
1669
|
}
|
@@ -1676,7 +1764,7 @@ function createFormControl(props = {}) {
|
|
1676
1764
|
});
|
1677
1765
|
if (shouldSkipValidation) {
|
1678
1766
|
return (shouldRender &&
|
1679
|
-
_subjects.state.next(
|
1767
|
+
_subjects.state.next({ name, ...(watched ? {} : fieldState) }));
|
1680
1768
|
}
|
1681
1769
|
!isBlurEvent && watched && _subjects.state.next({});
|
1682
1770
|
validateFields[name] = validateFields[name] ? +1 : 1;
|
@@ -1695,7 +1783,8 @@ function createFormControl(props = {}) {
|
|
1695
1783
|
error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1696
1784
|
isValid = await _updateValid(true);
|
1697
1785
|
}
|
1698
|
-
field._f.deps &&
|
1786
|
+
field._f.deps &&
|
1787
|
+
trigger(field._f.deps);
|
1699
1788
|
shouldRenderByError(false, name, isValid, error, fieldState);
|
1700
1789
|
}
|
1701
1790
|
};
|
@@ -1723,17 +1812,25 @@ function createFormControl(props = {}) {
|
|
1723
1812
|
else {
|
1724
1813
|
validationResult = isValid = await executeBuildInValidation(_fields);
|
1725
1814
|
}
|
1726
|
-
_subjects.state.next(
|
1727
|
-
(
|
1728
|
-
|
1729
|
-
|
1815
|
+
_subjects.state.next({
|
1816
|
+
...(!isString(name) ||
|
1817
|
+
(_proxyFormState.isValid && isValid !== _formState.isValid)
|
1818
|
+
? {}
|
1819
|
+
: { name }),
|
1820
|
+
...(_options.resolver ? { isValid } : {}),
|
1821
|
+
errors: _formState.errors,
|
1822
|
+
isValidating: false,
|
1823
|
+
});
|
1730
1824
|
options.shouldFocus &&
|
1731
1825
|
!validationResult &&
|
1732
1826
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), name ? fieldNames : _names.mount);
|
1733
1827
|
return validationResult;
|
1734
1828
|
};
|
1735
1829
|
const getValues = (fieldNames) => {
|
1736
|
-
const values =
|
1830
|
+
const values = {
|
1831
|
+
..._defaultValues,
|
1832
|
+
...(_stateFlags.mount ? _formValues : {}),
|
1833
|
+
};
|
1737
1834
|
return isUndefined(fieldNames)
|
1738
1835
|
? values
|
1739
1836
|
: isString(fieldNames)
|
@@ -1741,7 +1838,6 @@ function createFormControl(props = {}) {
|
|
1741
1838
|
: fieldNames.map((name) => get(values, name));
|
1742
1839
|
};
|
1743
1840
|
const getFieldState = (name, formState) => ({
|
1744
|
-
invalid: !!get((formState || _formState).errors, name),
|
1745
1841
|
isDirty: !!get((formState || _formState).dirtyFields, name),
|
1746
1842
|
isTouched: !!get((formState || _formState).touchedFields, name),
|
1747
1843
|
error: get((formState || _formState).errors, name),
|
@@ -1756,7 +1852,10 @@ function createFormControl(props = {}) {
|
|
1756
1852
|
};
|
1757
1853
|
const setError = (name, error, options) => {
|
1758
1854
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
1759
|
-
set(_formState.errors, name,
|
1855
|
+
set(_formState.errors, name, {
|
1856
|
+
...error,
|
1857
|
+
ref,
|
1858
|
+
});
|
1760
1859
|
_subjects.state.next({
|
1761
1860
|
name,
|
1762
1861
|
errors: _formState.errors,
|
@@ -1787,14 +1886,22 @@ function createFormControl(props = {}) {
|
|
1787
1886
|
}
|
1788
1887
|
}
|
1789
1888
|
_subjects.watch.next({});
|
1790
|
-
_subjects.state.next(
|
1889
|
+
_subjects.state.next({
|
1890
|
+
..._formState,
|
1891
|
+
...(!options.keepDirty ? {} : { isDirty: _getDirty() }),
|
1892
|
+
});
|
1791
1893
|
_proxyFormState.isValid && _updateValid();
|
1792
1894
|
};
|
1793
1895
|
const register = (name, options = {}) => {
|
1794
1896
|
let field = get(_fields, name);
|
1795
1897
|
const disabledIsDefined = isBoolean(options.disabled);
|
1796
1898
|
set(_fields, name, {
|
1797
|
-
_f:
|
1899
|
+
_f: {
|
1900
|
+
...(field && field._f ? field._f : { ref: { name } }),
|
1901
|
+
name,
|
1902
|
+
mount: true,
|
1903
|
+
...options,
|
1904
|
+
},
|
1798
1905
|
});
|
1799
1906
|
_names.mount.add(name);
|
1800
1907
|
field
|
@@ -1803,17 +1910,22 @@ function createFormControl(props = {}) {
|
|
1803
1910
|
? undefined
|
1804
1911
|
: get(_formValues, name, getFieldValue(field._f)))
|
1805
1912
|
: updateValidAndValue(name, true, options.value);
|
1806
|
-
return
|
1807
|
-
? {
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1913
|
+
return {
|
1914
|
+
...(disabledIsDefined ? { disabled: options.disabled } : {}),
|
1915
|
+
...(_options.shouldUseNativeValidation
|
1916
|
+
? {
|
1917
|
+
required: !!options.required,
|
1918
|
+
min: getRuleValue(options.min),
|
1919
|
+
max: getRuleValue(options.max),
|
1920
|
+
minLength: getRuleValue(options.minLength),
|
1921
|
+
maxLength: getRuleValue(options.maxLength),
|
1922
|
+
pattern: getRuleValue(options.pattern),
|
1923
|
+
}
|
1924
|
+
: {}),
|
1925
|
+
name,
|
1926
|
+
onChange,
|
1927
|
+
onBlur: onChange,
|
1928
|
+
ref: (ref) => {
|
1817
1929
|
if (ref) {
|
1818
1930
|
register(name, options);
|
1819
1931
|
field = get(_fields, name);
|
@@ -1830,12 +1942,15 @@ function createFormControl(props = {}) {
|
|
1830
1942
|
return;
|
1831
1943
|
}
|
1832
1944
|
set(_fields, name, {
|
1833
|
-
_f:
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1945
|
+
_f: {
|
1946
|
+
...field._f,
|
1947
|
+
...(radioOrCheckbox
|
1948
|
+
? {
|
1949
|
+
refs: [...refs.filter(live), fieldRef],
|
1950
|
+
ref: { type: fieldRef.type, name },
|
1951
|
+
}
|
1952
|
+
: { ref: fieldRef }),
|
1953
|
+
},
|
1839
1954
|
});
|
1840
1955
|
updateValidAndValue(name, false, undefined, fieldRef);
|
1841
1956
|
}
|
@@ -1848,7 +1963,8 @@ function createFormControl(props = {}) {
|
|
1848
1963
|
!(isNameInFieldArray(_names.array, name) && _stateFlags.action) &&
|
1849
1964
|
_names.unMount.add(name);
|
1850
1965
|
}
|
1851
|
-
}
|
1966
|
+
},
|
1967
|
+
};
|
1852
1968
|
};
|
1853
1969
|
const handleSubmit = (onValid, onInvalid) => async (e) => {
|
1854
1970
|
if (e) {
|
@@ -1879,7 +1995,7 @@ function createFormControl(props = {}) {
|
|
1879
1995
|
}
|
1880
1996
|
else {
|
1881
1997
|
if (onInvalid) {
|
1882
|
-
await onInvalid(
|
1998
|
+
await onInvalid({ ..._formState.errors }, e);
|
1883
1999
|
}
|
1884
2000
|
_options.shouldFocusError &&
|
1885
2001
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
|
@@ -1922,7 +2038,7 @@ function createFormControl(props = {}) {
|
|
1922
2038
|
unset(_formState.errors, name);
|
1923
2039
|
_proxyFormState.isValid && _updateValid();
|
1924
2040
|
}
|
1925
|
-
_subjects.state.next(
|
2041
|
+
_subjects.state.next({ ..._formState });
|
1926
2042
|
}
|
1927
2043
|
};
|
1928
2044
|
const reset = (formValues, keepStateOptions = {}) => {
|
@@ -1973,7 +2089,10 @@ function createFormControl(props = {}) {
|
|
1973
2089
|
dirtyFields: keepStateOptions.keepDirty
|
1974
2090
|
? _formState.dirtyFields
|
1975
2091
|
: (keepStateOptions.keepDefaultValues && formValues
|
1976
|
-
? Object.entries(formValues).reduce((previous, [key, value]) => (
|
2092
|
+
? Object.entries(formValues).reduce((previous, [key, value]) => ({
|
2093
|
+
...previous,
|
2094
|
+
[key]: value !== get(_defaultValues, key),
|
2095
|
+
}), {})
|
1977
2096
|
: {}),
|
1978
2097
|
touchedFields: keepStateOptions.keepTouched
|
1979
2098
|
? _formState.touchedFields
|
@@ -2035,7 +2154,10 @@ function createFormControl(props = {}) {
|
|
2035
2154
|
return _options;
|
2036
2155
|
},
|
2037
2156
|
set _options(value) {
|
2038
|
-
_options =
|
2157
|
+
_options = {
|
2158
|
+
..._options,
|
2159
|
+
...value,
|
2160
|
+
};
|
2039
2161
|
},
|
2040
2162
|
},
|
2041
2163
|
trigger,
|
@@ -2101,13 +2223,19 @@ function useForm(props = {}) {
|
|
2101
2223
|
_formControl.current.control._options = props;
|
2102
2224
|
}
|
2103
2225
|
else {
|
2104
|
-
_formControl.current =
|
2226
|
+
_formControl.current = {
|
2227
|
+
...createFormControl(props),
|
2228
|
+
formState,
|
2229
|
+
};
|
2105
2230
|
}
|
2106
2231
|
const control = _formControl.current.control;
|
2107
2232
|
const callback = React.useCallback((value) => {
|
2108
2233
|
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2109
|
-
control._formState =
|
2110
|
-
|
2234
|
+
control._formState = {
|
2235
|
+
...control._formState,
|
2236
|
+
...value,
|
2237
|
+
};
|
2238
|
+
updateFormState({ ...control._formState });
|
2111
2239
|
}
|
2112
2240
|
}, [control]);
|
2113
2241
|
useSubscribe({
|