react-hook-form 8.0.0-beta.1 → 8.0.0-beta.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 +16 -29
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/form.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 +395 -153
- 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 +13 -0
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/logic/{isNameInFieldArray.d.ts → getFieldArrayParentNames.d.ts} +2 -2
- package/dist/logic/getFieldArrayParentNames.d.ts.map +1 -0
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/logic/getResolverOptions.d.ts +2 -2
- package/dist/logic/hasValidation.d.ts +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
- package/dist/logic/validateField.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +310 -76
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/errors.d.ts +1 -0
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/form.d.ts +12 -5
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/path/eager.d.ts +1 -1
- package/dist/types/path/eager.d.ts.map +1 -1
- package/dist/types/utils.d.ts +2 -2
- package/dist/types/validator.d.ts +13 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/utils/deepEqual.d.ts +1 -1
- package/dist/utils/deepEqual.d.ts.map +1 -1
- package/dist/utils/unset.d.ts.map +1 -1
- package/dist/watch.d.ts +1 -1
- package/dist/watch.d.ts.map +1 -1
- package/package.json +25 -26
- package/dist/__tests__/controller.server.test.d.ts +0 -2
- package/dist/__tests__/controller.server.test.d.ts.map +0 -1
- package/dist/__tests__/controller.test.d.ts +0 -2
- package/dist/__tests__/controller.test.d.ts.map +0 -1
- package/dist/__tests__/form.test.d.ts +0 -2
- package/dist/__tests__/form.test.d.ts.map +0 -1
- package/dist/__tests__/formStateSubscribe.server.test.d.ts +0 -2
- package/dist/__tests__/formStateSubscribe.server.test.d.ts.map +0 -1
- package/dist/__tests__/formStateSubscribe.test.d.ts +0 -2
- package/dist/__tests__/formStateSubscribe.test.d.ts.map +0 -1
- package/dist/__tests__/isPlainObject.test.d.ts +0 -2
- package/dist/__tests__/isPlainObject.test.d.ts.map +0 -1
- package/dist/__tests__/logic/appendErrors.test.d.ts +0 -2
- package/dist/__tests__/logic/appendErrors.test.d.ts.map +0 -1
- package/dist/__tests__/logic/createFormControl.test.d.ts +0 -2
- package/dist/__tests__/logic/createFormControl.test.d.ts.map +0 -1
- package/dist/__tests__/logic/generateId.test.d.ts +0 -2
- package/dist/__tests__/logic/generateId.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getCheckboxValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getDirtyFields.test.d.ts +0 -2
- package/dist/__tests__/logic/getDirtyFields.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getEventValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getEventValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getFieldValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getFieldValueAs.test.d.ts +0 -2
- package/dist/__tests__/logic/getFieldValueAs.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getFocusFieldName.test.d.ts +0 -2
- package/dist/__tests__/logic/getFocusFieldName.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -2
- package/dist/__tests__/logic/getNodeParentName.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getRadioValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getResolverOptions.test.d.ts +0 -2
- package/dist/__tests__/logic/getResolverOptions.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getRuleValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getRuleValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getValidateError.test.d.ts +0 -2
- package/dist/__tests__/logic/getValidateError.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getValidationModes.test.d.ts +0 -2
- package/dist/__tests__/logic/getValidationModes.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -2
- package/dist/__tests__/logic/getValueAndMessage.test.d.ts.map +0 -1
- package/dist/__tests__/logic/hasPromiseValidation.test.d.ts +0 -2
- package/dist/__tests__/logic/hasPromiseValidation.test.d.ts.map +0 -1
- package/dist/__tests__/logic/hasValidation.test.d.ts +0 -2
- package/dist/__tests__/logic/hasValidation.test.d.ts.map +0 -1
- package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -2
- package/dist/__tests__/logic/isNameInFieldArray.test.d.ts.map +0 -1
- package/dist/__tests__/logic/isWatched.test.d.ts +0 -2
- package/dist/__tests__/logic/isWatched.test.d.ts.map +0 -1
- package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts +0 -2
- package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts.map +0 -1
- package/dist/__tests__/logic/schemaErrorLookup.test.d.ts +0 -2
- package/dist/__tests__/logic/schemaErrorLookup.test.d.ts.map +0 -1
- package/dist/__tests__/logic/shouldRenderFormState.test.d.ts +0 -2
- package/dist/__tests__/logic/shouldRenderFormState.test.d.ts.map +0 -1
- package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts +0 -2
- package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts.map +0 -1
- package/dist/__tests__/logic/skipValidation.test.d.ts +0 -2
- package/dist/__tests__/logic/skipValidation.test.d.ts.map +0 -1
- package/dist/__tests__/logic/unsetEmptyArray.test.d.ts +0 -2
- package/dist/__tests__/logic/unsetEmptyArray.test.d.ts.map +0 -1
- package/dist/__tests__/logic/validateField.test.d.ts +0 -2
- package/dist/__tests__/logic/validateField.test.d.ts.map +0 -1
- package/dist/__tests__/type.test.d.ts +0 -2
- package/dist/__tests__/type.test.d.ts.map +0 -1
- package/dist/__tests__/useController.test.d.ts +0 -2
- package/dist/__tests__/useController.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/append.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/append.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/focus.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/insert.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/move.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/move.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/remove.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/replace.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/replace.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/swap.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/update.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/update.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -2
- package/dist/__tests__/useForm/clearErrors.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/formState.test.d.ts +0 -2
- package/dist/__tests__/useForm/formState.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/getFieldState.test.d.ts +0 -2
- package/dist/__tests__/useForm/getFieldState.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/getValues.test.d.ts +0 -2
- package/dist/__tests__/useForm/getValues.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -2
- package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/register.test.d.ts +0 -2
- package/dist/__tests__/useForm/register.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/reset.test.d.ts +0 -2
- package/dist/__tests__/useForm/reset.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/resetField.test.d.ts +0 -2
- package/dist/__tests__/useForm/resetField.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/resolver.test.d.ts +0 -2
- package/dist/__tests__/useForm/resolver.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/setError.test.d.ts +0 -2
- package/dist/__tests__/useForm/setError.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/setFocus.test.d.ts +0 -2
- package/dist/__tests__/useForm/setFocus.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/setValue.test.d.ts +0 -2
- package/dist/__tests__/useForm/setValue.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/subscribe.test.d.ts +0 -2
- package/dist/__tests__/useForm/subscribe.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/trigger.test.d.ts +0 -2
- package/dist/__tests__/useForm/trigger.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/unregister.test.d.ts +0 -2
- package/dist/__tests__/useForm/unregister.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts +0 -2
- package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/watch.test.d.ts +0 -2
- package/dist/__tests__/useForm/watch.test.d.ts.map +0 -1
- package/dist/__tests__/useForm.server.test.d.ts +0 -2
- package/dist/__tests__/useForm.server.test.d.ts.map +0 -1
- package/dist/__tests__/useForm.test.d.ts +0 -2
- package/dist/__tests__/useForm.test.d.ts.map +0 -1
- package/dist/__tests__/useFormContext.server.test.d.ts +0 -2
- package/dist/__tests__/useFormContext.server.test.d.ts.map +0 -1
- package/dist/__tests__/useFormContext.test.d.ts +0 -2
- package/dist/__tests__/useFormContext.test.d.ts.map +0 -1
- package/dist/__tests__/useFormState.test.d.ts +0 -2
- package/dist/__tests__/useFormState.test.d.ts.map +0 -1
- package/dist/__tests__/useWatch.test.d.ts +0 -2
- package/dist/__tests__/useWatch.test.d.ts.map +0 -1
- package/dist/__tests__/utils/append.test.d.ts +0 -2
- package/dist/__tests__/utils/append.test.d.ts.map +0 -1
- package/dist/__tests__/utils/cloneObject.test.d.ts +0 -2
- package/dist/__tests__/utils/cloneObject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/compact.test.d.ts +0 -2
- package/dist/__tests__/utils/compact.test.d.ts.map +0 -1
- package/dist/__tests__/utils/convertToArrayPayload.test.d.ts +0 -2
- package/dist/__tests__/utils/convertToArrayPayload.test.d.ts.map +0 -1
- package/dist/__tests__/utils/createSubject.test.d.ts +0 -2
- package/dist/__tests__/utils/createSubject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/deepEqual.test.d.ts +0 -2
- package/dist/__tests__/utils/deepEqual.test.d.ts.map +0 -1
- package/dist/__tests__/utils/deepMerge.test.d.ts +0 -2
- package/dist/__tests__/utils/deepMerge.test.d.ts.map +0 -1
- package/dist/__tests__/utils/extractFormValues.test.d.ts +0 -2
- package/dist/__tests__/utils/extractFormValues.test.d.ts.map +0 -1
- package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -2
- package/dist/__tests__/utils/fillEmptyArray.test.d.ts.map +0 -1
- package/dist/__tests__/utils/flatten.test.d.ts +0 -2
- package/dist/__tests__/utils/flatten.test.d.ts.map +0 -1
- package/dist/__tests__/utils/get.test.d.ts +0 -2
- package/dist/__tests__/utils/get.test.d.ts.map +0 -1
- package/dist/__tests__/utils/insert.test.d.ts +0 -2
- package/dist/__tests__/utils/insert.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isBoolean.test.d.ts +0 -2
- package/dist/__tests__/utils/isBoolean.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -2
- package/dist/__tests__/utils/isCheckBoxInput.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -2
- package/dist/__tests__/utils/isEmptyObject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isFileInput.test.d.ts +0 -2
- package/dist/__tests__/utils/isFileInput.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isFunction.test.d.ts +0 -2
- package/dist/__tests__/utils/isFunction.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -2
- package/dist/__tests__/utils/isHTMLElement.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isKey.test.d.ts +0 -2
- package/dist/__tests__/utils/isKey.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -2
- package/dist/__tests__/utils/isMultipleSelect.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -2
- package/dist/__tests__/utils/isNullOrUndefined.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isObject.test.d.ts +0 -2
- package/dist/__tests__/utils/isObject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -2
- package/dist/__tests__/utils/isPrimitive.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -2
- package/dist/__tests__/utils/isRadioInput.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -2
- package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isRegex.test.d.ts +0 -2
- package/dist/__tests__/utils/isRegex.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isString.test.d.ts +0 -2
- package/dist/__tests__/utils/isString.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isUndefined.test.d.ts +0 -2
- package/dist/__tests__/utils/isUndefined.test.d.ts.map +0 -1
- package/dist/__tests__/utils/live.test.d.ts +0 -2
- package/dist/__tests__/utils/live.test.d.ts.map +0 -1
- package/dist/__tests__/utils/move.test.d.ts +0 -2
- package/dist/__tests__/utils/move.test.d.ts.map +0 -1
- package/dist/__tests__/utils/noop.test.d.ts +0 -2
- package/dist/__tests__/utils/noop.test.d.ts.map +0 -1
- package/dist/__tests__/utils/objectHasFunction.test.d.ts +0 -2
- package/dist/__tests__/utils/objectHasFunction.test.d.ts.map +0 -1
- package/dist/__tests__/utils/prepend.test.d.ts +0 -2
- package/dist/__tests__/utils/prepend.test.d.ts.map +0 -1
- package/dist/__tests__/utils/remove.test.d.ts +0 -2
- package/dist/__tests__/utils/remove.test.d.ts.map +0 -1
- package/dist/__tests__/utils/set.test.d.ts +0 -2
- package/dist/__tests__/utils/set.test.d.ts.map +0 -1
- package/dist/__tests__/utils/stringToPath.test.d.ts +0 -2
- package/dist/__tests__/utils/stringToPath.test.d.ts.map +0 -1
- package/dist/__tests__/utils/swap.test.d.ts +0 -2
- package/dist/__tests__/utils/swap.test.d.ts.map +0 -1
- package/dist/__tests__/utils/unset.test.d.ts +0 -2
- package/dist/__tests__/utils/unset.test.d.ts.map +0 -1
- package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -2
- package/dist/__tests__/utils/validationModeChecker.test.d.ts.map +0 -1
- package/dist/__tests__/watch.server.test.d.ts +0 -2
- package/dist/__tests__/watch.server.test.d.ts.map +0 -1
- package/dist/__tests__/watch.test.d.ts +0 -2
- package/dist/__tests__/watch.test.d.ts.map +0 -1
- package/dist/logic/isNameInFieldArray.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
|
@@ -18,9 +18,15 @@ var getEventValue = (event) => isObject(event) && event.target
|
|
|
18
18
|
: event.target.value
|
|
19
19
|
: event;
|
|
20
20
|
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
var getFieldArrayParentNames = (names, name) => {
|
|
22
|
+
const parts = name.split('.');
|
|
23
|
+
const matches = [];
|
|
24
|
+
let prefix = parts[0];
|
|
25
|
+
for (let i = 1; i < parts.length; prefix += '.' + parts[i++]) {
|
|
26
|
+
!isNaN(+parts[i]) && names.has(prefix) && matches.push(prefix);
|
|
27
|
+
}
|
|
28
|
+
return matches;
|
|
29
|
+
};
|
|
24
30
|
|
|
25
31
|
var isPlainObject = (tempObject) => {
|
|
26
32
|
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
@@ -64,7 +70,10 @@ var get = (object, path, defaultValue) => {
|
|
|
64
70
|
if (!path || !isObject(object)) {
|
|
65
71
|
return defaultValue;
|
|
66
72
|
}
|
|
67
|
-
const
|
|
73
|
+
const paths = isKey(path) ? [path] : stringToPath(path);
|
|
74
|
+
const result = paths.reduce((result, key) => {
|
|
75
|
+
return isNullOrUndefined(result) ? undefined : result[key];
|
|
76
|
+
}, object);
|
|
68
77
|
return isUndefined(result) || result === object
|
|
69
78
|
? isUndefined(object[path])
|
|
70
79
|
? defaultValue
|
|
@@ -103,6 +112,9 @@ const EVENTS = {
|
|
|
103
112
|
BLUR: 'blur',
|
|
104
113
|
FOCUS_OUT: 'focusout',
|
|
105
114
|
CHANGE: 'change',
|
|
115
|
+
SUBMIT: 'submit',
|
|
116
|
+
TRIGGER: 'trigger',
|
|
117
|
+
VALID: 'valid',
|
|
106
118
|
};
|
|
107
119
|
const VALIDATION_MODE = {
|
|
108
120
|
onBlur: 'onBlur',
|
|
@@ -120,6 +132,8 @@ const INPUT_VALIDATION_RULES = {
|
|
|
120
132
|
required: 'required',
|
|
121
133
|
validate: 'validate',
|
|
122
134
|
};
|
|
135
|
+
const FORM_ERROR_TYPE = 'form';
|
|
136
|
+
const ROOT_ERROR_TYPE = 'root';
|
|
123
137
|
|
|
124
138
|
/**
|
|
125
139
|
* Separate context for `control` to prevent unnecessary rerenders.
|
|
@@ -133,10 +147,7 @@ HookFormControlContext.displayName = 'HookFormControlContext';
|
|
|
133
147
|
const useFormControlContext = () => React.useContext(HookFormControlContext);
|
|
134
148
|
|
|
135
149
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
136
|
-
const result = {
|
|
137
|
-
...formState,
|
|
138
|
-
defaultValues: control._defaultValues,
|
|
139
|
-
};
|
|
150
|
+
const result = {};
|
|
140
151
|
for (const key in formState) {
|
|
141
152
|
Object.defineProperty(result, key, {
|
|
142
153
|
get: () => {
|
|
@@ -187,7 +198,10 @@ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayou
|
|
|
187
198
|
function useFormState(props) {
|
|
188
199
|
const formControl = useFormControlContext();
|
|
189
200
|
const { control = formControl, disabled, name, exact } = props || {};
|
|
190
|
-
const [formState, updateFormState] = React.useState(
|
|
201
|
+
const [formState, updateFormState] = React.useState(() => ({
|
|
202
|
+
...control._formState,
|
|
203
|
+
defaultValues: control._defaultValues,
|
|
204
|
+
}));
|
|
191
205
|
const _localProxyFormState = React.useRef({
|
|
192
206
|
isDirty: false,
|
|
193
207
|
isLoading: false,
|
|
@@ -207,6 +221,7 @@ function useFormState(props) {
|
|
|
207
221
|
updateFormState({
|
|
208
222
|
...control._formState,
|
|
209
223
|
...formState,
|
|
224
|
+
defaultValues: control._defaultValues,
|
|
210
225
|
});
|
|
211
226
|
},
|
|
212
227
|
}), [name, disabled, exact]);
|
|
@@ -233,7 +248,10 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
|
233
248
|
|
|
234
249
|
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
235
250
|
|
|
236
|
-
function deepEqual(object1, object2,
|
|
251
|
+
function deepEqual(object1, object2, visited = new WeakSet()) {
|
|
252
|
+
if (object1 === object2) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
237
255
|
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
238
256
|
return Object.is(object1, object2);
|
|
239
257
|
}
|
|
@@ -245,22 +263,22 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
|
245
263
|
if (keys1.length !== keys2.length) {
|
|
246
264
|
return false;
|
|
247
265
|
}
|
|
248
|
-
if (
|
|
266
|
+
if (visited.has(object1) || visited.has(object2)) {
|
|
249
267
|
return true;
|
|
250
268
|
}
|
|
251
|
-
|
|
252
|
-
|
|
269
|
+
visited.add(object1);
|
|
270
|
+
visited.add(object2);
|
|
253
271
|
for (const key of keys1) {
|
|
254
272
|
const val1 = object1[key];
|
|
255
|
-
if (!
|
|
273
|
+
if (!(key in object2)) {
|
|
256
274
|
return false;
|
|
257
275
|
}
|
|
258
276
|
if (key !== 'ref') {
|
|
259
277
|
const val2 = object2[key];
|
|
260
278
|
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
261
|
-
(isObject(val1)
|
|
262
|
-
|
|
263
|
-
? !deepEqual(val1, val2,
|
|
279
|
+
((isObject(val1) || Array.isArray(val1)) &&
|
|
280
|
+
(isObject(val2) || Array.isArray(val2)))
|
|
281
|
+
? !deepEqual(val1, val2, visited)
|
|
264
282
|
: !Object.is(val1, val2)) {
|
|
265
283
|
return false;
|
|
266
284
|
}
|
|
@@ -382,7 +400,8 @@ function useWatch(props) {
|
|
|
382
400
|
function useController(props) {
|
|
383
401
|
const formControl = useFormControlContext();
|
|
384
402
|
const { name, disabled, control = formControl, shouldUnregister, defaultValue, exact = true, } = props;
|
|
385
|
-
const isArrayField =
|
|
403
|
+
const isArrayField = !!getFieldArrayParentNames(control._names.array, name)
|
|
404
|
+
.length;
|
|
386
405
|
const defaultValueMemo = React.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
|
387
406
|
const value = useWatch({
|
|
388
407
|
control,
|
|
@@ -396,7 +415,6 @@ function useController(props) {
|
|
|
396
415
|
exact,
|
|
397
416
|
});
|
|
398
417
|
const _props = React.useRef(props);
|
|
399
|
-
const _previousNameRef = React.useRef(undefined);
|
|
400
418
|
const _registerProps = React.useRef(control.register(name, {
|
|
401
419
|
...props.rules,
|
|
402
420
|
value,
|
|
@@ -457,10 +475,6 @@ function useController(props) {
|
|
|
457
475
|
}), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
|
|
458
476
|
React.useEffect(() => {
|
|
459
477
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
|
460
|
-
const previousName = _previousNameRef.current;
|
|
461
|
-
if (previousName && previousName !== name && !isArrayField) {
|
|
462
|
-
control.unregister(previousName);
|
|
463
|
-
}
|
|
464
478
|
control.register(name, {
|
|
465
479
|
..._props.current.rules,
|
|
466
480
|
...(isBoolean(_props.current.disabled)
|
|
@@ -475,14 +489,13 @@ function useController(props) {
|
|
|
475
489
|
};
|
|
476
490
|
updateMounted(name, true);
|
|
477
491
|
if (_shouldUnregisterField) {
|
|
478
|
-
const value = cloneObject(get(control._options.defaultValues, name, _props.current.defaultValue));
|
|
492
|
+
const value = cloneObject(get(control._defaultValues, name, get(control._options.defaultValues, name, _props.current.defaultValue)));
|
|
479
493
|
set(control._defaultValues, name, value);
|
|
480
494
|
if (isUndefined(get(control._formValues, name))) {
|
|
481
495
|
set(control._formValues, name, value);
|
|
482
496
|
}
|
|
483
497
|
}
|
|
484
498
|
!isArrayField && control.register(name);
|
|
485
|
-
_previousNameRef.current = name;
|
|
486
499
|
return () => {
|
|
487
500
|
(isArrayField
|
|
488
501
|
? _shouldUnregisterField && !control._state.action
|
|
@@ -628,43 +641,46 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
|
628
641
|
* ```
|
|
629
642
|
*/
|
|
630
643
|
const FormProvider = (props) => {
|
|
631
|
-
const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
644
|
+
const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
|
|
645
|
+
const memoizedValue = React.useMemo(() => ({
|
|
646
|
+
watch,
|
|
647
|
+
getValues,
|
|
648
|
+
getFieldState,
|
|
649
|
+
setError,
|
|
650
|
+
clearErrors,
|
|
651
|
+
setValue,
|
|
652
|
+
setValues,
|
|
653
|
+
trigger,
|
|
654
|
+
formState,
|
|
655
|
+
resetField,
|
|
656
|
+
reset,
|
|
657
|
+
handleSubmit,
|
|
658
|
+
unregister,
|
|
659
|
+
control,
|
|
660
|
+
register,
|
|
661
|
+
setFocus,
|
|
662
|
+
subscribe,
|
|
663
|
+
}), [
|
|
664
|
+
clearErrors,
|
|
665
|
+
control,
|
|
666
|
+
formState,
|
|
667
|
+
getFieldState,
|
|
668
|
+
getValues,
|
|
669
|
+
handleSubmit,
|
|
670
|
+
register,
|
|
671
|
+
reset,
|
|
672
|
+
resetField,
|
|
673
|
+
setError,
|
|
674
|
+
setFocus,
|
|
675
|
+
setValue,
|
|
676
|
+
setValues,
|
|
677
|
+
subscribe,
|
|
678
|
+
trigger,
|
|
679
|
+
unregister,
|
|
680
|
+
watch,
|
|
681
|
+
]);
|
|
682
|
+
return (React.createElement(HookFormContext.Provider, { value: memoizedValue },
|
|
683
|
+
React.createElement(HookFormControlContext.Provider, { value: memoizedValue.control }, children)));
|
|
668
684
|
};
|
|
669
685
|
|
|
670
686
|
const POST_REQUEST = 'post';
|
|
@@ -694,7 +710,7 @@ function Form(props) {
|
|
|
694
710
|
const methods = useFormContext();
|
|
695
711
|
const [mounted, setMounted] = React.useState(false);
|
|
696
712
|
const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, ...rest } = props;
|
|
697
|
-
const submit = async (event) => {
|
|
713
|
+
const submit = React.useCallback(async (event) => {
|
|
698
714
|
let hasError = false;
|
|
699
715
|
let type = '';
|
|
700
716
|
await control.handleSubmit(async (data) => {
|
|
@@ -703,8 +719,8 @@ function Form(props) {
|
|
|
703
719
|
try {
|
|
704
720
|
formDataJson = JSON.stringify(data);
|
|
705
721
|
}
|
|
706
|
-
catch
|
|
707
|
-
const flattenFormValues = flatten(
|
|
722
|
+
catch { }
|
|
723
|
+
const flattenFormValues = flatten(data);
|
|
708
724
|
for (const key in flattenFormValues) {
|
|
709
725
|
formData.append(key, flattenFormValues[key]);
|
|
710
726
|
}
|
|
@@ -751,15 +767,25 @@ function Form(props) {
|
|
|
751
767
|
}
|
|
752
768
|
}
|
|
753
769
|
})(event);
|
|
754
|
-
if (hasError &&
|
|
755
|
-
|
|
770
|
+
if (hasError && control) {
|
|
771
|
+
control._subjects.state.next({
|
|
756
772
|
isSubmitSuccessful: false,
|
|
757
773
|
});
|
|
758
|
-
|
|
774
|
+
control.setError('root.server', {
|
|
759
775
|
type,
|
|
760
776
|
});
|
|
761
777
|
}
|
|
762
|
-
}
|
|
778
|
+
}, [
|
|
779
|
+
control,
|
|
780
|
+
onSubmit,
|
|
781
|
+
method,
|
|
782
|
+
action,
|
|
783
|
+
headers,
|
|
784
|
+
encType,
|
|
785
|
+
validateStatus,
|
|
786
|
+
onError,
|
|
787
|
+
onSuccess,
|
|
788
|
+
]);
|
|
763
789
|
React.useEffect(() => {
|
|
764
790
|
setMounted(true);
|
|
765
791
|
}, []);
|
|
@@ -857,7 +883,12 @@ function baseGet(object, updatePath) {
|
|
|
857
883
|
const length = updatePath.slice(0, -1).length;
|
|
858
884
|
let index = 0;
|
|
859
885
|
while (index < length) {
|
|
860
|
-
|
|
886
|
+
if (isNullOrUndefined(object)) {
|
|
887
|
+
object = undefined;
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
object = object[updatePath[index]];
|
|
891
|
+
index++;
|
|
861
892
|
}
|
|
862
893
|
return object;
|
|
863
894
|
}
|
|
@@ -870,6 +901,10 @@ function isEmptyArray(obj) {
|
|
|
870
901
|
return true;
|
|
871
902
|
}
|
|
872
903
|
function unset(object, path) {
|
|
904
|
+
if (isString(path) && Object.prototype.hasOwnProperty.call(object, path)) {
|
|
905
|
+
delete object[path];
|
|
906
|
+
return object;
|
|
907
|
+
}
|
|
873
908
|
const paths = Array.isArray(path)
|
|
874
909
|
? path
|
|
875
910
|
: isKey(path)
|
|
@@ -914,6 +949,29 @@ function markFieldsDirty(data, fields = {}) {
|
|
|
914
949
|
}
|
|
915
950
|
return fields;
|
|
916
951
|
}
|
|
952
|
+
function pruneDirtyFields(value) {
|
|
953
|
+
if (value === false) {
|
|
954
|
+
return undefined;
|
|
955
|
+
}
|
|
956
|
+
if (value === true) {
|
|
957
|
+
return true;
|
|
958
|
+
}
|
|
959
|
+
if (Array.isArray(value)) {
|
|
960
|
+
const result = value.map((value) => pruneDirtyFields(value));
|
|
961
|
+
return (result.some((value) => value !== undefined) ? result : undefined);
|
|
962
|
+
}
|
|
963
|
+
if (isObject(value)) {
|
|
964
|
+
const result = {};
|
|
965
|
+
for (const key in value) {
|
|
966
|
+
const pruned = pruneDirtyFields(value[key]);
|
|
967
|
+
if (!isUndefined(pruned)) {
|
|
968
|
+
result[key] = pruned;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return (Object.keys(result).length ? result : undefined);
|
|
972
|
+
}
|
|
973
|
+
return undefined;
|
|
974
|
+
}
|
|
917
975
|
function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
918
976
|
if (!dirtyFieldsFromValues) {
|
|
919
977
|
dirtyFieldsFromValues = markFieldsDirty(formValues);
|
|
@@ -933,7 +991,7 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
|
933
991
|
dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
|
|
934
992
|
}
|
|
935
993
|
}
|
|
936
|
-
return dirtyFieldsFromValues;
|
|
994
|
+
return pruneDirtyFields(dirtyFieldsFromValues) || {};
|
|
937
995
|
}
|
|
938
996
|
|
|
939
997
|
const defaultResult = {
|
|
@@ -1129,7 +1187,8 @@ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, is
|
|
|
1129
1187
|
updateFormState(formStateData);
|
|
1130
1188
|
const { name, ...formState } = formStateData;
|
|
1131
1189
|
return (isEmptyObject(formState) ||
|
|
1132
|
-
|
|
1190
|
+
(isRoot &&
|
|
1191
|
+
Object.keys(formState).length >= Object.keys(_proxyFormState).length) ||
|
|
1133
1192
|
Object.keys(formState).find((key) => _proxyFormState[key] ===
|
|
1134
1193
|
(!isRoot || VALIDATION_MODE.all)));
|
|
1135
1194
|
};
|
|
@@ -1163,7 +1222,7 @@ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(re
|
|
|
1163
1222
|
|
|
1164
1223
|
var updateFieldArrayRootError = (errors, error, name) => {
|
|
1165
1224
|
const fieldArrayErrors = convertToArrayPayload(get(errors, name));
|
|
1166
|
-
set(fieldArrayErrors,
|
|
1225
|
+
set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
|
|
1167
1226
|
set(errors, name, fieldArrayErrors);
|
|
1168
1227
|
return errors;
|
|
1169
1228
|
};
|
|
@@ -1209,7 +1268,8 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
|
|
|
1209
1268
|
isUndefined(inputValue)) ||
|
|
1210
1269
|
(isHTMLElement(ref) && ref.value === '') ||
|
|
1211
1270
|
inputValue === '' ||
|
|
1212
|
-
(Array.isArray(inputValue) && !inputValue.length)
|
|
1271
|
+
(Array.isArray(inputValue) && !inputValue.length) ||
|
|
1272
|
+
(valueAsNumber && typeof inputValue === 'number' && isNaN(inputValue));
|
|
1213
1273
|
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
|
1214
1274
|
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
|
1215
1275
|
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
|
@@ -1371,24 +1431,27 @@ const defaultOptions = {
|
|
|
1371
1431
|
reValidateMode: VALIDATION_MODE.onChange,
|
|
1372
1432
|
shouldFocusError: true,
|
|
1373
1433
|
};
|
|
1434
|
+
const DEFAULT_FORM_STATE = {
|
|
1435
|
+
submitCount: 0,
|
|
1436
|
+
isDirty: false,
|
|
1437
|
+
isReady: false,
|
|
1438
|
+
isValidating: false,
|
|
1439
|
+
isSubmitted: false,
|
|
1440
|
+
isSubmitting: false,
|
|
1441
|
+
isSubmitSuccessful: false,
|
|
1442
|
+
isValid: false,
|
|
1443
|
+
touchedFields: {},
|
|
1444
|
+
dirtyFields: {},
|
|
1445
|
+
validatingFields: {},
|
|
1446
|
+
};
|
|
1374
1447
|
function createFormControl(props = {}) {
|
|
1375
1448
|
let _options = {
|
|
1376
1449
|
...defaultOptions,
|
|
1377
1450
|
...props,
|
|
1378
1451
|
};
|
|
1379
1452
|
let _formState = {
|
|
1380
|
-
|
|
1381
|
-
isDirty: false,
|
|
1382
|
-
isReady: false,
|
|
1453
|
+
...cloneObject(DEFAULT_FORM_STATE),
|
|
1383
1454
|
isLoading: isFunction(_options.defaultValues),
|
|
1384
|
-
isValidating: false,
|
|
1385
|
-
isSubmitted: false,
|
|
1386
|
-
isSubmitting: false,
|
|
1387
|
-
isSubmitSuccessful: false,
|
|
1388
|
-
isValid: false,
|
|
1389
|
-
touchedFields: {},
|
|
1390
|
-
dirtyFields: {},
|
|
1391
|
-
validatingFields: {},
|
|
1392
1455
|
errors: _options.errors || {},
|
|
1393
1456
|
disabled: _options.disabled || false,
|
|
1394
1457
|
};
|
|
@@ -1411,6 +1474,7 @@ function createFormControl(props = {}) {
|
|
|
1411
1474
|
unMount: new Set(),
|
|
1412
1475
|
array: new Set(),
|
|
1413
1476
|
watch: new Set(),
|
|
1477
|
+
registerName: new Set(),
|
|
1414
1478
|
};
|
|
1415
1479
|
let delayErrorCallback;
|
|
1416
1480
|
let timer = 0;
|
|
@@ -1452,7 +1516,11 @@ function createFormControl(props = {}) {
|
|
|
1452
1516
|
_updateIsValidating();
|
|
1453
1517
|
}
|
|
1454
1518
|
else {
|
|
1455
|
-
isValid = await executeBuiltInValidation(
|
|
1519
|
+
isValid = await executeBuiltInValidation({
|
|
1520
|
+
fields: _fields,
|
|
1521
|
+
onlyCheckValid: true,
|
|
1522
|
+
eventType: EVENTS.VALID,
|
|
1523
|
+
});
|
|
1456
1524
|
}
|
|
1457
1525
|
if (isValid !== _formState.isValid) {
|
|
1458
1526
|
_subjects.state.next({
|
|
@@ -1480,6 +1548,9 @@ function createFormControl(props = {}) {
|
|
|
1480
1548
|
});
|
|
1481
1549
|
}
|
|
1482
1550
|
};
|
|
1551
|
+
const _updateDirtyFields = () => {
|
|
1552
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
1553
|
+
};
|
|
1483
1554
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
1484
1555
|
if (args && method && !_options.disabled) {
|
|
1485
1556
|
_state.action = true;
|
|
@@ -1501,7 +1572,7 @@ function createFormControl(props = {}) {
|
|
|
1501
1572
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
|
1502
1573
|
}
|
|
1503
1574
|
if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
|
|
1504
|
-
|
|
1575
|
+
_updateDirtyFields();
|
|
1505
1576
|
}
|
|
1506
1577
|
_subjects.state.next({
|
|
1507
1578
|
name,
|
|
@@ -1528,16 +1599,53 @@ function createFormControl(props = {}) {
|
|
|
1528
1599
|
isValid: false,
|
|
1529
1600
|
});
|
|
1530
1601
|
};
|
|
1602
|
+
const hasExplicitNullIntermediate = (name) => {
|
|
1603
|
+
const segments = isKey(name) ? [name] : stringToPath(name);
|
|
1604
|
+
let formValues = _formValues;
|
|
1605
|
+
let defaultValues = _defaultValues;
|
|
1606
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1607
|
+
const key = segments[i];
|
|
1608
|
+
formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
|
|
1609
|
+
defaultValues = isNullOrUndefined(defaultValues)
|
|
1610
|
+
? defaultValues
|
|
1611
|
+
: defaultValues[key];
|
|
1612
|
+
if (formValues === null && defaultValues !== null) {
|
|
1613
|
+
return true;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
return false;
|
|
1617
|
+
};
|
|
1531
1618
|
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
|
1532
1619
|
const field = get(_fields, name);
|
|
1533
1620
|
if (field) {
|
|
1621
|
+
if (hasExplicitNullIntermediate(name)) {
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
const wasUnsetInFormValues = isUndefined(get(_formValues, name));
|
|
1534
1625
|
const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
|
|
1535
1626
|
isUndefined(defaultValue) ||
|
|
1536
1627
|
(ref && ref.defaultChecked) ||
|
|
1537
1628
|
shouldSkipSetValueAs
|
|
1538
1629
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
|
1539
1630
|
: setFieldValue(name, defaultValue);
|
|
1540
|
-
_state.mount && !_state.action
|
|
1631
|
+
if (_state.mount && !_state.action) {
|
|
1632
|
+
_setValid();
|
|
1633
|
+
// Re-registering a field after a prior unregister puts its key back
|
|
1634
|
+
// into _formValues, which can flip isDirty back to false (#13397).
|
|
1635
|
+
// Only run when we are currently dirty, otherwise an initial register
|
|
1636
|
+
// for a field with no defaultValue would flip isDirty to true. Reset
|
|
1637
|
+
// paths repopulate _formValues before re-register, so the key is
|
|
1638
|
+
// present then and this branch is skipped (preserves keepDirty).
|
|
1639
|
+
if (wasUnsetInFormValues &&
|
|
1640
|
+
_formState.isDirty &&
|
|
1641
|
+
(_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
|
|
1642
|
+
const isDirty = _getDirty();
|
|
1643
|
+
if (!isDirty) {
|
|
1644
|
+
_formState.isDirty = false;
|
|
1645
|
+
_subjects.state.next({ ..._formState });
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1541
1649
|
}
|
|
1542
1650
|
};
|
|
1543
1651
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
|
@@ -1555,9 +1663,14 @@ function createFormControl(props = {}) {
|
|
|
1555
1663
|
}
|
|
1556
1664
|
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
1557
1665
|
isPreviousDirty = !!get(_formState.dirtyFields, name);
|
|
1558
|
-
isCurrentFieldPristine
|
|
1559
|
-
|
|
1560
|
-
|
|
1666
|
+
if (isCurrentFieldPristine !== _formState.isDirty) {
|
|
1667
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
1668
|
+
}
|
|
1669
|
+
else {
|
|
1670
|
+
isCurrentFieldPristine
|
|
1671
|
+
? unset(_formState.dirtyFields, name)
|
|
1672
|
+
: set(_formState.dirtyFields, name, true);
|
|
1673
|
+
}
|
|
1561
1674
|
output.dirtyFields = _formState.dirtyFields;
|
|
1562
1675
|
shouldUpdateField =
|
|
1563
1676
|
shouldUpdateField ||
|
|
@@ -1615,8 +1728,7 @@ function createFormControl(props = {}) {
|
|
|
1615
1728
|
};
|
|
1616
1729
|
const _runSchema = async (name) => {
|
|
1617
1730
|
_updateIsValidating(name, true);
|
|
1618
|
-
|
|
1619
|
-
return result;
|
|
1731
|
+
return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
|
|
1620
1732
|
};
|
|
1621
1733
|
const executeSchemaAndUpdateState = async (names) => {
|
|
1622
1734
|
const { errors } = await _runSchema(names);
|
|
@@ -1625,7 +1737,9 @@ function createFormControl(props = {}) {
|
|
|
1625
1737
|
for (const name of names) {
|
|
1626
1738
|
const error = get(errors, name);
|
|
1627
1739
|
error
|
|
1628
|
-
?
|
|
1740
|
+
? _names.array.has(name) && isObject(error)
|
|
1741
|
+
? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
|
|
1742
|
+
: set(_formState.errors, name, error)
|
|
1629
1743
|
: unset(_formState.errors, name);
|
|
1630
1744
|
}
|
|
1631
1745
|
}
|
|
@@ -1634,9 +1748,55 @@ function createFormControl(props = {}) {
|
|
|
1634
1748
|
}
|
|
1635
1749
|
return errors;
|
|
1636
1750
|
};
|
|
1637
|
-
const
|
|
1751
|
+
const validateForm = async ({ name, eventType, }) => {
|
|
1752
|
+
if (props.validate) {
|
|
1753
|
+
const result = await props.validate({
|
|
1754
|
+
formValues: _formValues,
|
|
1755
|
+
formState: _formState,
|
|
1756
|
+
name,
|
|
1757
|
+
eventType,
|
|
1758
|
+
});
|
|
1759
|
+
if (isObject(result)) {
|
|
1760
|
+
for (const key in result) {
|
|
1761
|
+
const error = result[key];
|
|
1762
|
+
if (error) {
|
|
1763
|
+
setError(`${FORM_ERROR_TYPE}.${key}`, {
|
|
1764
|
+
message: isString(error.message) ? error.message : '',
|
|
1765
|
+
type: error.type || INPUT_VALIDATION_RULES.validate,
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
else if (isString(result) || !result) {
|
|
1771
|
+
setError(FORM_ERROR_TYPE, {
|
|
1772
|
+
message: result || '',
|
|
1773
|
+
type: INPUT_VALIDATION_RULES.validate,
|
|
1774
|
+
});
|
|
1775
|
+
}
|
|
1776
|
+
else {
|
|
1777
|
+
clearErrors(FORM_ERROR_TYPE);
|
|
1778
|
+
}
|
|
1779
|
+
return result;
|
|
1780
|
+
}
|
|
1781
|
+
return true;
|
|
1782
|
+
};
|
|
1783
|
+
const executeBuiltInValidation = async ({ fields, onlyCheckValid, name, eventType, context = {
|
|
1638
1784
|
valid: true,
|
|
1639
|
-
|
|
1785
|
+
runRootValidation: false,
|
|
1786
|
+
}, }) => {
|
|
1787
|
+
if (props.validate) {
|
|
1788
|
+
context.runRootValidation = true;
|
|
1789
|
+
const result = await validateForm({
|
|
1790
|
+
name,
|
|
1791
|
+
eventType,
|
|
1792
|
+
});
|
|
1793
|
+
if (!result) {
|
|
1794
|
+
context.valid = false;
|
|
1795
|
+
if (onlyCheckValid) {
|
|
1796
|
+
return context.valid;
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1640
1800
|
for (const name in fields) {
|
|
1641
1801
|
const field = fields[name];
|
|
1642
1802
|
if (field) {
|
|
@@ -1644,28 +1804,41 @@ function createFormControl(props = {}) {
|
|
|
1644
1804
|
if (_f) {
|
|
1645
1805
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
|
1646
1806
|
const isPromiseFunction = field._f && hasPromiseValidation(field._f);
|
|
1647
|
-
|
|
1807
|
+
const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
|
|
1808
|
+
_proxyFormState.isValidating ||
|
|
1809
|
+
_proxySubscribeFormState.validatingFields ||
|
|
1810
|
+
_proxySubscribeFormState.isValidating;
|
|
1811
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1648
1812
|
_updateIsValidating([_f.name], true);
|
|
1649
1813
|
}
|
|
1650
|
-
const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !
|
|
1651
|
-
if (isPromiseFunction &&
|
|
1814
|
+
const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
|
|
1815
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1652
1816
|
_updateIsValidating([_f.name]);
|
|
1653
1817
|
}
|
|
1654
1818
|
if (fieldError[_f.name]) {
|
|
1655
1819
|
context.valid = false;
|
|
1656
|
-
if (
|
|
1820
|
+
if (onlyCheckValid) {
|
|
1657
1821
|
break;
|
|
1658
1822
|
}
|
|
1659
1823
|
}
|
|
1660
|
-
!
|
|
1824
|
+
!onlyCheckValid &&
|
|
1661
1825
|
(get(fieldError, _f.name)
|
|
1662
1826
|
? isFieldArrayRoot
|
|
1663
1827
|
? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
|
|
1664
1828
|
: set(_formState.errors, _f.name, fieldError[_f.name])
|
|
1665
1829
|
: unset(_formState.errors, _f.name));
|
|
1830
|
+
if (props.shouldUseNativeValidation && fieldError[_f.name]) {
|
|
1831
|
+
break;
|
|
1832
|
+
}
|
|
1666
1833
|
}
|
|
1667
1834
|
!isEmptyObject(fieldValue) &&
|
|
1668
|
-
(await executeBuiltInValidation(
|
|
1835
|
+
(await executeBuiltInValidation({
|
|
1836
|
+
context,
|
|
1837
|
+
onlyCheckValid,
|
|
1838
|
+
fields: fieldValue,
|
|
1839
|
+
name: name,
|
|
1840
|
+
eventType,
|
|
1841
|
+
}));
|
|
1669
1842
|
}
|
|
1670
1843
|
}
|
|
1671
1844
|
return context.valid;
|
|
@@ -1745,7 +1918,7 @@ function createFormControl(props = {}) {
|
|
|
1745
1918
|
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
|
|
1746
1919
|
options.shouldValidate && trigger(name);
|
|
1747
1920
|
};
|
|
1748
|
-
const
|
|
1921
|
+
const setFieldValues = (name, value, options) => {
|
|
1749
1922
|
for (const fieldKey in value) {
|
|
1750
1923
|
if (!value.hasOwnProperty(fieldKey)) {
|
|
1751
1924
|
return;
|
|
@@ -1757,7 +1930,7 @@ function createFormControl(props = {}) {
|
|
|
1757
1930
|
isObject(fieldValue) ||
|
|
1758
1931
|
(field && !field._f)) &&
|
|
1759
1932
|
!isDateObject(fieldValue)
|
|
1760
|
-
?
|
|
1933
|
+
? setFieldValues(fieldName, fieldValue, options)
|
|
1761
1934
|
: setFieldValue(fieldName, fieldValue, options);
|
|
1762
1935
|
}
|
|
1763
1936
|
};
|
|
@@ -1765,7 +1938,11 @@ function createFormControl(props = {}) {
|
|
|
1765
1938
|
const field = get(_fields, name);
|
|
1766
1939
|
const isFieldArray = _names.array.has(name);
|
|
1767
1940
|
const cloneValue = cloneObject(value);
|
|
1768
|
-
|
|
1941
|
+
const previousValue = get(_formValues, name);
|
|
1942
|
+
const isValueUnchanged = deepEqual(previousValue, cloneValue);
|
|
1943
|
+
if (!isValueUnchanged) {
|
|
1944
|
+
set(_formValues, name, cloneValue);
|
|
1945
|
+
}
|
|
1769
1946
|
if (isFieldArray) {
|
|
1770
1947
|
_subjects.array.next({
|
|
1771
1948
|
name,
|
|
@@ -1776,30 +1953,52 @@ function createFormControl(props = {}) {
|
|
|
1776
1953
|
_proxySubscribeFormState.isDirty ||
|
|
1777
1954
|
_proxySubscribeFormState.dirtyFields) &&
|
|
1778
1955
|
options.shouldDirty) {
|
|
1956
|
+
_updateDirtyFields();
|
|
1779
1957
|
_subjects.state.next({
|
|
1780
1958
|
name,
|
|
1781
|
-
dirtyFields:
|
|
1959
|
+
dirtyFields: _formState.dirtyFields,
|
|
1782
1960
|
isDirty: _getDirty(name, cloneValue),
|
|
1783
1961
|
});
|
|
1784
1962
|
}
|
|
1785
1963
|
}
|
|
1786
1964
|
else {
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1965
|
+
const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
|
|
1966
|
+
isEmptyObject(cloneValue);
|
|
1967
|
+
if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
|
|
1968
|
+
setFieldValue(name, cloneValue, options);
|
|
1969
|
+
}
|
|
1970
|
+
else {
|
|
1971
|
+
setFieldValues(name, cloneValue, options);
|
|
1972
|
+
}
|
|
1790
1973
|
}
|
|
1791
|
-
if (
|
|
1974
|
+
if (!isValueUnchanged) {
|
|
1975
|
+
const watched = isWatched(name, _names);
|
|
1976
|
+
const values = cloneObject(_formValues);
|
|
1977
|
+
if (!isFieldArray) {
|
|
1978
|
+
for (const arrayName of getFieldArrayParentNames(_names.array, name)) {
|
|
1979
|
+
_subjects.array.next({ name: arrayName, values });
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1792
1982
|
_subjects.state.next({
|
|
1793
|
-
..._formState,
|
|
1794
|
-
name,
|
|
1795
|
-
values
|
|
1983
|
+
...(watched && _formState),
|
|
1984
|
+
name: _state.mount || watched ? name : undefined,
|
|
1985
|
+
values,
|
|
1796
1986
|
});
|
|
1797
1987
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1988
|
+
};
|
|
1989
|
+
const setValues = (formValues) => {
|
|
1990
|
+
const updatedFormValues = isFunction(formValues)
|
|
1991
|
+
? formValues(_formValues)
|
|
1992
|
+
: formValues;
|
|
1993
|
+
if (!deepEqual(_formValues, updatedFormValues)) {
|
|
1994
|
+
_formValues = {
|
|
1995
|
+
..._formValues,
|
|
1996
|
+
...updatedFormValues,
|
|
1997
|
+
};
|
|
1998
|
+
for (const fieldName of _names.mount) {
|
|
1999
|
+
setValue(fieldName, get(updatedFormValues, fieldName));
|
|
2000
|
+
}
|
|
2001
|
+
_subjects.state.next({ ..._formState, values: _formValues });
|
|
1803
2002
|
}
|
|
1804
2003
|
};
|
|
1805
2004
|
const onChange = async (event) => {
|
|
@@ -1824,6 +2023,7 @@ function createFormControl(props = {}) {
|
|
|
1824
2023
|
: getEventValue(event);
|
|
1825
2024
|
const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
|
|
1826
2025
|
const shouldSkipValidation = (!hasValidation(field._f) &&
|
|
2026
|
+
!props.validate &&
|
|
1827
2027
|
!_options.resolver &&
|
|
1828
2028
|
!get(_formState.errors, name) &&
|
|
1829
2029
|
!field._f.deps) ||
|
|
@@ -1861,6 +2061,12 @@ function createFormControl(props = {}) {
|
|
|
1861
2061
|
return (shouldRender &&
|
|
1862
2062
|
_subjects.state.next({ name, ...(watched ? {} : fieldState) }));
|
|
1863
2063
|
}
|
|
2064
|
+
if (!_options.resolver && props.validate) {
|
|
2065
|
+
await validateForm({
|
|
2066
|
+
name: name,
|
|
2067
|
+
eventType: event.type,
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
1864
2070
|
!isBlurEvent && watched && _subjects.state.next({ ..._formState });
|
|
1865
2071
|
if (_options.resolver) {
|
|
1866
2072
|
const { errors } = await _runSchema([name]);
|
|
@@ -1885,7 +2091,12 @@ function createFormControl(props = {}) {
|
|
|
1885
2091
|
}
|
|
1886
2092
|
else if (_proxyFormState.isValid ||
|
|
1887
2093
|
_proxySubscribeFormState.isValid) {
|
|
1888
|
-
isValid = await executeBuiltInValidation(
|
|
2094
|
+
isValid = await executeBuiltInValidation({
|
|
2095
|
+
fields: _fields,
|
|
2096
|
+
onlyCheckValid: true,
|
|
2097
|
+
name: name,
|
|
2098
|
+
eventType: event.type,
|
|
2099
|
+
});
|
|
1889
2100
|
}
|
|
1890
2101
|
}
|
|
1891
2102
|
}
|
|
@@ -1918,12 +2129,19 @@ function createFormControl(props = {}) {
|
|
|
1918
2129
|
else if (name) {
|
|
1919
2130
|
validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
|
|
1920
2131
|
const field = get(_fields, fieldName);
|
|
1921
|
-
return await executeBuiltInValidation(
|
|
2132
|
+
return await executeBuiltInValidation({
|
|
2133
|
+
fields: field && field._f ? { [fieldName]: field } : field,
|
|
2134
|
+
eventType: EVENTS.TRIGGER,
|
|
2135
|
+
});
|
|
1922
2136
|
}))).every(Boolean);
|
|
1923
2137
|
!(!validationResult && !_formState.isValid) && _setValid();
|
|
1924
2138
|
}
|
|
1925
2139
|
else {
|
|
1926
|
-
validationResult = isValid = await executeBuiltInValidation(
|
|
2140
|
+
validationResult = isValid = await executeBuiltInValidation({
|
|
2141
|
+
fields: _fields,
|
|
2142
|
+
name,
|
|
2143
|
+
eventType: EVENTS.TRIGGER,
|
|
2144
|
+
});
|
|
1927
2145
|
}
|
|
1928
2146
|
_subjects.state.next({
|
|
1929
2147
|
...(!isString(name) ||
|
|
@@ -1960,11 +2178,24 @@ function createFormControl(props = {}) {
|
|
|
1960
2178
|
isTouched: !!get((formState || _formState).touchedFields, name),
|
|
1961
2179
|
});
|
|
1962
2180
|
const clearErrors = (name) => {
|
|
1963
|
-
name
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
2181
|
+
const names = name ? convertToArrayPayload(name) : undefined;
|
|
2182
|
+
names?.forEach((inputName) => unset(_formState.errors, inputName));
|
|
2183
|
+
if (names) {
|
|
2184
|
+
// Emit for each cleared field with the field name so that
|
|
2185
|
+
// shouldSubscribeByName can filter and avoid broad re-renders
|
|
2186
|
+
names.forEach((inputName) => {
|
|
2187
|
+
_subjects.state.next({
|
|
2188
|
+
name: inputName,
|
|
2189
|
+
errors: _formState.errors,
|
|
2190
|
+
});
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
2193
|
+
else {
|
|
2194
|
+
// Clear all errors - emit without name to notify all subscribers
|
|
2195
|
+
_subjects.state.next({
|
|
2196
|
+
errors: {},
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
1968
2199
|
};
|
|
1969
2200
|
const setError = (name, error, options) => {
|
|
1970
2201
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
|
@@ -1988,8 +2219,9 @@ function createFormControl(props = {}) {
|
|
|
1988
2219
|
next: (formState) => {
|
|
1989
2220
|
if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
|
|
1990
2221
|
shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
|
|
2222
|
+
const snapshot = { ..._formValues };
|
|
1991
2223
|
props.callback({
|
|
1992
|
-
values:
|
|
2224
|
+
values: snapshot,
|
|
1993
2225
|
..._formState,
|
|
1994
2226
|
...formState,
|
|
1995
2227
|
defaultValues: _defaultValues,
|
|
@@ -2051,6 +2283,7 @@ function createFormControl(props = {}) {
|
|
|
2051
2283
|
const register = (name, options = {}) => {
|
|
2052
2284
|
let field = get(_fields, name);
|
|
2053
2285
|
const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
|
|
2286
|
+
const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
|
|
2054
2287
|
set(_fields, name, {
|
|
2055
2288
|
...(field || {}),
|
|
2056
2289
|
_f: {
|
|
@@ -2061,7 +2294,7 @@ function createFormControl(props = {}) {
|
|
|
2061
2294
|
},
|
|
2062
2295
|
});
|
|
2063
2296
|
_names.mount.add(name);
|
|
2064
|
-
if (field) {
|
|
2297
|
+
if (field && !shouldRevalidateRemount) {
|
|
2065
2298
|
_setDisabledField({
|
|
2066
2299
|
disabled: isBoolean(options.disabled)
|
|
2067
2300
|
? options.disabled
|
|
@@ -2091,7 +2324,9 @@ function createFormControl(props = {}) {
|
|
|
2091
2324
|
onBlur: onChange,
|
|
2092
2325
|
ref: (ref) => {
|
|
2093
2326
|
if (ref) {
|
|
2327
|
+
_names.registerName.add(name);
|
|
2094
2328
|
register(name, options);
|
|
2329
|
+
_names.registerName.delete(name);
|
|
2095
2330
|
field = get(_fields, name);
|
|
2096
2331
|
const fieldRef = isUndefined(ref.value)
|
|
2097
2332
|
? ref.querySelectorAll
|
|
@@ -2128,13 +2363,15 @@ function createFormControl(props = {}) {
|
|
|
2128
2363
|
field._f.mount = false;
|
|
2129
2364
|
}
|
|
2130
2365
|
(_options.shouldUnregister || options.shouldUnregister) &&
|
|
2131
|
-
!(
|
|
2366
|
+
!(getFieldArrayParentNames(_names.array, name).length &&
|
|
2367
|
+
_state.action) &&
|
|
2132
2368
|
_names.unMount.add(name);
|
|
2133
2369
|
}
|
|
2134
2370
|
},
|
|
2135
2371
|
};
|
|
2136
2372
|
};
|
|
2137
2373
|
const _focusError = () => _options.shouldFocusError &&
|
|
2374
|
+
!_options.shouldUseNativeValidation &&
|
|
2138
2375
|
iterateFieldsByAction(_fields, _focusInput, _names.mount);
|
|
2139
2376
|
const _disableForm = (disabled) => {
|
|
2140
2377
|
if (isBoolean(disabled)) {
|
|
@@ -2170,14 +2407,17 @@ function createFormControl(props = {}) {
|
|
|
2170
2407
|
fieldValues = cloneObject(values);
|
|
2171
2408
|
}
|
|
2172
2409
|
else {
|
|
2173
|
-
await executeBuiltInValidation(
|
|
2410
|
+
await executeBuiltInValidation({
|
|
2411
|
+
fields: _fields,
|
|
2412
|
+
eventType: EVENTS.SUBMIT,
|
|
2413
|
+
});
|
|
2174
2414
|
}
|
|
2175
2415
|
if (_names.disabled.size) {
|
|
2176
2416
|
for (const name of _names.disabled) {
|
|
2177
2417
|
unset(fieldValues, name);
|
|
2178
2418
|
}
|
|
2179
2419
|
}
|
|
2180
|
-
unset(_formState.errors,
|
|
2420
|
+
unset(_formState.errors, ROOT_ERROR_TYPE);
|
|
2181
2421
|
if (isEmptyObject(_formState.errors)) {
|
|
2182
2422
|
_subjects.state.next({
|
|
2183
2423
|
errors: {},
|
|
@@ -2301,6 +2541,7 @@ function createFormControl(props = {}) {
|
|
|
2301
2541
|
mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
|
|
2302
2542
|
unMount: new Set(),
|
|
2303
2543
|
array: new Set(),
|
|
2544
|
+
registerName: new Set(),
|
|
2304
2545
|
disabled: new Set(),
|
|
2305
2546
|
watch: new Set(),
|
|
2306
2547
|
watchAll: false,
|
|
@@ -2454,6 +2695,7 @@ function createFormControl(props = {}) {
|
|
|
2454
2695
|
handleSubmit,
|
|
2455
2696
|
watch,
|
|
2456
2697
|
setValue,
|
|
2698
|
+
setValues,
|
|
2457
2699
|
getValues,
|
|
2458
2700
|
reset,
|
|
2459
2701
|
resetField,
|
|
@@ -2691,10 +2933,11 @@ function useFieldArray(props) {
|
|
|
2691
2933
|
control._subjects.state.next({
|
|
2692
2934
|
...control._formState,
|
|
2693
2935
|
});
|
|
2936
|
+
const validationModes = getValidationModes(control._options.mode);
|
|
2694
2937
|
if (_actioned.current &&
|
|
2695
|
-
(!
|
|
2696
|
-
|
|
2697
|
-
!
|
|
2938
|
+
(!validationModes.isOnSubmit || control._formState.isSubmitted) &&
|
|
2939
|
+
!getValidationModes(control._options.reValidateMode).isOnSubmit &&
|
|
2940
|
+
!validationModes.isOnBlur) {
|
|
2698
2941
|
if (control._options.resolver) {
|
|
2699
2942
|
control._runSchema([name]).then((result) => {
|
|
2700
2943
|
control._updateIsValidating([name]);
|
|
@@ -2749,15 +2992,22 @@ function useFieldArray(props) {
|
|
|
2749
2992
|
React.useEffect(() => {
|
|
2750
2993
|
!get(control._formValues, name) && control._setFieldArray(name);
|
|
2751
2994
|
return () => {
|
|
2995
|
+
const shouldKeepFieldArrayValues = !(control._options.shouldUnregister || shouldUnregister);
|
|
2752
2996
|
const updateMounted = (name, value) => {
|
|
2753
2997
|
const field = get(control._fields, name);
|
|
2754
2998
|
if (field && field._f) {
|
|
2755
2999
|
field._f.mount = value;
|
|
2756
3000
|
}
|
|
2757
3001
|
};
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
3002
|
+
if (_actioned.current && shouldKeepFieldArrayValues) {
|
|
3003
|
+
control._subjects.state.next({
|
|
3004
|
+
name,
|
|
3005
|
+
values: cloneObject(control._formValues),
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
3008
|
+
shouldKeepFieldArrayValues
|
|
3009
|
+
? updateMounted(name, false)
|
|
3010
|
+
: control.unregister(name);
|
|
2761
3011
|
};
|
|
2762
3012
|
}, [name, control, shouldUnregister]);
|
|
2763
3013
|
return {
|
|
@@ -2819,25 +3069,15 @@ function updateMethodsReference(_formControl) {
|
|
|
2819
3069
|
function useForm(props = {}) {
|
|
2820
3070
|
const _formControl = React.useRef(undefined);
|
|
2821
3071
|
const _values = React.useRef(undefined);
|
|
2822
|
-
const [formState, updateFormState] = React.useState({
|
|
2823
|
-
|
|
2824
|
-
isValidating: false,
|
|
3072
|
+
const [formState, updateFormState] = React.useState(() => ({
|
|
3073
|
+
...cloneObject(DEFAULT_FORM_STATE),
|
|
2825
3074
|
isLoading: isFunction(props.defaultValues),
|
|
2826
|
-
isSubmitted: false,
|
|
2827
|
-
isSubmitting: false,
|
|
2828
|
-
isSubmitSuccessful: false,
|
|
2829
|
-
isValid: false,
|
|
2830
|
-
submitCount: 0,
|
|
2831
|
-
dirtyFields: {},
|
|
2832
|
-
touchedFields: {},
|
|
2833
|
-
validatingFields: {},
|
|
2834
3075
|
errors: props.errors || {},
|
|
2835
3076
|
disabled: props.disabled || false,
|
|
2836
|
-
isReady: false,
|
|
2837
3077
|
defaultValues: isFunction(props.defaultValues)
|
|
2838
3078
|
? undefined
|
|
2839
3079
|
: props.defaultValues,
|
|
2840
|
-
});
|
|
3080
|
+
}));
|
|
2841
3081
|
if (!_formControl.current) {
|
|
2842
3082
|
if (props.formControl) {
|
|
2843
3083
|
_formControl.current = {
|
|
@@ -2861,7 +3101,10 @@ function useForm(props = {}) {
|
|
|
2861
3101
|
useIsomorphicLayoutEffect(() => {
|
|
2862
3102
|
const sub = control._subscribe({
|
|
2863
3103
|
formState: control._proxyFormState,
|
|
2864
|
-
callback: () => updateFormState({
|
|
3104
|
+
callback: () => updateFormState({
|
|
3105
|
+
...control._formState,
|
|
3106
|
+
defaultValues: control._defaultValues,
|
|
3107
|
+
}),
|
|
2865
3108
|
reRenderRoot: true,
|
|
2866
3109
|
});
|
|
2867
3110
|
updateFormState((data) => ({
|
|
@@ -2903,14 +3146,13 @@ function useForm(props = {}) {
|
|
|
2903
3146
|
}
|
|
2904
3147
|
}, [control, formState.isDirty]);
|
|
2905
3148
|
React.useEffect(() => {
|
|
2906
|
-
var _a;
|
|
2907
3149
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
|
2908
3150
|
updateMethodsReference(_formControl);
|
|
2909
3151
|
control._reset(props.values, {
|
|
2910
3152
|
keepFieldsRef: true,
|
|
2911
3153
|
...control._options.resetOptions,
|
|
2912
3154
|
});
|
|
2913
|
-
if (!
|
|
3155
|
+
if (!control._options.resetOptions?.keepIsValid) {
|
|
2914
3156
|
control._setValid();
|
|
2915
3157
|
}
|
|
2916
3158
|
_values.current = props.values;
|