react-hook-form 7.76.1 → 7.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +82 -45
- 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/index.d.ts +2 -3
- package/dist/logic/index.d.ts.map +1 -1
- package/dist/logic/isWatched.d.ts.map +1 -1
- package/dist/logic/skipValidation.d.ts +1 -4
- package/dist/logic/skipValidation.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +45 -13
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/form.d.ts +23 -3
- package/dist/types/form.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useFormContext.d.ts +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useIsomorphicLayoutEffect.d.ts.map +1 -1
- package/dist/utils/get.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -3
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/set.d.ts.map +1 -1
- package/dist/utils/stringToPath.d.ts.map +1 -1
- package/package.json +17 -17
package/dist/index.esm.mjs
CHANGED
|
@@ -52,19 +52,48 @@ function cloneObject(data) {
|
|
|
52
52
|
return copy;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
const EVENTS = {
|
|
56
|
+
BLUR: 'blur',
|
|
57
|
+
FOCUS_OUT: 'focusout',
|
|
58
|
+
CHANGE: 'change',
|
|
59
|
+
SUBMIT: 'submit',
|
|
60
|
+
TRIGGER: 'trigger',
|
|
61
|
+
VALID: 'valid',
|
|
62
|
+
};
|
|
63
|
+
const VALIDATION_MODE = {
|
|
64
|
+
onBlur: 'onBlur',
|
|
65
|
+
onChange: 'onChange',
|
|
66
|
+
onSubmit: 'onSubmit',
|
|
67
|
+
onTouched: 'onTouched',
|
|
68
|
+
all: 'all',
|
|
69
|
+
};
|
|
70
|
+
const INPUT_VALIDATION_RULES = {
|
|
71
|
+
max: 'max',
|
|
72
|
+
min: 'min',
|
|
73
|
+
maxLength: 'maxLength',
|
|
74
|
+
minLength: 'minLength',
|
|
75
|
+
pattern: 'pattern',
|
|
76
|
+
required: 'required',
|
|
77
|
+
validate: 'validate',
|
|
78
|
+
};
|
|
79
|
+
const FORM_ERROR_TYPE = 'form';
|
|
80
|
+
const ROOT_ERROR_TYPE = 'root';
|
|
81
|
+
const PROTOTYPE_KEYWORDS = ['__proto__', 'constructor', 'prototype'];
|
|
82
|
+
|
|
55
83
|
var isKey = (value) => /^\w*$/.test(value);
|
|
56
84
|
|
|
57
85
|
var isUndefined = (val) => val === undefined;
|
|
58
86
|
|
|
59
|
-
var
|
|
60
|
-
|
|
61
|
-
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
|
|
87
|
+
var stringToPath = (input) => input.split(/[.[\]'"]/g).filter(Boolean);
|
|
62
88
|
|
|
63
89
|
var get = (object, path, defaultValue) => {
|
|
64
90
|
if (!path || !isObject(object)) {
|
|
65
91
|
return defaultValue;
|
|
66
92
|
}
|
|
67
93
|
const paths = isKey(path) ? [path] : stringToPath(path);
|
|
94
|
+
if (paths.some((key) => PROTOTYPE_KEYWORDS.includes(key))) {
|
|
95
|
+
return defaultValue;
|
|
96
|
+
}
|
|
68
97
|
const result = paths.reduce((result, key) => {
|
|
69
98
|
return isNullOrUndefined(result) ? undefined : result[key];
|
|
70
99
|
}, object);
|
|
@@ -96,7 +125,7 @@ var set = (object, path, value) => {
|
|
|
96
125
|
? []
|
|
97
126
|
: {};
|
|
98
127
|
}
|
|
99
|
-
if (key
|
|
128
|
+
if (PROTOTYPE_KEYWORDS.includes(key)) {
|
|
100
129
|
return;
|
|
101
130
|
}
|
|
102
131
|
object[key] = newValue;
|
|
@@ -104,33 +133,6 @@ var set = (object, path, value) => {
|
|
|
104
133
|
}
|
|
105
134
|
};
|
|
106
135
|
|
|
107
|
-
const EVENTS = {
|
|
108
|
-
BLUR: 'blur',
|
|
109
|
-
FOCUS_OUT: 'focusout',
|
|
110
|
-
CHANGE: 'change',
|
|
111
|
-
SUBMIT: 'submit',
|
|
112
|
-
TRIGGER: 'trigger',
|
|
113
|
-
VALID: 'valid',
|
|
114
|
-
};
|
|
115
|
-
const VALIDATION_MODE = {
|
|
116
|
-
onBlur: 'onBlur',
|
|
117
|
-
onChange: 'onChange',
|
|
118
|
-
onSubmit: 'onSubmit',
|
|
119
|
-
onTouched: 'onTouched',
|
|
120
|
-
all: 'all',
|
|
121
|
-
};
|
|
122
|
-
const INPUT_VALIDATION_RULES = {
|
|
123
|
-
max: 'max',
|
|
124
|
-
min: 'min',
|
|
125
|
-
maxLength: 'maxLength',
|
|
126
|
-
minLength: 'minLength',
|
|
127
|
-
pattern: 'pattern',
|
|
128
|
-
required: 'required',
|
|
129
|
-
validate: 'validate',
|
|
130
|
-
};
|
|
131
|
-
const FORM_ERROR_TYPE = 'form';
|
|
132
|
-
const ROOT_ERROR_TYPE = 'root';
|
|
133
|
-
|
|
134
136
|
/**
|
|
135
137
|
* Separate context for `control` to prevent unnecessary rerenders.
|
|
136
138
|
* Internal hooks that only need control use this instead of full form context.
|
|
@@ -159,7 +161,9 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
|
159
161
|
return result;
|
|
160
162
|
};
|
|
161
163
|
|
|
162
|
-
const useIsomorphicLayoutEffect =
|
|
164
|
+
const useIsomorphicLayoutEffect = isWeb
|
|
165
|
+
? React.useLayoutEffect
|
|
166
|
+
: React.useEffect;
|
|
163
167
|
|
|
164
168
|
/**
|
|
165
169
|
* This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
|
|
@@ -640,8 +644,7 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
|
640
644
|
* }
|
|
641
645
|
* ```
|
|
642
646
|
*/
|
|
643
|
-
const FormProvider = (
|
|
644
|
-
const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
|
|
647
|
+
const FormProvider = ({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, }) => {
|
|
645
648
|
const memoizedValue = React.useMemo(() => ({
|
|
646
649
|
watch,
|
|
647
650
|
getValues,
|
|
@@ -806,6 +809,8 @@ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => va
|
|
|
806
809
|
}
|
|
807
810
|
: {};
|
|
808
811
|
|
|
812
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
813
|
+
|
|
809
814
|
var convertToArrayPayload = (value) => (Array.isArray(value) ? value : [value]);
|
|
810
815
|
|
|
811
816
|
var createSubject = () => {
|
|
@@ -1115,8 +1120,7 @@ var hasValidation = (options) => options.mount &&
|
|
|
1115
1120
|
var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
|
|
1116
1121
|
(_names.watchAll ||
|
|
1117
1122
|
_names.watch.has(name) ||
|
|
1118
|
-
[..._names.watch].some((watchName) => name.startsWith(watchName)
|
|
1119
|
-
/^\.\w+/.test(name.slice(watchName.length))));
|
|
1123
|
+
[..._names.watch].some((watchName) => name.startsWith(`${watchName}.`)));
|
|
1120
1124
|
|
|
1121
1125
|
const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
1122
1126
|
for (const key of fieldsNames || Object.keys(fields)) {
|
|
@@ -1219,7 +1223,8 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
|
1219
1223
|
var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
|
|
1220
1224
|
|
|
1221
1225
|
var updateFieldArrayRootError = (errors, error, name) => {
|
|
1222
|
-
const
|
|
1226
|
+
const existingErrors = get(errors, name);
|
|
1227
|
+
const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
|
|
1223
1228
|
set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
|
|
1224
1229
|
set(errors, name, fieldArrayErrors);
|
|
1225
1230
|
return errors;
|
|
@@ -1734,7 +1739,9 @@ function createFormControl(props = {}) {
|
|
|
1734
1739
|
for (const name of names) {
|
|
1735
1740
|
const error = get(errors, name);
|
|
1736
1741
|
error
|
|
1737
|
-
? _names.array.has(name) &&
|
|
1742
|
+
? _names.array.has(name) &&
|
|
1743
|
+
isObject(error) &&
|
|
1744
|
+
!Object.keys(error).some((key) => !Number.isNaN(Number(key)))
|
|
1738
1745
|
? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
|
|
1739
1746
|
: set(_formState.errors, name, error)
|
|
1740
1747
|
: unset(_formState.errors, name);
|
|
@@ -2481,7 +2488,7 @@ function createFormControl(props = {}) {
|
|
|
2481
2488
|
const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
|
|
2482
2489
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
|
2483
2490
|
const isEmptyResetValues = isEmptyObject(formValues);
|
|
2484
|
-
const values =
|
|
2491
|
+
const values = cloneUpdatedValues;
|
|
2485
2492
|
if (!keepStateOptions.keepDefaultValues) {
|
|
2486
2493
|
_defaultValues = updatedValues;
|
|
2487
2494
|
}
|
|
@@ -2530,11 +2537,19 @@ function createFormControl(props = {}) {
|
|
|
2530
2537
|
_fields = {};
|
|
2531
2538
|
}
|
|
2532
2539
|
}
|
|
2533
|
-
|
|
2534
|
-
|
|
2540
|
+
if (_options.shouldUnregister) {
|
|
2541
|
+
_formValues = keepStateOptions.keepDefaultValues
|
|
2535
2542
|
? cloneObject(_defaultValues)
|
|
2536
|
-
: {}
|
|
2537
|
-
|
|
2543
|
+
: {};
|
|
2544
|
+
if (keepStateOptions.keepFieldsRef) {
|
|
2545
|
+
for (const fieldName of _names.mount) {
|
|
2546
|
+
set(_formValues, fieldName, get(values, fieldName));
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
else {
|
|
2551
|
+
_formValues = cloneObject(values);
|
|
2552
|
+
}
|
|
2538
2553
|
_subjects.array.next({
|
|
2539
2554
|
values: { ...values },
|
|
2540
2555
|
});
|
|
@@ -2574,8 +2589,10 @@ function createFormControl(props = {}) {
|
|
|
2574
2589
|
? false
|
|
2575
2590
|
: keepStateOptions.keepDirty
|
|
2576
2591
|
? _formState.isDirty
|
|
2577
|
-
:
|
|
2578
|
-
|
|
2592
|
+
: keepStateOptions.keepValues
|
|
2593
|
+
? _getDirty()
|
|
2594
|
+
: !!(keepStateOptions.keepDefaultValues &&
|
|
2595
|
+
!deepEqual(formValues, _defaultValues)),
|
|
2579
2596
|
isSubmitted: keepStateOptions.keepIsSubmitted
|
|
2580
2597
|
? _formState.isSubmitted
|
|
2581
2598
|
: false,
|
|
@@ -2636,6 +2653,21 @@ function createFormControl(props = {}) {
|
|
|
2636
2653
|
isLoading: false,
|
|
2637
2654
|
});
|
|
2638
2655
|
});
|
|
2656
|
+
const resetDefaultValues = (values, options = {}) => {
|
|
2657
|
+
_defaultValues = cloneObject(values);
|
|
2658
|
+
if (!options.keepDirty) {
|
|
2659
|
+
const newDirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
2660
|
+
_formState.dirtyFields = newDirtyFields;
|
|
2661
|
+
_formState.isDirty = !isEmptyObject(newDirtyFields);
|
|
2662
|
+
}
|
|
2663
|
+
if (!options.keepIsValid) {
|
|
2664
|
+
_setValid();
|
|
2665
|
+
}
|
|
2666
|
+
_subjects.state.next({
|
|
2667
|
+
..._formState,
|
|
2668
|
+
defaultValues: _defaultValues,
|
|
2669
|
+
});
|
|
2670
|
+
};
|
|
2639
2671
|
const methods = {
|
|
2640
2672
|
control: {
|
|
2641
2673
|
register,
|
|
@@ -2704,6 +2736,7 @@ function createFormControl(props = {}) {
|
|
|
2704
2736
|
getValues,
|
|
2705
2737
|
reset,
|
|
2706
2738
|
resetField,
|
|
2739
|
+
resetDefaultValues,
|
|
2707
2740
|
clearErrors,
|
|
2708
2741
|
unregister,
|
|
2709
2742
|
setError,
|
|
@@ -2840,6 +2873,10 @@ function useFieldArray(props) {
|
|
|
2840
2873
|
setFields(fieldValues);
|
|
2841
2874
|
ids.current = fieldValues.map(generateId);
|
|
2842
2875
|
}
|
|
2876
|
+
else if (!fieldArrayName) {
|
|
2877
|
+
setFields([]);
|
|
2878
|
+
ids.current = [];
|
|
2879
|
+
}
|
|
2843
2880
|
}
|
|
2844
2881
|
},
|
|
2845
2882
|
}).unsubscribe, [control, name]);
|