react-hook-form 7.57.0-next.0 → 7.57.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 +8 -4
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +91 -93
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/schemaErrorLookup.d.ts.map +1 -1
- package/dist/logic/shouldSubscribeByName.d.ts +1 -1
- package/dist/logic/shouldSubscribeByName.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +25 -11
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/form.d.ts +14 -11
- package/dist/types/form.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/useFormState.d.ts.map +1 -1
- package/dist/useIsomorphicLayoutEffect.d.ts +3 -0
- package/dist/useIsomorphicLayoutEffect.d.ts.map +1 -0
- package/dist/useWatch.d.ts +0 -91
- package/dist/useWatch.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/useDeepEqualEffect.d.ts +0 -3
- package/dist/useDeepEqualEffect.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import * as React from 'react';
|
2
|
-
import React__default
|
2
|
+
import React__default from 'react';
|
3
3
|
|
4
4
|
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
5
5
|
|
@@ -217,47 +217,7 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
217
217
|
return result;
|
218
218
|
};
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
function deepEqual(object1, object2) {
|
223
|
-
if (isPrimitive(object1) || isPrimitive(object2)) {
|
224
|
-
return object1 === object2;
|
225
|
-
}
|
226
|
-
if (isDateObject(object1) && isDateObject(object2)) {
|
227
|
-
return object1.getTime() === object2.getTime();
|
228
|
-
}
|
229
|
-
const keys1 = Object.keys(object1);
|
230
|
-
const keys2 = Object.keys(object2);
|
231
|
-
if (keys1.length !== keys2.length) {
|
232
|
-
return false;
|
233
|
-
}
|
234
|
-
for (const key of keys1) {
|
235
|
-
const val1 = object1[key];
|
236
|
-
if (!keys2.includes(key)) {
|
237
|
-
return false;
|
238
|
-
}
|
239
|
-
if (key !== 'ref') {
|
240
|
-
const val2 = object2[key];
|
241
|
-
if ((isDateObject(val1) && isDateObject(val2)) ||
|
242
|
-
(isObject(val1) && isObject(val2)) ||
|
243
|
-
(Array.isArray(val1) && Array.isArray(val2))
|
244
|
-
? !deepEqual(val1, val2)
|
245
|
-
: val1 !== val2) {
|
246
|
-
return false;
|
247
|
-
}
|
248
|
-
}
|
249
|
-
}
|
250
|
-
return true;
|
251
|
-
}
|
252
|
-
|
253
|
-
const useDeepEqualEffect = (effect, deps) => {
|
254
|
-
const ref = React.useRef(deps);
|
255
|
-
if (!deepEqual(deps, ref.current)) {
|
256
|
-
ref.current = deps;
|
257
|
-
}
|
258
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
259
|
-
React.useEffect(effect, ref.current);
|
260
|
-
};
|
220
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
261
221
|
|
262
222
|
/**
|
263
223
|
* This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
|
@@ -303,8 +263,8 @@ function useFormState(props) {
|
|
303
263
|
isValid: false,
|
304
264
|
errors: false,
|
305
265
|
});
|
306
|
-
|
307
|
-
name
|
266
|
+
useIsomorphicLayoutEffect(() => control._subscribe({
|
267
|
+
name,
|
308
268
|
formState: _localProxyFormState.current,
|
309
269
|
exact,
|
310
270
|
callback: (formState) => {
|
@@ -353,34 +313,18 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
353
313
|
*/
|
354
314
|
function useWatch(props) {
|
355
315
|
const methods = useFormContext();
|
356
|
-
const { control = methods.control, name, defaultValue, disabled, exact,
|
357
|
-
const
|
358
|
-
const
|
359
|
-
|
360
|
-
|
361
|
-
const [value, updateValue] = React__default.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo);
|
362
|
-
useDeepEqualEffect(() => control._subscribe({
|
363
|
-
name: name,
|
316
|
+
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
317
|
+
const _defaultValue = React__default.useRef(defaultValue);
|
318
|
+
const [value, updateValue] = React__default.useState(control._getWatch(name, _defaultValue.current));
|
319
|
+
useIsomorphicLayoutEffect(() => control._subscribe({
|
320
|
+
name,
|
364
321
|
formState: {
|
365
322
|
values: true,
|
366
323
|
},
|
367
324
|
exact,
|
368
|
-
callback: (formState) =>
|
369
|
-
|
370
|
-
|
371
|
-
if (_compute.current) {
|
372
|
-
const computedFormValues = _compute.current(formValues);
|
373
|
-
if (!deepEqual(computedFormValues, _computeFormValues.current)) {
|
374
|
-
updateValue(computedFormValues);
|
375
|
-
_computeFormValues.current = computedFormValues;
|
376
|
-
}
|
377
|
-
}
|
378
|
-
else {
|
379
|
-
updateValue(formValues);
|
380
|
-
}
|
381
|
-
}
|
382
|
-
},
|
383
|
-
}), [defaultValue, disabled, name, exact]);
|
325
|
+
callback: (formState) => !disabled &&
|
326
|
+
updateValue(generateWatchOutput(name, control._names, formState.values || control._formValues, false, _defaultValue.current)),
|
327
|
+
}), [name, control, disabled, exact]);
|
384
328
|
React__default.useEffect(() => control._removeUnmounted());
|
385
329
|
return value;
|
386
330
|
}
|
@@ -411,13 +355,12 @@ function useWatch(props) {
|
|
411
355
|
*/
|
412
356
|
function useController(props) {
|
413
357
|
const methods = useFormContext();
|
414
|
-
const { name, disabled, control = methods.control, shouldUnregister
|
358
|
+
const { name, disabled, control = methods.control, shouldUnregister } = props;
|
415
359
|
const isArrayField = isNameInFieldArray(control._names.array, name);
|
416
|
-
const defaultValueMemo = React__default.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
417
360
|
const value = useWatch({
|
418
361
|
control,
|
419
362
|
name,
|
420
|
-
defaultValue:
|
363
|
+
defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
|
421
364
|
exact: true,
|
422
365
|
});
|
423
366
|
const formState = useFormState({
|
@@ -431,7 +374,6 @@ function useController(props) {
|
|
431
374
|
value,
|
432
375
|
...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
|
433
376
|
}));
|
434
|
-
_props.current = props;
|
435
377
|
const fieldState = React__default.useMemo(() => Object.defineProperties({}, {
|
436
378
|
invalid: {
|
437
379
|
enumerable: true,
|
@@ -471,7 +413,12 @@ function useController(props) {
|
|
471
413
|
const ref = React__default.useCallback((elm) => {
|
472
414
|
const field = get(control._fields, name);
|
473
415
|
if (field && elm) {
|
474
|
-
field._f.ref =
|
416
|
+
field._f.ref = {
|
417
|
+
focus: () => elm.focus && elm.focus(),
|
418
|
+
select: () => elm.select && elm.select(),
|
419
|
+
setCustomValidity: (message) => elm.setCustomValidity(message),
|
420
|
+
reportValidity: () => elm.reportValidity(),
|
421
|
+
};
|
475
422
|
}
|
476
423
|
}, [control._fields, name]);
|
477
424
|
const field = React__default.useMemo(() => ({
|
@@ -727,6 +674,39 @@ var createSubject = () => {
|
|
727
674
|
};
|
728
675
|
};
|
729
676
|
|
677
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
678
|
+
|
679
|
+
function deepEqual(object1, object2) {
|
680
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
681
|
+
return object1 === object2;
|
682
|
+
}
|
683
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
684
|
+
return object1.getTime() === object2.getTime();
|
685
|
+
}
|
686
|
+
const keys1 = Object.keys(object1);
|
687
|
+
const keys2 = Object.keys(object2);
|
688
|
+
if (keys1.length !== keys2.length) {
|
689
|
+
return false;
|
690
|
+
}
|
691
|
+
for (const key of keys1) {
|
692
|
+
const val1 = object1[key];
|
693
|
+
if (!keys2.includes(key)) {
|
694
|
+
return false;
|
695
|
+
}
|
696
|
+
if (key !== 'ref') {
|
697
|
+
const val2 = object2[key];
|
698
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
699
|
+
(isObject(val1) && isObject(val2)) ||
|
700
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
701
|
+
? !deepEqual(val1, val2)
|
702
|
+
: val1 !== val2) {
|
703
|
+
return false;
|
704
|
+
}
|
705
|
+
}
|
706
|
+
}
|
707
|
+
return true;
|
708
|
+
}
|
709
|
+
|
730
710
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
731
711
|
|
732
712
|
var isFileInput = (element) => element.type === 'file';
|
@@ -1012,6 +992,12 @@ function schemaErrorLookup(errors, _fields, name) {
|
|
1012
992
|
error: foundError,
|
1013
993
|
};
|
1014
994
|
}
|
995
|
+
if (foundError && foundError.root && foundError.root.type) {
|
996
|
+
return {
|
997
|
+
name: `${fieldName}.root`,
|
998
|
+
error: foundError.root,
|
999
|
+
};
|
1000
|
+
}
|
1015
1001
|
names.pop();
|
1016
1002
|
}
|
1017
1003
|
return {
|
@@ -1290,7 +1276,7 @@ function createFormControl(props = {}) {
|
|
1290
1276
|
};
|
1291
1277
|
const _fields = {};
|
1292
1278
|
let _defaultValues = isObject(_options.defaultValues) || isObject(_options.values)
|
1293
|
-
? cloneObject(_options.
|
1279
|
+
? cloneObject(_options.defaultValues || _options.values) || {}
|
1294
1280
|
: {};
|
1295
1281
|
let _formValues = _options.shouldUnregister
|
1296
1282
|
? {}
|
@@ -1325,8 +1311,6 @@ function createFormControl(props = {}) {
|
|
1325
1311
|
array: createSubject(),
|
1326
1312
|
state: createSubject(),
|
1327
1313
|
};
|
1328
|
-
const validationModeBeforeSubmit = getValidationModes(_options.mode);
|
1329
|
-
const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
1330
1314
|
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
1331
1315
|
const debounce = (callback) => (wait) => {
|
1332
1316
|
clearTimeout(timer);
|
@@ -1597,13 +1581,17 @@ function createFormControl(props = {}) {
|
|
1597
1581
|
}
|
1598
1582
|
else if (fieldReference.refs) {
|
1599
1583
|
if (isCheckBoxInput(fieldReference.ref)) {
|
1600
|
-
fieldReference.refs.
|
1601
|
-
|
1602
|
-
(
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1584
|
+
fieldReference.refs.forEach((checkboxRef) => {
|
1585
|
+
if (!checkboxRef.defaultChecked || !checkboxRef.disabled) {
|
1586
|
+
if (Array.isArray(fieldValue)) {
|
1587
|
+
checkboxRef.checked = !!fieldValue.find((data) => data === checkboxRef.value);
|
1588
|
+
}
|
1589
|
+
else {
|
1590
|
+
checkboxRef.checked =
|
1591
|
+
fieldValue === checkboxRef.value || !!fieldValue;
|
1592
|
+
}
|
1593
|
+
}
|
1594
|
+
});
|
1607
1595
|
}
|
1608
1596
|
else {
|
1609
1597
|
fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
|
@@ -1629,8 +1617,11 @@ function createFormControl(props = {}) {
|
|
1629
1617
|
};
|
1630
1618
|
const setValues = (name, value, options) => {
|
1631
1619
|
for (const fieldKey in value) {
|
1620
|
+
if (!value.hasOwnProperty(fieldKey)) {
|
1621
|
+
return;
|
1622
|
+
}
|
1632
1623
|
const fieldValue = value[fieldKey];
|
1633
|
-
const fieldName =
|
1624
|
+
const fieldName = name + '.' + fieldKey;
|
1634
1625
|
const field = get(_fields, fieldName);
|
1635
1626
|
(_names.array.has(name) ||
|
1636
1627
|
isObject(fieldValue) ||
|
@@ -1685,6 +1676,8 @@ function createFormControl(props = {}) {
|
|
1685
1676
|
(isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
|
1686
1677
|
deepEqual(fieldValue, get(_formValues, name, fieldValue));
|
1687
1678
|
};
|
1679
|
+
const validationModeBeforeSubmit = getValidationModes(_options.mode);
|
1680
|
+
const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
1688
1681
|
if (field) {
|
1689
1682
|
let error;
|
1690
1683
|
let isValid;
|
@@ -2227,6 +2220,7 @@ function createFormControl(props = {}) {
|
|
2227
2220
|
setError,
|
2228
2221
|
_subscribe,
|
2229
2222
|
_runSchema,
|
2223
|
+
_focusError,
|
2230
2224
|
_getWatch,
|
2231
2225
|
_getDirty,
|
2232
2226
|
_setValid,
|
@@ -2404,22 +2398,24 @@ function useFieldArray(props) {
|
|
2404
2398
|
const [fields, setFields] = React__default.useState(control._getFieldArray(name));
|
2405
2399
|
const ids = React__default.useRef(control._getFieldArray(name).map(generateId));
|
2406
2400
|
const _fieldIds = React__default.useRef(fields);
|
2401
|
+
const _name = React__default.useRef(name);
|
2407
2402
|
const _actioned = React__default.useRef(false);
|
2403
|
+
_name.current = name;
|
2408
2404
|
_fieldIds.current = fields;
|
2409
2405
|
control._names.array.add(name);
|
2410
|
-
|
2411
|
-
control.register(name, rules)
|
2412
|
-
useEffect(() => control._subjects.array.subscribe({
|
2406
|
+
rules &&
|
2407
|
+
control.register(name, rules);
|
2408
|
+
React__default.useEffect(() => control._subjects.array.subscribe({
|
2413
2409
|
next: ({ values, name: fieldArrayName, }) => {
|
2414
|
-
if (fieldArrayName ===
|
2415
|
-
const fieldValues = get(values,
|
2410
|
+
if (fieldArrayName === _name.current || !fieldArrayName) {
|
2411
|
+
const fieldValues = get(values, _name.current);
|
2416
2412
|
if (Array.isArray(fieldValues)) {
|
2417
2413
|
setFields(fieldValues);
|
2418
2414
|
ids.current = fieldValues.map(generateId);
|
2419
2415
|
}
|
2420
2416
|
}
|
2421
2417
|
},
|
2422
|
-
}).unsubscribe, [control
|
2418
|
+
}).unsubscribe, [control]);
|
2423
2419
|
const updateValues = React__default.useCallback((updatedFieldArrayValues) => {
|
2424
2420
|
_actioned.current = true;
|
2425
2421
|
control._setFieldArray(name, updatedFieldArrayValues);
|
@@ -2599,7 +2595,6 @@ function useFieldArray(props) {
|
|
2599
2595
|
};
|
2600
2596
|
}
|
2601
2597
|
|
2602
|
-
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React__default.useLayoutEffect : React__default.useEffect;
|
2603
2598
|
/**
|
2604
2599
|
* Custom hook to manage the entire form.
|
2605
2600
|
*
|
@@ -2685,10 +2680,13 @@ function useForm(props = {}) {
|
|
2685
2680
|
if (props.reValidateMode) {
|
2686
2681
|
control._options.reValidateMode = props.reValidateMode;
|
2687
2682
|
}
|
2688
|
-
|
2683
|
+
}, [control, props.mode, props.reValidateMode]);
|
2684
|
+
React__default.useEffect(() => {
|
2685
|
+
if (props.errors) {
|
2689
2686
|
control._setErrors(props.errors);
|
2687
|
+
control._focusError();
|
2690
2688
|
}
|
2691
|
-
}, [control, props.errors
|
2689
|
+
}, [control, props.errors]);
|
2692
2690
|
React__default.useEffect(() => {
|
2693
2691
|
props.shouldUnregister &&
|
2694
2692
|
control._subjects.state.next({
|