react-hook-form 7.40.0 → 7.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/controller.server.test.d.ts +2 -0
- package/dist/__tests__/controller.server.test.d.ts.map +1 -0
- package/dist/__tests__/controller.test.d.ts +2 -0
- package/dist/__tests__/controller.test.d.ts.map +1 -0
- package/dist/__tests__/logic/validateField.test.d.ts +2 -0
- package/dist/__tests__/logic/validateField.test.d.ts.map +1 -0
- package/dist/__tests__/type.test.d.ts +2 -0
- package/dist/__tests__/type.test.d.ts.map +1 -0
- package/dist/__tests__/useController.test.d.ts +2 -0
- package/dist/__tests__/useController.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/append.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/append.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/focus.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/focus.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/insert.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/insert.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/move.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/move.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/prepend.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/remove.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/remove.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/replace.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/replace.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/swap.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/swap.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray/update.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray/update.test.d.ts.map +1 -0
- package/dist/__tests__/useFieldArray.test.d.ts +2 -0
- package/dist/__tests__/useFieldArray.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/clearErrors.test.d.ts +2 -0
- package/dist/__tests__/useForm/clearErrors.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/formState.test.d.ts +2 -0
- package/dist/__tests__/useForm/formState.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/getFieldState.test.d.ts +2 -0
- package/dist/__tests__/useForm/getFieldState.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/getValues.test.d.ts +2 -0
- package/dist/__tests__/useForm/getValues.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/handleSubmit.test.d.ts +2 -0
- package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/register.test.d.ts +2 -0
- package/dist/__tests__/useForm/register.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/reset.test.d.ts +2 -0
- package/dist/__tests__/useForm/reset.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/resetField.test.d.ts +2 -0
- package/dist/__tests__/useForm/resetField.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/resolver.test.d.ts +2 -0
- package/dist/__tests__/useForm/resolver.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/setError.test.d.ts +2 -0
- package/dist/__tests__/useForm/setError.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/setValue.test.d.ts +2 -0
- package/dist/__tests__/useForm/setValue.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/trigger.test.d.ts +2 -0
- package/dist/__tests__/useForm/trigger.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/unregister.test.d.ts +2 -0
- package/dist/__tests__/useForm/unregister.test.d.ts.map +1 -0
- package/dist/__tests__/useForm/watch.test.d.ts +2 -0
- package/dist/__tests__/useForm/watch.test.d.ts.map +1 -0
- package/dist/__tests__/useForm.server.test.d.ts +2 -0
- package/dist/__tests__/useForm.server.test.d.ts.map +1 -0
- package/dist/__tests__/useForm.test.d.ts +2 -0
- package/dist/__tests__/useForm.test.d.ts.map +1 -0
- package/dist/__tests__/useFormContext.server.test.d.ts +2 -0
- package/dist/__tests__/useFormContext.server.test.d.ts.map +1 -0
- package/dist/__tests__/useFormContext.test.d.ts +2 -0
- package/dist/__tests__/useFormContext.test.d.ts.map +1 -0
- package/dist/__tests__/useFormState.test.d.ts +2 -0
- package/dist/__tests__/useFormState.test.d.ts.map +1 -0
- package/dist/__tests__/useWatch.test.d.ts +2 -0
- package/dist/__tests__/useWatch.test.d.ts.map +1 -0
- package/dist/controller.d.ts +1 -1
- package/dist/controller.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 +70 -47
- 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 +25 -2
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/{utils → logic}/getValidationModes.d.ts +0 -0
- package/dist/{utils → logic}/getValidationModes.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
- package/dist/logic/validateField.d.ts.map +1 -1
- package/dist/types/errors.d.ts +2 -2
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/form.d.ts +11 -7
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/path/eager.d.ts +5 -5
- package/dist/types/path/eager.d.ts.map +1 -1
- package/dist/types/utils.d.ts +1 -0
- 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/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormContext.d.ts +1 -0
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/useSubscribe.d.ts +1 -1
- package/dist/useSubscribe.d.ts.map +1 -1
- package/dist/utils/isHTMLElement.d.ts.map +1 -1
- package/package.json +18 -18
package/dist/index.esm.mjs
CHANGED
@@ -173,7 +173,7 @@ function useSubscribe(props) {
|
|
173
173
|
React.useEffect(() => {
|
174
174
|
const subscription = !props.disabled &&
|
175
175
|
_props.current.subject.subscribe({
|
176
|
-
next: _props.current.
|
176
|
+
next: _props.current.next,
|
177
177
|
});
|
178
178
|
return () => {
|
179
179
|
subscription && subscription.unsubscribe();
|
@@ -218,6 +218,7 @@ function useFormState(props) {
|
|
218
218
|
const _mounted = React.useRef(true);
|
219
219
|
const _localProxyFormState = React.useRef({
|
220
220
|
isDirty: false,
|
221
|
+
isLoading: false,
|
221
222
|
dirtyFields: false,
|
222
223
|
touchedFields: false,
|
223
224
|
isValidating: false,
|
@@ -228,13 +229,13 @@ function useFormState(props) {
|
|
228
229
|
_name.current = name;
|
229
230
|
useSubscribe({
|
230
231
|
disabled,
|
231
|
-
|
232
|
+
next: (value) => _mounted.current &&
|
232
233
|
shouldSubscribeByName(_name.current, value.name, exact) &&
|
233
234
|
shouldRenderFormState(value, _localProxyFormState.current) &&
|
234
235
|
updateFormState({
|
235
236
|
...control._formState,
|
236
237
|
...value,
|
237
|
-
}),
|
238
|
+
}),
|
238
239
|
subject: control._subjects.state,
|
239
240
|
});
|
240
241
|
React.useEffect(() => {
|
@@ -327,16 +328,14 @@ function useWatch(props) {
|
|
327
328
|
useSubscribe({
|
328
329
|
disabled,
|
329
330
|
subject: control._subjects.watch,
|
330
|
-
|
331
|
+
next: (formState) => {
|
331
332
|
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
332
333
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
333
334
|
updateValue(isUndefined(fieldValues) ? defaultValue : cloneObject(fieldValues));
|
334
335
|
}
|
335
336
|
},
|
336
337
|
});
|
337
|
-
const [value, updateValue] = React.useState(
|
338
|
-
? control._getWatch(name)
|
339
|
-
: defaultValue);
|
338
|
+
const [value, updateValue] = React.useState(control._getWatch(name, defaultValue));
|
340
339
|
React.useEffect(() => control._removeUnmounted());
|
341
340
|
return value;
|
342
341
|
}
|
@@ -568,6 +567,14 @@ var getFocusFieldName = (name, index, options = {}) => options.shouldFocus || is
|
|
568
567
|
`${name}.${isUndefined(options.focusIndex) ? index : options.focusIndex}.`
|
569
568
|
: '';
|
570
569
|
|
570
|
+
var getValidationModes = (mode) => ({
|
571
|
+
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
572
|
+
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
573
|
+
isOnChange: mode === VALIDATION_MODE.onChange,
|
574
|
+
isOnAll: mode === VALIDATION_MODE.all,
|
575
|
+
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
576
|
+
});
|
577
|
+
|
571
578
|
var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
|
572
579
|
(_names.watchAll ||
|
573
580
|
_names.watch.has(name) ||
|
@@ -666,7 +673,9 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
666
673
|
const isRadio = isRadioInput(ref);
|
667
674
|
const isCheckBox = isCheckBoxInput(ref);
|
668
675
|
const isRadioOrCheckbox = isRadio || isCheckBox;
|
669
|
-
const isEmpty = ((valueAsNumber || isFileInput(ref)) &&
|
676
|
+
const isEmpty = ((valueAsNumber || isFileInput(ref)) &&
|
677
|
+
isUndefined(ref.value) &&
|
678
|
+
isUndefined(inputValue)) ||
|
670
679
|
inputValue === '' ||
|
671
680
|
(Array.isArray(inputValue) && !inputValue.length);
|
672
681
|
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
@@ -831,14 +840,6 @@ function append(data, value) {
|
|
831
840
|
|
832
841
|
var fillEmptyArray = (value) => Array.isArray(value) ? value.map(() => undefined) : undefined;
|
833
842
|
|
834
|
-
var getValidationModes = (mode) => ({
|
835
|
-
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
836
|
-
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
837
|
-
isOnChange: mode === VALIDATION_MODE.onChange,
|
838
|
-
isOnAll: mode === VALIDATION_MODE.all,
|
839
|
-
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
840
|
-
});
|
841
|
-
|
842
843
|
function insert(data, index, value) {
|
843
844
|
return [
|
844
845
|
...data.slice(0, index),
|
@@ -980,17 +981,16 @@ function useFieldArray(props) {
|
|
980
981
|
control._names.array.add(name);
|
981
982
|
props.rules &&
|
982
983
|
control.register(name, props.rules);
|
983
|
-
const callback = React.useCallback(({ values, name: fieldArrayName, }) => {
|
984
|
-
if (fieldArrayName === _name.current || !fieldArrayName) {
|
985
|
-
const fieldValues = get(values, _name.current);
|
986
|
-
if (Array.isArray(fieldValues)) {
|
987
|
-
setFields(fieldValues);
|
988
|
-
ids.current = fieldValues.map(generateId);
|
989
|
-
}
|
990
|
-
}
|
991
|
-
}, []);
|
992
984
|
useSubscribe({
|
993
|
-
|
985
|
+
next: ({ values, name: fieldArrayName, }) => {
|
986
|
+
if (fieldArrayName === _name.current || !fieldArrayName) {
|
987
|
+
const fieldValues = get(values, _name.current);
|
988
|
+
if (Array.isArray(fieldValues)) {
|
989
|
+
setFields(fieldValues);
|
990
|
+
ids.current = fieldValues.map(generateId);
|
991
|
+
}
|
992
|
+
}
|
993
|
+
},
|
994
994
|
subject: control._subjects.array,
|
995
995
|
});
|
996
996
|
const updateValues = React.useCallback((updatedFieldArrayValues) => {
|
@@ -1205,8 +1205,8 @@ function deepEqual(object1, object2) {
|
|
1205
1205
|
|
1206
1206
|
var isHTMLElement = (value) => {
|
1207
1207
|
const owner = value ? value.ownerDocument : 0;
|
1208
|
-
|
1209
|
-
|
1208
|
+
return (value instanceof
|
1209
|
+
(owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement));
|
1210
1210
|
};
|
1211
1211
|
|
1212
1212
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
@@ -1386,14 +1386,16 @@ const defaultOptions = {
|
|
1386
1386
|
reValidateMode: VALIDATION_MODE.onChange,
|
1387
1387
|
shouldFocusError: true,
|
1388
1388
|
};
|
1389
|
-
function createFormControl(props = {}) {
|
1389
|
+
function createFormControl(props = {}, flushRootRender) {
|
1390
1390
|
let _options = {
|
1391
1391
|
...defaultOptions,
|
1392
1392
|
...props,
|
1393
1393
|
};
|
1394
|
+
const shouldCaptureDirtyFields = props.resetOptions && props.resetOptions.keepDirtyValues;
|
1394
1395
|
let _formState = {
|
1395
1396
|
submitCount: 0,
|
1396
1397
|
isDirty: false,
|
1398
|
+
isLoading: true,
|
1397
1399
|
isValidating: false,
|
1398
1400
|
isSubmitted: false,
|
1399
1401
|
isSubmitting: false,
|
@@ -1404,7 +1406,9 @@ function createFormControl(props = {}) {
|
|
1404
1406
|
errors: {},
|
1405
1407
|
};
|
1406
1408
|
let _fields = {};
|
1407
|
-
let _defaultValues =
|
1409
|
+
let _defaultValues = isObject(_options.defaultValues)
|
1410
|
+
? cloneObject(_options.defaultValues) || {}
|
1411
|
+
: {};
|
1408
1412
|
let _formValues = _options.shouldUnregister
|
1409
1413
|
? {}
|
1410
1414
|
: cloneObject(_defaultValues);
|
@@ -1455,7 +1459,6 @@ function createFormControl(props = {}) {
|
|
1455
1459
|
}
|
1456
1460
|
};
|
1457
1461
|
const _updateIsValidating = (value) => _proxyFormState.isValidating &&
|
1458
|
-
value !== _formState.isValidating &&
|
1459
1462
|
_subjects.state.next({
|
1460
1463
|
isValidating: value,
|
1461
1464
|
});
|
@@ -1523,16 +1526,16 @@ function createFormControl(props = {}) {
|
|
1523
1526
|
_formState.isDirty = output.isDirty = _getDirty();
|
1524
1527
|
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
1525
1528
|
}
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
shouldUpdateField
|
1534
|
-
|
1535
|
-
|
1529
|
+
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
1530
|
+
isPreviousDirty = get(_formState.dirtyFields, name);
|
1531
|
+
isCurrentFieldPristine
|
1532
|
+
? unset(_formState.dirtyFields, name)
|
1533
|
+
: set(_formState.dirtyFields, name, true);
|
1534
|
+
output.dirtyFields = _formState.dirtyFields;
|
1535
|
+
shouldUpdateField =
|
1536
|
+
shouldUpdateField ||
|
1537
|
+
(_proxyFormState.dirtyFields &&
|
1538
|
+
isPreviousDirty !== !isCurrentFieldPristine);
|
1536
1539
|
}
|
1537
1540
|
if (isBlurEvent) {
|
1538
1541
|
const isPreviousFieldTouched = get(_formState.touchedFields, name);
|
@@ -1693,7 +1696,8 @@ function createFormControl(props = {}) {
|
|
1693
1696
|
}
|
1694
1697
|
(options.shouldDirty || options.shouldTouch) &&
|
1695
1698
|
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
|
1696
|
-
options.shouldValidate &&
|
1699
|
+
options.shouldValidate &&
|
1700
|
+
trigger(name);
|
1697
1701
|
};
|
1698
1702
|
const setValues = (name, value, options) => {
|
1699
1703
|
for (const fieldKey in value) {
|
@@ -1737,6 +1741,7 @@ function createFormControl(props = {}) {
|
|
1737
1741
|
_subjects.watch.next({
|
1738
1742
|
name,
|
1739
1743
|
});
|
1744
|
+
!_stateFlags.mount && flushRootRender();
|
1740
1745
|
};
|
1741
1746
|
const onChange = async (event) => {
|
1742
1747
|
const target = event.target;
|
@@ -2070,7 +2075,7 @@ function createFormControl(props = {}) {
|
|
2070
2075
|
_defaultValues = updatedValues;
|
2071
2076
|
}
|
2072
2077
|
if (!keepStateOptions.keepValues) {
|
2073
|
-
if (keepStateOptions.keepDirtyValues) {
|
2078
|
+
if (keepStateOptions.keepDirtyValues || shouldCaptureDirtyFields) {
|
2074
2079
|
for (const fieldName of _names.mount) {
|
2075
2080
|
get(_formState.dirtyFields, fieldName)
|
2076
2081
|
? set(values, fieldName, get(_formValues, fieldName))
|
@@ -2117,6 +2122,7 @@ function createFormControl(props = {}) {
|
|
2117
2122
|
watchAll: false,
|
2118
2123
|
focus: '',
|
2119
2124
|
};
|
2125
|
+
!_stateFlags.mount && flushRootRender();
|
2120
2126
|
_stateFlags.mount =
|
2121
2127
|
!_proxyFormState.isValid || !!keepStateOptions.keepIsValid;
|
2122
2128
|
_stateFlags.watch = !!props.shouldUnregister;
|
@@ -2160,6 +2166,14 @@ function createFormControl(props = {}) {
|
|
2160
2166
|
}
|
2161
2167
|
}
|
2162
2168
|
};
|
2169
|
+
if (isFunction(_options.defaultValues)) {
|
2170
|
+
_options.defaultValues().then((values) => {
|
2171
|
+
reset(values, _options.resetOptions);
|
2172
|
+
_subjects.state.next({
|
2173
|
+
isLoading: false,
|
2174
|
+
});
|
2175
|
+
});
|
2176
|
+
}
|
2163
2177
|
return {
|
2164
2178
|
control: {
|
2165
2179
|
register,
|
@@ -2173,6 +2187,7 @@ function createFormControl(props = {}) {
|
|
2173
2187
|
_removeUnmounted,
|
2174
2188
|
_updateFieldArray,
|
2175
2189
|
_getFieldArray,
|
2190
|
+
_reset,
|
2176
2191
|
_subjects,
|
2177
2192
|
_proxyFormState,
|
2178
2193
|
get _fields() {
|
@@ -2262,6 +2277,7 @@ function useForm(props = {}) {
|
|
2262
2277
|
const [formState, updateFormState] = React.useState({
|
2263
2278
|
isDirty: false,
|
2264
2279
|
isValidating: false,
|
2280
|
+
isLoading: true,
|
2265
2281
|
isSubmitted: false,
|
2266
2282
|
isSubmitting: false,
|
2267
2283
|
isSubmitSuccessful: false,
|
@@ -2270,11 +2286,13 @@ function useForm(props = {}) {
|
|
2270
2286
|
dirtyFields: {},
|
2271
2287
|
touchedFields: {},
|
2272
2288
|
errors: {},
|
2273
|
-
defaultValues: props.defaultValues
|
2289
|
+
defaultValues: isFunction(props.defaultValues)
|
2290
|
+
? undefined
|
2291
|
+
: props.defaultValues,
|
2274
2292
|
});
|
2275
2293
|
if (!_formControl.current) {
|
2276
2294
|
_formControl.current = {
|
2277
|
-
...createFormControl(props),
|
2295
|
+
...createFormControl(props, () => updateFormState((formState) => ({ ...formState }))),
|
2278
2296
|
formState,
|
2279
2297
|
};
|
2280
2298
|
}
|
@@ -2282,7 +2300,7 @@ function useForm(props = {}) {
|
|
2282
2300
|
control._options = props;
|
2283
2301
|
useSubscribe({
|
2284
2302
|
subject: control._subjects.state,
|
2285
|
-
|
2303
|
+
next: (value) => {
|
2286
2304
|
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2287
2305
|
control._formState = {
|
2288
2306
|
...control._formState,
|
@@ -2290,7 +2308,7 @@ function useForm(props = {}) {
|
|
2290
2308
|
};
|
2291
2309
|
updateFormState({ ...control._formState });
|
2292
2310
|
}
|
2293
|
-
},
|
2311
|
+
},
|
2294
2312
|
});
|
2295
2313
|
React.useEffect(() => {
|
2296
2314
|
if (!control._stateFlags.mount) {
|
@@ -2303,6 +2321,11 @@ function useForm(props = {}) {
|
|
2303
2321
|
}
|
2304
2322
|
control._removeUnmounted();
|
2305
2323
|
});
|
2324
|
+
React.useEffect(() => {
|
2325
|
+
if (props.values && !deepEqual(props.values, control._defaultValues)) {
|
2326
|
+
control._reset(props.values, control._options.resetOptions);
|
2327
|
+
}
|
2328
|
+
}, [props.values, control]);
|
2306
2329
|
React.useEffect(() => {
|
2307
2330
|
formState.submitCount && control._focusError();
|
2308
2331
|
}, [control, formState.submitCount]);
|