@depup/react-hook-form 7.72.1-depup.0 → 7.84.0-depup.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/README.md +2 -2
- package/changes.json +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/fieldArray.d.ts +37 -0
- package/dist/fieldArray.d.ts.map +1 -0
- package/dist/form.d.ts +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/formStateSubscribe.d.ts +8 -3
- package/dist/formStateSubscribe.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.mjs +2537 -2059
- 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/collectDirtyFieldNames.d.ts +3 -0
- package/dist/logic/collectDirtyFieldNames.d.ts.map +1 -0
- package/dist/logic/createFormControl.d.ts +13 -0
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getDirtyFields.d.ts +3 -2
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/logic/getEventValue.d.ts.map +1 -1
- package/dist/logic/getFieldValue.d.ts.map +1 -1
- package/dist/logic/getNodeParentName.d.ts.map +1 -1
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/logic/getResolverOptions.d.ts +2 -2
- package/dist/logic/getValueAndMessage.d.ts +1 -4
- package/dist/logic/getValueAndMessage.d.ts.map +1 -1
- package/dist/logic/hasPromiseValidation.d.ts.map +1 -1
- package/dist/logic/hasValidation.d.ts +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/iterateFieldsByAction.d.ts.map +1 -1
- package/dist/logic/shouldRenderFormState.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/logic/validateField.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +517 -188
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/errors.d.ts +2 -2
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +25 -1
- package/dist/types/fieldArray.d.ts.map +1 -1
- package/dist/types/form.d.ts +85 -60
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/path/common.d.ts +6 -0
- package/dist/types/path/common.d.ts.map +1 -1
- package/dist/types/path/eager.d.ts +15 -11
- package/dist/types/path/eager.d.ts.map +1 -1
- package/dist/types/utils.d.ts +4 -4
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/types/validator.d.ts +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/types/watch.d.ts +1 -1
- package/dist/types/watch.d.ts.map +1 -1
- package/dist/useController.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 +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useFormState.d.ts +2 -2
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/useIsomorphicLayoutEffect.d.ts.map +1 -1
- package/dist/useWatch.d.ts +14 -14
- package/dist/utils/deepEqual.d.ts +1 -1
- package/dist/utils/deepEqual.d.ts.map +1 -1
- package/dist/utils/flatten.d.ts.map +1 -1
- package/dist/utils/formData.d.ts +3 -0
- package/dist/utils/formData.d.ts.map +1 -0
- 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/isKey.d.ts.map +1 -1
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/set.d.ts.map +1 -1
- package/dist/utils/stringToPath.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 +29 -28
- 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/dirtyFields.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/dirtyFields.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/update.test.d.ts +0 -2
- package/dist/__tests__/utils/update.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
|
@@ -31,8 +31,8 @@ const INPUT_VALIDATION_RULES = {
|
|
|
31
31
|
required: 'required',
|
|
32
32
|
validate: 'validate',
|
|
33
33
|
};
|
|
34
|
-
const FORM_ERROR_TYPE = 'form';
|
|
35
34
|
const ROOT_ERROR_TYPE = 'root';
|
|
35
|
+
const PROTOTYPE_KEYWORDS = ['__proto__', 'constructor', 'prototype'];
|
|
36
36
|
|
|
37
37
|
var isDateObject = (value) => value instanceof Date;
|
|
38
38
|
|
|
@@ -108,7 +108,11 @@ var createSubject = () => {
|
|
|
108
108
|
|
|
109
109
|
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
const isEmptyObjectWithCustomPrototype = (object, keys) => keys.length === 0 && !Array.isArray(object) && !isPlainObject(object);
|
|
112
|
+
function deepEqual(object1, object2, visited = new WeakMap()) {
|
|
113
|
+
if (object1 === object2) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
112
116
|
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
113
117
|
return Object.is(object1, object2);
|
|
114
118
|
}
|
|
@@ -120,14 +124,28 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
|
120
124
|
if (keys1.length !== keys2.length) {
|
|
121
125
|
return false;
|
|
122
126
|
}
|
|
123
|
-
if (
|
|
127
|
+
if (isEmptyObjectWithCustomPrototype(object1, keys1) ||
|
|
128
|
+
isEmptyObjectWithCustomPrototype(object2, keys2)) {
|
|
129
|
+
return Object.is(object1, object2);
|
|
130
|
+
}
|
|
131
|
+
if (!keys1.length && Array.isArray(object1) !== Array.isArray(object2)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
const visitedPairs = visited.get(object1);
|
|
135
|
+
if (visitedPairs && visitedPairs.has(object2)) {
|
|
124
136
|
return true;
|
|
125
137
|
}
|
|
126
|
-
|
|
127
|
-
|
|
138
|
+
if (visitedPairs) {
|
|
139
|
+
visitedPairs.add(object2);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const ws = new WeakSet();
|
|
143
|
+
ws.add(object2);
|
|
144
|
+
visited.set(object1, ws);
|
|
145
|
+
}
|
|
128
146
|
for (const key of keys1) {
|
|
129
147
|
const val1 = object1[key];
|
|
130
|
-
if (!
|
|
148
|
+
if (!(key in object2)) {
|
|
131
149
|
return false;
|
|
132
150
|
}
|
|
133
151
|
if (key !== 'ref') {
|
|
@@ -135,7 +153,7 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
|
135
153
|
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
136
154
|
((isObject(val1) || Array.isArray(val1)) &&
|
|
137
155
|
(isObject(val2) || Array.isArray(val2)))
|
|
138
|
-
? !deepEqual(val1, val2,
|
|
156
|
+
? !deepEqual(val1, val2, visited)
|
|
139
157
|
: !Object.is(val1, val2)) {
|
|
140
158
|
return false;
|
|
141
159
|
}
|
|
@@ -164,17 +182,43 @@ function extractFormValues(fieldsState, formValues) {
|
|
|
164
182
|
return values;
|
|
165
183
|
}
|
|
166
184
|
|
|
167
|
-
|
|
185
|
+
const flatten = (obj) => {
|
|
186
|
+
const output = {};
|
|
187
|
+
for (const key of Object.keys(obj)) {
|
|
188
|
+
if (isObjectType(obj[key]) &&
|
|
189
|
+
obj[key] !== null &&
|
|
190
|
+
!isDateObject(obj[key])) {
|
|
191
|
+
const nested = flatten(obj[key]);
|
|
192
|
+
for (const nestedKey of Object.keys(nested)) {
|
|
193
|
+
output[`${key}.${nestedKey}`] = nested[nestedKey];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
output[key] = obj[key];
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return output;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const IS_KEY_RE = /^\w*$/;
|
|
204
|
+
var isKey = (value) => IS_KEY_RE.test(value);
|
|
168
205
|
|
|
169
206
|
var isUndefined = (val) => val === undefined;
|
|
170
207
|
|
|
171
|
-
|
|
208
|
+
const FIELD_PATH_RE = /[.[\]'"]/;
|
|
209
|
+
var stringToPath = (input) => input.split(FIELD_PATH_RE).filter(Boolean);
|
|
172
210
|
|
|
173
211
|
var get = (object, path, defaultValue) => {
|
|
174
212
|
if (!path || !isObject(object)) {
|
|
175
213
|
return defaultValue;
|
|
176
214
|
}
|
|
177
|
-
const
|
|
215
|
+
const paths = isKey(path) ? [path] : stringToPath(path);
|
|
216
|
+
if (paths.some((key) => PROTOTYPE_KEYWORDS.includes(key))) {
|
|
217
|
+
return defaultValue;
|
|
218
|
+
}
|
|
219
|
+
const result = paths.reduce((result, key) => {
|
|
220
|
+
return isNullOrUndefined(result) ? undefined : result[key];
|
|
221
|
+
}, object);
|
|
178
222
|
return isUndefined(result) || result === object
|
|
179
223
|
? isUndefined(object[path])
|
|
180
224
|
? defaultValue
|
|
@@ -228,7 +272,7 @@ var set = (object, path, value) => {
|
|
|
228
272
|
? []
|
|
229
273
|
: {};
|
|
230
274
|
}
|
|
231
|
-
if (key
|
|
275
|
+
if (PROTOTYPE_KEYWORDS.includes(key)) {
|
|
232
276
|
return;
|
|
233
277
|
}
|
|
234
278
|
object[key] = newValue;
|
|
@@ -237,10 +281,15 @@ var set = (object, path, value) => {
|
|
|
237
281
|
};
|
|
238
282
|
|
|
239
283
|
function baseGet(object, updatePath) {
|
|
240
|
-
const length = updatePath.
|
|
284
|
+
const length = updatePath.length - 1;
|
|
241
285
|
let index = 0;
|
|
242
286
|
while (index < length) {
|
|
243
|
-
|
|
287
|
+
if (isNullOrUndefined(object)) {
|
|
288
|
+
object = undefined;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
object = object[updatePath[index]];
|
|
292
|
+
index++;
|
|
244
293
|
}
|
|
245
294
|
return object;
|
|
246
295
|
}
|
|
@@ -253,11 +302,18 @@ function isEmptyArray(obj) {
|
|
|
253
302
|
return true;
|
|
254
303
|
}
|
|
255
304
|
function unset(object, path) {
|
|
305
|
+
if (isString(path) && Object.prototype.hasOwnProperty.call(object, path)) {
|
|
306
|
+
delete object[path];
|
|
307
|
+
return object;
|
|
308
|
+
}
|
|
256
309
|
const paths = Array.isArray(path)
|
|
257
310
|
? path
|
|
258
311
|
: isKey(path)
|
|
259
312
|
? [path]
|
|
260
313
|
: stringToPath(path);
|
|
314
|
+
if (paths.some((segment) => PROTOTYPE_KEYWORDS.includes(String(segment)))) {
|
|
315
|
+
return object;
|
|
316
|
+
}
|
|
261
317
|
const childObject = paths.length === 1 ? object : baseGet(object, paths);
|
|
262
318
|
const index = paths.length - 1;
|
|
263
319
|
const key = paths[index];
|
|
@@ -272,6 +328,24 @@ function unset(object, path) {
|
|
|
272
328
|
return object;
|
|
273
329
|
}
|
|
274
330
|
|
|
331
|
+
function isDirtyContainer(value) {
|
|
332
|
+
return Array.isArray(value) || isObject(value);
|
|
333
|
+
}
|
|
334
|
+
function collectDirtyFieldNames(dirtyTree, cachedDirtyFields, prefix = '', names = []) {
|
|
335
|
+
for (const key in dirtyTree) {
|
|
336
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
337
|
+
const value = dirtyTree[key];
|
|
338
|
+
if (isDirtyContainer(value) &&
|
|
339
|
+
isDirtyContainer(get(cachedDirtyFields, path))) {
|
|
340
|
+
collectDirtyFieldNames(value, cachedDirtyFields, path, names);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
names.push(path);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return names;
|
|
347
|
+
}
|
|
348
|
+
|
|
275
349
|
var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
|
|
276
350
|
if (isString(names)) {
|
|
277
351
|
isGlobal && _names.watch.add(names);
|
|
@@ -297,12 +371,33 @@ var objectHasFunction = (data) => {
|
|
|
297
371
|
function isTraversable(value) {
|
|
298
372
|
return Array.isArray(value) || (isObject(value) && !objectHasFunction(value));
|
|
299
373
|
}
|
|
300
|
-
function
|
|
374
|
+
function isRegisteredLeaf(fieldRef) {
|
|
375
|
+
return !!(fieldRef && '_f' in fieldRef);
|
|
376
|
+
}
|
|
377
|
+
function isEmptyDirtyContainer(value) {
|
|
378
|
+
return Array.isArray(value)
|
|
379
|
+
? !value.some((item) => !isUndefined(item))
|
|
380
|
+
: !Object.keys(value).length;
|
|
381
|
+
}
|
|
382
|
+
function clearDirtyField(container, key) {
|
|
383
|
+
if (Array.isArray(container)) {
|
|
384
|
+
container[key] = undefined;
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
delete container[key];
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function markFieldsDirty(data, fields = {}, fieldRefs) {
|
|
301
391
|
for (const key in data) {
|
|
302
392
|
const value = data[key];
|
|
303
|
-
|
|
393
|
+
const fieldRef = fieldRefs && fieldRefs[key];
|
|
394
|
+
if (isTraversable(value) &&
|
|
395
|
+
(!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
|
|
304
396
|
fields[key] = Array.isArray(value) ? [] : {};
|
|
305
|
-
markFieldsDirty(value, fields[key]);
|
|
397
|
+
markFieldsDirty(value, fields[key], fieldRef);
|
|
398
|
+
if (isEmptyDirtyContainer(fields[key])) {
|
|
399
|
+
clearDirtyField(fields, key);
|
|
400
|
+
}
|
|
306
401
|
}
|
|
307
402
|
else if (!isUndefined(value)) {
|
|
308
403
|
fields[key] = true;
|
|
@@ -310,23 +405,30 @@ function markFieldsDirty(data, fields = {}) {
|
|
|
310
405
|
}
|
|
311
406
|
return fields;
|
|
312
407
|
}
|
|
313
|
-
function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
408
|
+
function getDirtyFields(data, formValues, dirtyFieldsFromValues, fieldRefs) {
|
|
314
409
|
if (!dirtyFieldsFromValues) {
|
|
315
|
-
dirtyFieldsFromValues = markFieldsDirty(formValues);
|
|
410
|
+
dirtyFieldsFromValues = markFieldsDirty(formValues, {}, fieldRefs);
|
|
316
411
|
}
|
|
317
412
|
for (const key in data) {
|
|
318
413
|
const value = data[key];
|
|
319
|
-
|
|
414
|
+
const fieldRef = fieldRefs && fieldRefs[key];
|
|
415
|
+
if (isTraversable(value) &&
|
|
416
|
+
(!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
|
|
320
417
|
if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
|
|
321
|
-
dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
|
|
418
|
+
dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {}, fieldRef);
|
|
322
419
|
}
|
|
323
420
|
else {
|
|
324
|
-
getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
|
421
|
+
getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key], fieldRef);
|
|
422
|
+
}
|
|
423
|
+
if (isEmptyDirtyContainer(dirtyFieldsFromValues[key])) {
|
|
424
|
+
clearDirtyField(dirtyFieldsFromValues, key);
|
|
325
425
|
}
|
|
326
426
|
}
|
|
427
|
+
else if (deepEqual(value, formValues[key])) {
|
|
428
|
+
clearDirtyField(dirtyFieldsFromValues, key);
|
|
429
|
+
}
|
|
327
430
|
else {
|
|
328
|
-
|
|
329
|
-
dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
|
|
431
|
+
dirtyFieldsFromValues[key] = true;
|
|
330
432
|
}
|
|
331
433
|
}
|
|
332
434
|
return dirtyFieldsFromValues;
|
|
@@ -335,7 +437,9 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
|
335
437
|
var getEventValue = (event) => isObject(event) && event.target
|
|
336
438
|
? isCheckBoxInput(event.target)
|
|
337
439
|
? event.target.checked
|
|
338
|
-
: event.target
|
|
440
|
+
: isFileInput(event.target)
|
|
441
|
+
? event.target.files
|
|
442
|
+
: event.target.value
|
|
339
443
|
: event;
|
|
340
444
|
|
|
341
445
|
const defaultResult = {
|
|
@@ -404,11 +508,9 @@ function getFieldValue(_f) {
|
|
|
404
508
|
if (isCheckBoxInput(ref)) {
|
|
405
509
|
return getCheckboxValue(_f.refs).value;
|
|
406
510
|
}
|
|
407
|
-
return getFieldValueAs(
|
|
511
|
+
return getFieldValueAs(ref.value, _f);
|
|
408
512
|
}
|
|
409
513
|
|
|
410
|
-
var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
|
|
411
|
-
|
|
412
514
|
var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
|
|
413
515
|
const fields = {};
|
|
414
516
|
for (const name of fieldsNames) {
|
|
@@ -444,12 +546,22 @@ var getValidationModes = (mode) => ({
|
|
|
444
546
|
});
|
|
445
547
|
|
|
446
548
|
const ASYNC_FUNCTION = 'AsyncFunction';
|
|
447
|
-
var hasPromiseValidation = (fieldReference) =>
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
549
|
+
var hasPromiseValidation = (fieldReference) => {
|
|
550
|
+
if (!fieldReference || !fieldReference.validate)
|
|
551
|
+
return false;
|
|
552
|
+
if (isFunction(fieldReference.validate)) {
|
|
553
|
+
return fieldReference.validate.constructor.name === ASYNC_FUNCTION;
|
|
554
|
+
}
|
|
555
|
+
if (isObject(fieldReference.validate)) {
|
|
556
|
+
for (const key in fieldReference.validate) {
|
|
557
|
+
if (fieldReference.validate[key].constructor
|
|
558
|
+
.name === ASYNC_FUNCTION) {
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return false;
|
|
564
|
+
};
|
|
453
565
|
|
|
454
566
|
var hasValidation = (options) => options.mount &&
|
|
455
567
|
(options.required ||
|
|
@@ -464,17 +576,26 @@ var isNameInFieldArray = (names, name) => name
|
|
|
464
576
|
.split('.')
|
|
465
577
|
.some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
|
|
466
578
|
|
|
467
|
-
var isWatched = (name, _names, isBlurEvent) =>
|
|
468
|
-
(
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
579
|
+
var isWatched = (name, _names, isBlurEvent) => {
|
|
580
|
+
if (isBlurEvent)
|
|
581
|
+
return false;
|
|
582
|
+
if (_names.watchAll || _names.watch.has(name))
|
|
583
|
+
return true;
|
|
584
|
+
for (const watchName of _names.watch) {
|
|
585
|
+
if (name.startsWith(watchName) && name.charAt(watchName.length) === '.')
|
|
586
|
+
return true;
|
|
587
|
+
}
|
|
588
|
+
return false;
|
|
589
|
+
};
|
|
472
590
|
|
|
473
591
|
const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
474
592
|
for (const key of fieldsNames || Object.keys(fields)) {
|
|
475
|
-
|
|
593
|
+
if (key === '_f') {
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
const field = fieldsNames ? get(fields, key) : fields[key];
|
|
476
597
|
if (field) {
|
|
477
|
-
const { _f
|
|
598
|
+
const { _f } = field;
|
|
478
599
|
if (_f) {
|
|
479
600
|
if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
|
|
480
601
|
return true;
|
|
@@ -483,13 +604,13 @@ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
|
483
604
|
return true;
|
|
484
605
|
}
|
|
485
606
|
else {
|
|
486
|
-
if (iterateFieldsByAction(
|
|
607
|
+
if (iterateFieldsByAction(field, action)) {
|
|
487
608
|
break;
|
|
488
609
|
}
|
|
489
610
|
}
|
|
490
611
|
}
|
|
491
|
-
else if (isObject(
|
|
492
|
-
if (iterateFieldsByAction(
|
|
612
|
+
else if (isObject(field) || Array.isArray(field)) {
|
|
613
|
+
if (iterateFieldsByAction(field, action)) {
|
|
493
614
|
break;
|
|
494
615
|
}
|
|
495
616
|
}
|
|
@@ -535,10 +656,10 @@ function schemaErrorLookup(errors, _fields, name) {
|
|
|
535
656
|
|
|
536
657
|
var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
|
|
537
658
|
updateFormState(formStateData);
|
|
538
|
-
const
|
|
539
|
-
return (
|
|
540
|
-
|
|
541
|
-
|
|
659
|
+
const keys = Object.keys(formStateData).filter((key) => key !== 'name');
|
|
660
|
+
return (!keys.length ||
|
|
661
|
+
(isRoot && keys.length >= Object.keys(_proxyFormState).length) ||
|
|
662
|
+
keys.find((key) => _proxyFormState[key] ===
|
|
542
663
|
(!isRoot || VALIDATION_MODE.all)));
|
|
543
664
|
};
|
|
544
665
|
|
|
@@ -547,7 +668,7 @@ var shouldSubscribeByName = (name, signalName, exact) => !name ||
|
|
|
547
668
|
name === signalName ||
|
|
548
669
|
convertToArrayPayload(name).some((currentName) => currentName &&
|
|
549
670
|
(exact
|
|
550
|
-
? currentName === signalName
|
|
671
|
+
? currentName === signalName || currentName.startsWith(signalName + '.')
|
|
551
672
|
: currentName.startsWith(signalName) ||
|
|
552
673
|
signalName.startsWith(currentName)));
|
|
553
674
|
|
|
@@ -570,7 +691,8 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
|
570
691
|
var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
|
|
571
692
|
|
|
572
693
|
var updateFieldArrayRootError = (errors, error, name) => {
|
|
573
|
-
const
|
|
694
|
+
const existingErrors = get(errors, name);
|
|
695
|
+
const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
|
|
574
696
|
set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
|
|
575
697
|
set(errors, name, fieldArrayErrors);
|
|
576
698
|
return errors;
|
|
@@ -604,7 +726,13 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
|
|
|
604
726
|
const inputRef = refs ? refs[0] : ref;
|
|
605
727
|
const setCustomValidity = (message) => {
|
|
606
728
|
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
|
607
|
-
|
|
729
|
+
const validityMessage = isBoolean(message) ? '' : message || '';
|
|
730
|
+
if (refs) {
|
|
731
|
+
refs.forEach((ref) => ref.setCustomValidity(validityMessage));
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
inputRef.setCustomValidity(validityMessage);
|
|
735
|
+
}
|
|
608
736
|
inputRef.reportValidity();
|
|
609
737
|
}
|
|
610
738
|
};
|
|
@@ -779,24 +907,36 @@ const defaultOptions = {
|
|
|
779
907
|
reValidateMode: VALIDATION_MODE.onChange,
|
|
780
908
|
shouldFocusError: true,
|
|
781
909
|
};
|
|
910
|
+
const FORM_ERROR_TYPE = 'form';
|
|
911
|
+
const updateDirtyFields = (dirtyFields, nextDirtyFields) => {
|
|
912
|
+
for (const key in dirtyFields) {
|
|
913
|
+
if (!(key in nextDirtyFields)) {
|
|
914
|
+
delete dirtyFields[key];
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
Object.assign(dirtyFields, nextDirtyFields);
|
|
918
|
+
};
|
|
919
|
+
const DEFAULT_FORM_STATE = {
|
|
920
|
+
submitCount: 0,
|
|
921
|
+
isDirty: false,
|
|
922
|
+
isReady: false,
|
|
923
|
+
isValidating: false,
|
|
924
|
+
isSubmitted: false,
|
|
925
|
+
isSubmitting: false,
|
|
926
|
+
isSubmitSuccessful: false,
|
|
927
|
+
isValid: false,
|
|
928
|
+
touchedFields: {},
|
|
929
|
+
dirtyFields: {},
|
|
930
|
+
validatingFields: {},
|
|
931
|
+
};
|
|
782
932
|
function createFormControl(props = {}) {
|
|
783
933
|
let _options = {
|
|
784
934
|
...defaultOptions,
|
|
785
935
|
...props,
|
|
786
936
|
};
|
|
787
937
|
let _formState = {
|
|
788
|
-
|
|
789
|
-
isDirty: false,
|
|
790
|
-
isReady: false,
|
|
938
|
+
...cloneObject(DEFAULT_FORM_STATE),
|
|
791
939
|
isLoading: isFunction(_options.defaultValues),
|
|
792
|
-
isValidating: false,
|
|
793
|
-
isSubmitted: false,
|
|
794
|
-
isSubmitting: false,
|
|
795
|
-
isSubmitSuccessful: false,
|
|
796
|
-
isValid: false,
|
|
797
|
-
touchedFields: {},
|
|
798
|
-
dirtyFields: {},
|
|
799
|
-
validatingFields: {},
|
|
800
940
|
errors: _options.errors || {},
|
|
801
941
|
disabled: _options.disabled || false,
|
|
802
942
|
};
|
|
@@ -821,8 +961,11 @@ function createFormControl(props = {}) {
|
|
|
821
961
|
watch: new Set(),
|
|
822
962
|
registerName: new Set(),
|
|
823
963
|
};
|
|
824
|
-
|
|
825
|
-
|
|
964
|
+
const delayErrorCallbacks = {};
|
|
965
|
+
const timers = {};
|
|
966
|
+
let _valuesSubscriberCount = 0;
|
|
967
|
+
let _validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
968
|
+
let _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
826
969
|
const defaultProxyFormState = {
|
|
827
970
|
isDirty: false,
|
|
828
971
|
dirtyFields: false,
|
|
@@ -842,10 +985,11 @@ function createFormControl(props = {}) {
|
|
|
842
985
|
array: createSubject(),
|
|
843
986
|
state: createSubject(),
|
|
844
987
|
};
|
|
988
|
+
let _setValidCallId = 0;
|
|
845
989
|
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
|
846
|
-
const debounce = (callback) => (wait) => {
|
|
847
|
-
clearTimeout(
|
|
848
|
-
|
|
990
|
+
const debounce = (name, callback) => (wait) => {
|
|
991
|
+
clearTimeout(timers[name]);
|
|
992
|
+
timers[name] = setTimeout(callback, wait);
|
|
849
993
|
};
|
|
850
994
|
const _setValid = async (shouldUpdateValid) => {
|
|
851
995
|
if (_state.keepIsValid) {
|
|
@@ -855,10 +999,11 @@ function createFormControl(props = {}) {
|
|
|
855
999
|
(_proxyFormState.isValid ||
|
|
856
1000
|
_proxySubscribeFormState.isValid ||
|
|
857
1001
|
shouldUpdateValid)) {
|
|
1002
|
+
const callId = ++_setValidCallId;
|
|
858
1003
|
let isValid;
|
|
859
1004
|
if (_options.resolver) {
|
|
860
1005
|
isValid = isEmptyObject((await _runSchema()).errors);
|
|
861
|
-
_updateIsValidating();
|
|
1006
|
+
callId === _setValidCallId && _updateIsValidating();
|
|
862
1007
|
}
|
|
863
1008
|
else {
|
|
864
1009
|
isValid = await executeBuiltInValidation({
|
|
@@ -867,7 +1012,7 @@ function createFormControl(props = {}) {
|
|
|
867
1012
|
eventType: EVENTS.VALID,
|
|
868
1013
|
});
|
|
869
1014
|
}
|
|
870
|
-
if (isValid !== _formState.isValid) {
|
|
1015
|
+
if (callId === _setValidCallId && isValid !== _formState.isValid) {
|
|
871
1016
|
_subjects.state.next({
|
|
872
1017
|
isValid,
|
|
873
1018
|
});
|
|
@@ -893,10 +1038,8 @@ function createFormControl(props = {}) {
|
|
|
893
1038
|
});
|
|
894
1039
|
}
|
|
895
1040
|
};
|
|
896
|
-
const _updateDirtyFields = (
|
|
897
|
-
|
|
898
|
-
const rootName = getNodeParentName(name);
|
|
899
|
-
set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
|
|
1041
|
+
const _updateDirtyFields = () => {
|
|
1042
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
900
1043
|
};
|
|
901
1044
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
902
1045
|
if (args && method && !_options.disabled) {
|
|
@@ -919,7 +1062,7 @@ function createFormControl(props = {}) {
|
|
|
919
1062
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
|
920
1063
|
}
|
|
921
1064
|
if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
|
|
922
|
-
_updateDirtyFields(
|
|
1065
|
+
_updateDirtyFields();
|
|
923
1066
|
}
|
|
924
1067
|
_subjects.state.next({
|
|
925
1068
|
name,
|
|
@@ -935,6 +1078,7 @@ function createFormControl(props = {}) {
|
|
|
935
1078
|
};
|
|
936
1079
|
const updateErrors = (name, error) => {
|
|
937
1080
|
set(_formState.errors, name, error);
|
|
1081
|
+
_formState.errors = { ..._formState.errors };
|
|
938
1082
|
_subjects.state.next({
|
|
939
1083
|
errors: _formState.errors,
|
|
940
1084
|
});
|
|
@@ -946,16 +1090,53 @@ function createFormControl(props = {}) {
|
|
|
946
1090
|
isValid: false,
|
|
947
1091
|
});
|
|
948
1092
|
};
|
|
1093
|
+
const hasExplicitNullIntermediate = (name) => {
|
|
1094
|
+
const segments = isKey(name) ? [name] : stringToPath(name);
|
|
1095
|
+
let formValues = _formValues;
|
|
1096
|
+
let defaultValues = _defaultValues;
|
|
1097
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1098
|
+
const key = segments[i];
|
|
1099
|
+
formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
|
|
1100
|
+
defaultValues = isNullOrUndefined(defaultValues)
|
|
1101
|
+
? defaultValues
|
|
1102
|
+
: defaultValues[key];
|
|
1103
|
+
if (formValues === null && defaultValues !== null) {
|
|
1104
|
+
return true;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return false;
|
|
1108
|
+
};
|
|
949
1109
|
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
|
950
1110
|
const field = get(_fields, name);
|
|
951
1111
|
if (field) {
|
|
1112
|
+
if (hasExplicitNullIntermediate(name)) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const wasUnsetInFormValues = isUndefined(get(_formValues, name));
|
|
952
1116
|
const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
|
|
953
1117
|
isUndefined(defaultValue) ||
|
|
954
1118
|
(ref && ref.defaultChecked) ||
|
|
955
1119
|
shouldSkipSetValueAs
|
|
956
1120
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
|
957
1121
|
: setFieldValue(name, defaultValue);
|
|
958
|
-
_state.mount && !_state.action
|
|
1122
|
+
if (_state.mount && !_state.action) {
|
|
1123
|
+
_setValid();
|
|
1124
|
+
if (wasUnsetInFormValues &&
|
|
1125
|
+
_formState.isDirty &&
|
|
1126
|
+
(_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
|
|
1127
|
+
const isDirty = _getDirty();
|
|
1128
|
+
if (!isDirty) {
|
|
1129
|
+
_formState.isDirty = false;
|
|
1130
|
+
_subjects.state.next({ ..._formState });
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (props.shouldUnregister &&
|
|
1134
|
+
wasUnsetInFormValues &&
|
|
1135
|
+
!isUndefined(get(_formValues, name)) &&
|
|
1136
|
+
isWatched(name, _names)) {
|
|
1137
|
+
_state.watch = true;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
959
1140
|
}
|
|
960
1141
|
};
|
|
961
1142
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
|
@@ -964,18 +1145,26 @@ function createFormControl(props = {}) {
|
|
|
964
1145
|
const output = {
|
|
965
1146
|
name,
|
|
966
1147
|
};
|
|
967
|
-
|
|
1148
|
+
// an explicit programmatic update (e.g. setValue with shouldDirty: true)
|
|
1149
|
+
// opts into dirty tracking even when the form is disabled
|
|
1150
|
+
if (!_options.disabled || shouldDirty === true) {
|
|
968
1151
|
if (!isBlurEvent || shouldDirty) {
|
|
1152
|
+
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
969
1153
|
if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
|
|
970
1154
|
isPreviousDirty = _formState.isDirty;
|
|
971
|
-
_formState.isDirty = output.isDirty =
|
|
1155
|
+
_formState.isDirty = output.isDirty =
|
|
1156
|
+
!isCurrentFieldPristine || _getDirty();
|
|
972
1157
|
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
|
973
1158
|
}
|
|
974
|
-
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
975
1159
|
isPreviousDirty = !!get(_formState.dirtyFields, name);
|
|
976
|
-
isCurrentFieldPristine
|
|
977
|
-
|
|
978
|
-
|
|
1160
|
+
if (isCurrentFieldPristine !== _formState.isDirty) {
|
|
1161
|
+
updateDirtyFields(_formState.dirtyFields, getDirtyFields(_defaultValues, _formValues, undefined, _fields));
|
|
1162
|
+
}
|
|
1163
|
+
else {
|
|
1164
|
+
isCurrentFieldPristine
|
|
1165
|
+
? unset(_formState.dirtyFields, name)
|
|
1166
|
+
: set(_formState.dirtyFields, name, true);
|
|
1167
|
+
}
|
|
979
1168
|
output.dirtyFields = _formState.dirtyFields;
|
|
980
1169
|
shouldUpdateField =
|
|
981
1170
|
shouldUpdateField ||
|
|
@@ -1005,15 +1194,16 @@ function createFormControl(props = {}) {
|
|
|
1005
1194
|
isBoolean(isValid) &&
|
|
1006
1195
|
_formState.isValid !== isValid;
|
|
1007
1196
|
if (_options.delayError && error) {
|
|
1008
|
-
|
|
1009
|
-
|
|
1197
|
+
delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
|
|
1198
|
+
delayErrorCallbacks[name](_options.delayError);
|
|
1010
1199
|
}
|
|
1011
1200
|
else {
|
|
1012
|
-
clearTimeout(
|
|
1013
|
-
|
|
1201
|
+
clearTimeout(timers[name]);
|
|
1202
|
+
delete delayErrorCallbacks[name];
|
|
1014
1203
|
error
|
|
1015
1204
|
? set(_formState.errors, name, error)
|
|
1016
1205
|
: unset(_formState.errors, name);
|
|
1206
|
+
_formState.errors = { ..._formState.errors };
|
|
1017
1207
|
}
|
|
1018
1208
|
if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
|
|
1019
1209
|
!isEmptyObject(fieldState) ||
|
|
@@ -1042,9 +1232,14 @@ function createFormControl(props = {}) {
|
|
|
1042
1232
|
for (const name of names) {
|
|
1043
1233
|
const error = get(errors, name);
|
|
1044
1234
|
error
|
|
1045
|
-
?
|
|
1235
|
+
? _names.array.has(name) &&
|
|
1236
|
+
isObject(error) &&
|
|
1237
|
+
!Object.keys(error).some((key) => !Number.isNaN(Number(key)))
|
|
1238
|
+
? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
|
|
1239
|
+
: set(_formState.errors, name, error)
|
|
1046
1240
|
: unset(_formState.errors, name);
|
|
1047
1241
|
}
|
|
1242
|
+
_formState.errors = { ..._formState.errors };
|
|
1048
1243
|
}
|
|
1049
1244
|
else {
|
|
1050
1245
|
_formState.errors = errors;
|
|
@@ -1064,8 +1259,8 @@ function createFormControl(props = {}) {
|
|
|
1064
1259
|
const error = result[key];
|
|
1065
1260
|
if (error) {
|
|
1066
1261
|
setError(`${FORM_ERROR_TYPE}.${key}`, {
|
|
1067
|
-
message: isString(
|
|
1068
|
-
type: INPUT_VALIDATION_RULES.validate,
|
|
1262
|
+
message: isString(error.message) ? error.message : '',
|
|
1263
|
+
type: error.type || INPUT_VALIDATION_RULES.validate,
|
|
1069
1264
|
});
|
|
1070
1265
|
}
|
|
1071
1266
|
}
|
|
@@ -1107,11 +1302,15 @@ function createFormControl(props = {}) {
|
|
|
1107
1302
|
if (_f) {
|
|
1108
1303
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
|
1109
1304
|
const isPromiseFunction = field._f && hasPromiseValidation(field._f);
|
|
1110
|
-
|
|
1305
|
+
const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
|
|
1306
|
+
_proxyFormState.isValidating ||
|
|
1307
|
+
_proxySubscribeFormState.validatingFields ||
|
|
1308
|
+
_proxySubscribeFormState.isValidating;
|
|
1309
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1111
1310
|
_updateIsValidating([_f.name], true);
|
|
1112
1311
|
}
|
|
1113
1312
|
const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
|
|
1114
|
-
if (isPromiseFunction &&
|
|
1313
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1115
1314
|
_updateIsValidating([_f.name]);
|
|
1116
1315
|
}
|
|
1117
1316
|
if (fieldError[_f.name]) {
|
|
@@ -1153,9 +1352,8 @@ function createFormControl(props = {}) {
|
|
|
1153
1352
|
}
|
|
1154
1353
|
_names.unMount = new Set();
|
|
1155
1354
|
};
|
|
1156
|
-
const _getDirty = (name, data) =>
|
|
1157
|
-
(
|
|
1158
|
-
!deepEqual(getValues(), _defaultValues));
|
|
1355
|
+
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
|
1356
|
+
!deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
|
|
1159
1357
|
const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
|
|
1160
1358
|
...(_state.mount
|
|
1161
1359
|
? _formValues
|
|
@@ -1166,7 +1364,7 @@ function createFormControl(props = {}) {
|
|
|
1166
1364
|
: defaultValue),
|
|
1167
1365
|
}, isGlobal, defaultValue);
|
|
1168
1366
|
const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
|
|
1169
|
-
const setFieldValue = (name, value, options = {}) => {
|
|
1367
|
+
const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
|
|
1170
1368
|
const field = get(_fields, name);
|
|
1171
1369
|
let fieldValue = value;
|
|
1172
1370
|
if (field) {
|
|
@@ -1204,20 +1402,29 @@ function createFormControl(props = {}) {
|
|
|
1204
1402
|
}
|
|
1205
1403
|
else {
|
|
1206
1404
|
fieldReference.ref.value = fieldValue;
|
|
1207
|
-
if (!fieldReference.ref.type) {
|
|
1405
|
+
if (!fieldReference.ref.type && !skipRender) {
|
|
1208
1406
|
_subjects.state.next({
|
|
1209
1407
|
name,
|
|
1210
|
-
values: cloneObject(_formValues),
|
|
1408
|
+
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
1211
1409
|
});
|
|
1212
1410
|
}
|
|
1213
1411
|
}
|
|
1214
1412
|
}
|
|
1215
1413
|
}
|
|
1216
1414
|
(options.shouldDirty || options.shouldTouch) &&
|
|
1217
|
-
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty,
|
|
1218
|
-
options.shouldValidate &&
|
|
1415
|
+
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
|
|
1416
|
+
options.shouldValidate &&
|
|
1417
|
+
trigger(name, {
|
|
1418
|
+
delayError: options.delayError,
|
|
1419
|
+
});
|
|
1219
1420
|
};
|
|
1220
|
-
const
|
|
1421
|
+
const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
|
|
1422
|
+
if (_names.array.has(name)) {
|
|
1423
|
+
_subjects.array.next({
|
|
1424
|
+
name,
|
|
1425
|
+
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1221
1428
|
for (const fieldKey in value) {
|
|
1222
1429
|
if (!value.hasOwnProperty(fieldKey)) {
|
|
1223
1430
|
return;
|
|
@@ -1229,50 +1436,84 @@ function createFormControl(props = {}) {
|
|
|
1229
1436
|
isObject(fieldValue) ||
|
|
1230
1437
|
(field && !field._f)) &&
|
|
1231
1438
|
!isDateObject(fieldValue)
|
|
1232
|
-
?
|
|
1233
|
-
: setFieldValue(fieldName, fieldValue, options);
|
|
1439
|
+
? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender)
|
|
1440
|
+
: setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
|
|
1234
1441
|
}
|
|
1235
1442
|
};
|
|
1236
|
-
const
|
|
1443
|
+
const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
|
|
1237
1444
|
const field = get(_fields, name);
|
|
1238
1445
|
const isFieldArray = _names.array.has(name);
|
|
1239
|
-
const cloneValue = cloneObject(value);
|
|
1240
|
-
|
|
1446
|
+
const cloneValue = skipClone ? value : cloneObject(value);
|
|
1447
|
+
const previousValue = get(_formValues, name);
|
|
1448
|
+
const isValueUnchanged = deepEqual(previousValue, cloneValue);
|
|
1449
|
+
if (!isValueUnchanged) {
|
|
1450
|
+
set(_formValues, name, cloneValue);
|
|
1451
|
+
}
|
|
1241
1452
|
if (isFieldArray) {
|
|
1242
1453
|
_subjects.array.next({
|
|
1243
1454
|
name,
|
|
1244
|
-
values: cloneObject(_formValues),
|
|
1455
|
+
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
1245
1456
|
});
|
|
1246
1457
|
if ((_proxyFormState.isDirty ||
|
|
1247
1458
|
_proxyFormState.dirtyFields ||
|
|
1248
1459
|
_proxySubscribeFormState.isDirty ||
|
|
1249
1460
|
_proxySubscribeFormState.dirtyFields) &&
|
|
1250
1461
|
options.shouldDirty) {
|
|
1251
|
-
_updateDirtyFields(
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1462
|
+
_updateDirtyFields();
|
|
1463
|
+
if (!skipStateEmit) {
|
|
1464
|
+
_subjects.state.next({
|
|
1465
|
+
name,
|
|
1466
|
+
dirtyFields: _formState.dirtyFields,
|
|
1467
|
+
isDirty: _getDirty(name, cloneValue),
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1257
1470
|
}
|
|
1258
1471
|
}
|
|
1259
1472
|
else {
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1473
|
+
const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
|
|
1474
|
+
isEmptyObject(cloneValue);
|
|
1475
|
+
if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
|
|
1476
|
+
setFieldValue(name, cloneValue, options, skipClone, skipStateEmit);
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
setFieldValues(name, cloneValue, options, skipClone, skipStateEmit);
|
|
1480
|
+
}
|
|
1263
1481
|
}
|
|
1264
|
-
if (
|
|
1482
|
+
if (!isValueUnchanged && !skipStateEmit) {
|
|
1483
|
+
const watched = isWatched(name, _names);
|
|
1484
|
+
const values = skipClone ? _formValues : cloneObject(_formValues);
|
|
1265
1485
|
_subjects.state.next({
|
|
1266
|
-
..._formState,
|
|
1267
|
-
name,
|
|
1268
|
-
values
|
|
1486
|
+
...(watched && _formState),
|
|
1487
|
+
name: _state.mount || watched ? name : undefined,
|
|
1488
|
+
values,
|
|
1269
1489
|
});
|
|
1270
1490
|
}
|
|
1271
|
-
|
|
1491
|
+
};
|
|
1492
|
+
const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
|
|
1493
|
+
const setValues = (formValues, options = {}) => {
|
|
1494
|
+
const updatedFormValues = isFunction(formValues)
|
|
1495
|
+
? formValues(_formValues)
|
|
1496
|
+
: formValues;
|
|
1497
|
+
if (!deepEqual(_formValues, updatedFormValues)) {
|
|
1498
|
+
_formValues = {
|
|
1499
|
+
..._formValues,
|
|
1500
|
+
...updatedFormValues,
|
|
1501
|
+
};
|
|
1502
|
+
const flattenedUpdates = flatten(updatedFormValues);
|
|
1503
|
+
for (const fieldName of _names.mount) {
|
|
1504
|
+
if (fieldName in flattenedUpdates) {
|
|
1505
|
+
_setValue(fieldName, flattenedUpdates[fieldName], options, true, true);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1272
1508
|
_subjects.state.next({
|
|
1273
|
-
|
|
1274
|
-
|
|
1509
|
+
..._formState,
|
|
1510
|
+
name: undefined,
|
|
1511
|
+
type: undefined,
|
|
1512
|
+
...(_valuesSubscriberCount ? { values: _formValues } : {}),
|
|
1275
1513
|
});
|
|
1514
|
+
if (options.shouldValidate) {
|
|
1515
|
+
_setValid();
|
|
1516
|
+
}
|
|
1276
1517
|
}
|
|
1277
1518
|
};
|
|
1278
1519
|
const onChange = async (event) => {
|
|
@@ -1287,8 +1528,6 @@ function createFormControl(props = {}) {
|
|
|
1287
1528
|
(isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
|
|
1288
1529
|
deepEqual(fieldValue, get(_formValues, name, fieldValue));
|
|
1289
1530
|
};
|
|
1290
|
-
const validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
1291
|
-
const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
1292
1531
|
if (field) {
|
|
1293
1532
|
let error;
|
|
1294
1533
|
let isValid;
|
|
@@ -1296,18 +1535,20 @@ function createFormControl(props = {}) {
|
|
|
1296
1535
|
? getFieldValue(field._f)
|
|
1297
1536
|
: getEventValue(event);
|
|
1298
1537
|
const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
|
|
1299
|
-
const
|
|
1538
|
+
const hasNoValidationEffect = !hasValidation(field._f) &&
|
|
1300
1539
|
!props.validate &&
|
|
1301
1540
|
!_options.resolver &&
|
|
1302
1541
|
!get(_formState.errors, name) &&
|
|
1303
|
-
!field._f.deps
|
|
1304
|
-
|
|
1542
|
+
!field._f.deps;
|
|
1543
|
+
const shouldSkipValidation = hasNoValidationEffect ||
|
|
1544
|
+
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, _validationModeAfterSubmit, _validationModeBeforeSubmit);
|
|
1305
1545
|
const watched = isWatched(name, _names, isBlurEvent);
|
|
1306
1546
|
set(_formValues, name, fieldValue);
|
|
1307
1547
|
if (isBlurEvent) {
|
|
1308
1548
|
if (!target || !target.readOnly) {
|
|
1309
1549
|
field._f.onBlur && field._f.onBlur(event);
|
|
1310
|
-
|
|
1550
|
+
const pendingDelayError = delayErrorCallbacks[name];
|
|
1551
|
+
pendingDelayError && pendingDelayError(0);
|
|
1311
1552
|
}
|
|
1312
1553
|
}
|
|
1313
1554
|
else if (field._f.onChange) {
|
|
@@ -1319,10 +1560,13 @@ function createFormControl(props = {}) {
|
|
|
1319
1560
|
_subjects.state.next({
|
|
1320
1561
|
name,
|
|
1321
1562
|
type: event.type,
|
|
1322
|
-
|
|
1563
|
+
...(_valuesSubscriberCount
|
|
1564
|
+
? { values: cloneObject(_formValues) }
|
|
1565
|
+
: {}),
|
|
1323
1566
|
});
|
|
1324
1567
|
if (shouldSkipValidation) {
|
|
1325
|
-
if (
|
|
1568
|
+
if ((!hasNoValidationEffect || !_formState.isValid) &&
|
|
1569
|
+
(_proxyFormState.isValid || _proxySubscribeFormState.isValid)) {
|
|
1326
1570
|
if (_options.mode === 'onBlur') {
|
|
1327
1571
|
if (isBlurEvent) {
|
|
1328
1572
|
_setValid();
|
|
@@ -1346,13 +1590,15 @@ function createFormControl(props = {}) {
|
|
|
1346
1590
|
const { errors } = await _runSchema([name]);
|
|
1347
1591
|
_updateIsValidating([name]);
|
|
1348
1592
|
_updateIsFieldValueUpdated(fieldValue);
|
|
1349
|
-
if (isFieldValueUpdated) {
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
error = errorLookupResult.error;
|
|
1353
|
-
name = errorLookupResult.name;
|
|
1354
|
-
isValid = isEmptyObject(errors);
|
|
1593
|
+
if (!isFieldValueUpdated) {
|
|
1594
|
+
!isEmptyObject(fieldState) && _subjects.state.next(fieldState);
|
|
1595
|
+
return;
|
|
1355
1596
|
}
|
|
1597
|
+
const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
|
|
1598
|
+
const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
|
|
1599
|
+
error = errorLookupResult.error;
|
|
1600
|
+
name = errorLookupResult.name;
|
|
1601
|
+
isValid = isEmptyObject(errors);
|
|
1356
1602
|
}
|
|
1357
1603
|
else {
|
|
1358
1604
|
_updateIsValidating([name], true);
|
|
@@ -1417,6 +1663,18 @@ function createFormControl(props = {}) {
|
|
|
1417
1663
|
eventType: EVENTS.TRIGGER,
|
|
1418
1664
|
});
|
|
1419
1665
|
}
|
|
1666
|
+
if (options.delayError && _options.delayError && isString(name)) {
|
|
1667
|
+
const error = get(_formState.errors, name);
|
|
1668
|
+
if (error) {
|
|
1669
|
+
unset(_formState.errors, name);
|
|
1670
|
+
delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
|
|
1671
|
+
delayErrorCallbacks[name](_options.delayError);
|
|
1672
|
+
}
|
|
1673
|
+
else {
|
|
1674
|
+
clearTimeout(timers[name]);
|
|
1675
|
+
delete delayErrorCallbacks[name];
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1420
1678
|
_subjects.state.next({
|
|
1421
1679
|
...(!isString(name) ||
|
|
1422
1680
|
((_proxyFormState.isValid || _proxySubscribeFormState.isValid) &&
|
|
@@ -1455,8 +1713,6 @@ function createFormControl(props = {}) {
|
|
|
1455
1713
|
const names = name ? convertToArrayPayload(name) : undefined;
|
|
1456
1714
|
names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
|
|
1457
1715
|
if (names) {
|
|
1458
|
-
// Emit for each cleared field with the field name so that
|
|
1459
|
-
// shouldSubscribeByName can filter and avoid broad re-renders
|
|
1460
1716
|
names.forEach((inputName) => {
|
|
1461
1717
|
_subjects.state.next({
|
|
1462
1718
|
name: inputName,
|
|
@@ -1465,16 +1721,15 @@ function createFormControl(props = {}) {
|
|
|
1465
1721
|
});
|
|
1466
1722
|
}
|
|
1467
1723
|
else {
|
|
1468
|
-
|
|
1724
|
+
_formState.errors = {};
|
|
1469
1725
|
_subjects.state.next({
|
|
1470
|
-
errors:
|
|
1726
|
+
errors: _formState.errors,
|
|
1471
1727
|
});
|
|
1472
1728
|
}
|
|
1473
1729
|
};
|
|
1474
1730
|
const setError = (name, error, options) => {
|
|
1475
1731
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
|
1476
1732
|
const currentError = get(_formState.errors, name) || {};
|
|
1477
|
-
// Don't override existing error messages elsewhere in the object tree.
|
|
1478
1733
|
const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
|
|
1479
1734
|
set(_formState.errors, name, {
|
|
1480
1735
|
...restOfErrorTree,
|
|
@@ -1488,25 +1743,60 @@ function createFormControl(props = {}) {
|
|
|
1488
1743
|
});
|
|
1489
1744
|
options && options.shouldFocus && ref && ref.focus && ref.focus();
|
|
1490
1745
|
};
|
|
1491
|
-
const watch = (name, defaultValue) =>
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1746
|
+
const watch = (name, defaultValue) => {
|
|
1747
|
+
if (isFunction(name)) {
|
|
1748
|
+
_valuesSubscriberCount++;
|
|
1749
|
+
const { unsubscribe } = _subjects.state.subscribe({
|
|
1750
|
+
next: (payload) => 'values' in payload &&
|
|
1751
|
+
name(payload.values || _getWatch(undefined, defaultValue), payload),
|
|
1752
|
+
});
|
|
1753
|
+
let called = false;
|
|
1754
|
+
return {
|
|
1755
|
+
unsubscribe: () => {
|
|
1756
|
+
if (called) {
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
called = true;
|
|
1760
|
+
_valuesSubscriberCount--;
|
|
1761
|
+
unsubscribe();
|
|
1762
|
+
},
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
return _getWatch(name, defaultValue, true);
|
|
1766
|
+
};
|
|
1767
|
+
const _subscribe = (props) => {
|
|
1768
|
+
var _a;
|
|
1769
|
+
const needsValues = !!((_a = props.formState) === null || _a === void 0 ? void 0 : _a.values);
|
|
1770
|
+
if (needsValues) {
|
|
1771
|
+
_valuesSubscriberCount++;
|
|
1772
|
+
}
|
|
1773
|
+
const { unsubscribe } = _subjects.state.subscribe({
|
|
1774
|
+
next: (formState) => {
|
|
1775
|
+
if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
|
|
1776
|
+
shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
|
|
1777
|
+
const snapshot = { ..._formValues };
|
|
1778
|
+
props.callback({
|
|
1779
|
+
values: snapshot,
|
|
1780
|
+
..._formState,
|
|
1781
|
+
...formState,
|
|
1782
|
+
defaultValues: _defaultValues,
|
|
1783
|
+
});
|
|
1784
|
+
}
|
|
1785
|
+
},
|
|
1786
|
+
});
|
|
1787
|
+
if (!needsValues) {
|
|
1788
|
+
return unsubscribe;
|
|
1789
|
+
}
|
|
1790
|
+
let called = false;
|
|
1791
|
+
return () => {
|
|
1792
|
+
if (called) {
|
|
1793
|
+
return;
|
|
1507
1794
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1795
|
+
called = true;
|
|
1796
|
+
_valuesSubscriberCount--;
|
|
1797
|
+
unsubscribe();
|
|
1798
|
+
};
|
|
1799
|
+
};
|
|
1510
1800
|
const subscribe = (props) => {
|
|
1511
1801
|
_state.mount = true;
|
|
1512
1802
|
_proxySubscribeFormState = {
|
|
@@ -1561,7 +1851,7 @@ function createFormControl(props = {}) {
|
|
|
1561
1851
|
const register = (name, options = {}) => {
|
|
1562
1852
|
let field = get(_fields, name);
|
|
1563
1853
|
const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
|
|
1564
|
-
const shouldRevalidateRemount = !_names.registerName.has(name) && field && !field._f.mount;
|
|
1854
|
+
const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
|
|
1565
1855
|
set(_fields, name, {
|
|
1566
1856
|
...(field || {}),
|
|
1567
1857
|
_f: {
|
|
@@ -1618,20 +1908,23 @@ function createFormControl(props = {}) {
|
|
|
1618
1908
|
: fieldRef === field._f.ref) {
|
|
1619
1909
|
return;
|
|
1620
1910
|
}
|
|
1911
|
+
const newField = {
|
|
1912
|
+
...field._f,
|
|
1913
|
+
};
|
|
1914
|
+
if (radioOrCheckbox) {
|
|
1915
|
+
newField.refs = [
|
|
1916
|
+
...refs.filter(live),
|
|
1917
|
+
fieldRef,
|
|
1918
|
+
...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
|
|
1919
|
+
];
|
|
1920
|
+
newField.ref = { type: fieldRef.type, name };
|
|
1921
|
+
}
|
|
1922
|
+
else {
|
|
1923
|
+
newField.ref = fieldRef;
|
|
1924
|
+
delete newField.refs;
|
|
1925
|
+
}
|
|
1621
1926
|
set(_fields, name, {
|
|
1622
|
-
_f:
|
|
1623
|
-
...field._f,
|
|
1624
|
-
...(radioOrCheckbox
|
|
1625
|
-
? {
|
|
1626
|
-
refs: [
|
|
1627
|
-
...refs.filter(live),
|
|
1628
|
-
fieldRef,
|
|
1629
|
-
...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
|
|
1630
|
-
],
|
|
1631
|
-
ref: { type: fieldRef.type, name },
|
|
1632
|
-
}
|
|
1633
|
-
: { ref: fieldRef }),
|
|
1634
|
-
},
|
|
1927
|
+
_f: newField,
|
|
1635
1928
|
});
|
|
1636
1929
|
updateValidAndValue(name, false, undefined, fieldRef);
|
|
1637
1930
|
}
|
|
@@ -1648,6 +1941,7 @@ function createFormControl(props = {}) {
|
|
|
1648
1941
|
};
|
|
1649
1942
|
};
|
|
1650
1943
|
const _focusError = () => _options.shouldFocusError &&
|
|
1944
|
+
!_options.shouldUseNativeValidation &&
|
|
1651
1945
|
iterateFieldsByAction(_fields, _focusInput, _names.mount);
|
|
1652
1946
|
const _disableForm = (disabled) => {
|
|
1653
1947
|
if (isBoolean(disabled)) {
|
|
@@ -1666,6 +1960,7 @@ function createFormControl(props = {}) {
|
|
|
1666
1960
|
}
|
|
1667
1961
|
};
|
|
1668
1962
|
const handleSubmit = (onValid, onInvalid) => async (e) => {
|
|
1963
|
+
let result = undefined;
|
|
1669
1964
|
let onValidError = undefined;
|
|
1670
1965
|
if (e) {
|
|
1671
1966
|
e.preventDefault && e.preventDefault();
|
|
@@ -1699,7 +1994,7 @@ function createFormControl(props = {}) {
|
|
|
1699
1994
|
errors: {},
|
|
1700
1995
|
});
|
|
1701
1996
|
try {
|
|
1702
|
-
await onValid(fieldValues, e);
|
|
1997
|
+
result = await onValid(fieldValues, e);
|
|
1703
1998
|
}
|
|
1704
1999
|
catch (error) {
|
|
1705
2000
|
onValidError = error;
|
|
@@ -1722,6 +2017,7 @@ function createFormControl(props = {}) {
|
|
|
1722
2017
|
if (onValidError) {
|
|
1723
2018
|
throw onValidError;
|
|
1724
2019
|
}
|
|
2020
|
+
return result;
|
|
1725
2021
|
};
|
|
1726
2022
|
const resetField = (name, options = {}) => {
|
|
1727
2023
|
if (get(_fields, name)) {
|
|
@@ -1752,7 +2048,8 @@ function createFormControl(props = {}) {
|
|
|
1752
2048
|
const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
|
|
1753
2049
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
|
1754
2050
|
const isEmptyResetValues = isEmptyObject(formValues);
|
|
1755
|
-
const values =
|
|
2051
|
+
const values = cloneUpdatedValues;
|
|
2052
|
+
const fieldRefs = _fields;
|
|
1756
2053
|
if (!keepStateOptions.keepDefaultValues) {
|
|
1757
2054
|
_defaultValues = updatedValues;
|
|
1758
2055
|
}
|
|
@@ -1760,7 +2057,7 @@ function createFormControl(props = {}) {
|
|
|
1760
2057
|
if (keepStateOptions.keepDirtyValues) {
|
|
1761
2058
|
const fieldsToCheck = new Set([
|
|
1762
2059
|
..._names.mount,
|
|
1763
|
-
...
|
|
2060
|
+
...collectDirtyFieldNames(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs), _formState.dirtyFields),
|
|
1764
2061
|
]);
|
|
1765
2062
|
for (const fieldName of Array.from(fieldsToCheck)) {
|
|
1766
2063
|
const isDirty = get(_formState.dirtyFields, fieldName);
|
|
@@ -1801,15 +2098,25 @@ function createFormControl(props = {}) {
|
|
|
1801
2098
|
_fields = {};
|
|
1802
2099
|
}
|
|
1803
2100
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
2101
|
+
if (_options.shouldUnregister) {
|
|
2102
|
+
_formValues = keepStateOptions.keepDefaultValues
|
|
1806
2103
|
? cloneObject(_defaultValues)
|
|
1807
|
-
: {}
|
|
1808
|
-
|
|
2104
|
+
: {};
|
|
2105
|
+
if (keepStateOptions.keepFieldsRef) {
|
|
2106
|
+
for (const fieldName of _names.mount) {
|
|
2107
|
+
set(_formValues, fieldName, get(values, fieldName));
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
else {
|
|
2112
|
+
_formValues = cloneObject(values);
|
|
2113
|
+
}
|
|
1809
2114
|
_subjects.array.next({
|
|
1810
2115
|
values: { ...values },
|
|
1811
2116
|
});
|
|
1812
2117
|
_subjects.state.next({
|
|
2118
|
+
name: undefined,
|
|
2119
|
+
type: undefined,
|
|
1813
2120
|
values: { ...values },
|
|
1814
2121
|
});
|
|
1815
2122
|
}
|
|
@@ -1831,9 +2138,6 @@ function createFormControl(props = {}) {
|
|
|
1831
2138
|
_state.watch = !!_options.shouldUnregister;
|
|
1832
2139
|
_state.keepIsValid = !!keepStateOptions.keepIsValid;
|
|
1833
2140
|
_state.action = false;
|
|
1834
|
-
// Clear errors synchronously to prevent validation errors on subsequent submissions
|
|
1835
|
-
// This fixes the issue where form.reset() causes validation errors on subsequent
|
|
1836
|
-
// submissions in Next.js 16 with Server Actions
|
|
1837
2141
|
if (!keepStateOptions.keepErrors) {
|
|
1838
2142
|
_formState.errors = {};
|
|
1839
2143
|
}
|
|
@@ -1845,8 +2149,10 @@ function createFormControl(props = {}) {
|
|
|
1845
2149
|
? false
|
|
1846
2150
|
: keepStateOptions.keepDirty
|
|
1847
2151
|
? _formState.isDirty
|
|
1848
|
-
:
|
|
1849
|
-
|
|
2152
|
+
: keepStateOptions.keepValues
|
|
2153
|
+
? _getDirty()
|
|
2154
|
+
: !!(keepStateOptions.keepDefaultValues &&
|
|
2155
|
+
!deepEqual(formValues, _defaultValues)),
|
|
1850
2156
|
isSubmitted: keepStateOptions.keepIsSubmitted
|
|
1851
2157
|
? _formState.isSubmitted
|
|
1852
2158
|
: false,
|
|
@@ -1854,10 +2160,10 @@ function createFormControl(props = {}) {
|
|
|
1854
2160
|
? {}
|
|
1855
2161
|
: keepStateOptions.keepDirtyValues
|
|
1856
2162
|
? keepStateOptions.keepDefaultValues && _formValues
|
|
1857
|
-
? getDirtyFields(_defaultValues, _formValues)
|
|
2163
|
+
? getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)
|
|
1858
2164
|
: _formState.dirtyFields
|
|
1859
2165
|
: keepStateOptions.keepDefaultValues && formValues
|
|
1860
|
-
? getDirtyFields(_defaultValues, formValues)
|
|
2166
|
+
? getDirtyFields(_defaultValues, formValues, undefined, fieldRefs)
|
|
1861
2167
|
: keepStateOptions.keepDirty
|
|
1862
2168
|
? _formState.dirtyFields
|
|
1863
2169
|
: {},
|
|
@@ -1883,8 +2189,6 @@ function createFormControl(props = {}) {
|
|
|
1883
2189
|
? fieldReference.refs[0]
|
|
1884
2190
|
: fieldReference.ref;
|
|
1885
2191
|
if (fieldRef.focus) {
|
|
1886
|
-
// Use setTimeout to ensure focus happens after any pending state updates
|
|
1887
|
-
// This fixes the issue where setFocus doesn't work immediately after setError
|
|
1888
2192
|
setTimeout(() => {
|
|
1889
2193
|
fieldRef.focus();
|
|
1890
2194
|
options.shouldSelect &&
|
|
@@ -1895,9 +2199,15 @@ function createFormControl(props = {}) {
|
|
|
1895
2199
|
}
|
|
1896
2200
|
};
|
|
1897
2201
|
const _setFormState = (updatedFormState) => {
|
|
2202
|
+
// `name`, `type`, and `values` describe the event that produced this
|
|
2203
|
+
// update, not the form's persisted state (they aren't part of
|
|
2204
|
+
// `FormState`). Merging them in would leak a stale `name`/`type` from
|
|
2205
|
+
// one event into a later, unrelated notification that doesn't specify
|
|
2206
|
+
// its own.
|
|
2207
|
+
const { name, type, values, ...formState } = updatedFormState;
|
|
1898
2208
|
_formState = {
|
|
1899
2209
|
..._formState,
|
|
1900
|
-
...
|
|
2210
|
+
...formState,
|
|
1901
2211
|
};
|
|
1902
2212
|
};
|
|
1903
2213
|
const _resetDefaultValues = () => isFunction(_options.defaultValues) &&
|
|
@@ -1907,6 +2217,21 @@ function createFormControl(props = {}) {
|
|
|
1907
2217
|
isLoading: false,
|
|
1908
2218
|
});
|
|
1909
2219
|
});
|
|
2220
|
+
const resetDefaultValues = (values, options = {}) => {
|
|
2221
|
+
_defaultValues = cloneObject(values);
|
|
2222
|
+
if (!options.keepDirty) {
|
|
2223
|
+
const newDirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
2224
|
+
_formState.dirtyFields = newDirtyFields;
|
|
2225
|
+
_formState.isDirty = !isEmptyObject(newDirtyFields);
|
|
2226
|
+
}
|
|
2227
|
+
if (!options.keepIsValid) {
|
|
2228
|
+
_setValid();
|
|
2229
|
+
}
|
|
2230
|
+
_subjects.state.next({
|
|
2231
|
+
..._formState,
|
|
2232
|
+
defaultValues: _defaultValues,
|
|
2233
|
+
});
|
|
2234
|
+
};
|
|
1910
2235
|
const methods = {
|
|
1911
2236
|
control: {
|
|
1912
2237
|
register,
|
|
@@ -1963,6 +2288,8 @@ function createFormControl(props = {}) {
|
|
|
1963
2288
|
..._options,
|
|
1964
2289
|
...value,
|
|
1965
2290
|
};
|
|
2291
|
+
_validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
2292
|
+
_validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
1966
2293
|
},
|
|
1967
2294
|
},
|
|
1968
2295
|
subscribe,
|
|
@@ -1971,9 +2298,11 @@ function createFormControl(props = {}) {
|
|
|
1971
2298
|
handleSubmit,
|
|
1972
2299
|
watch,
|
|
1973
2300
|
setValue,
|
|
2301
|
+
setValues,
|
|
1974
2302
|
getValues,
|
|
1975
2303
|
reset,
|
|
1976
2304
|
resetField,
|
|
2305
|
+
resetDefaultValues,
|
|
1977
2306
|
clearErrors,
|
|
1978
2307
|
unregister,
|
|
1979
2308
|
setError,
|