react-hook-form 7.40.0-next.1 → 7.40.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/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 +75 -109
- 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/getProxyFormState.d.ts +1 -1
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/types/form.d.ts +6 -10
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/path/eager.d.ts +3 -3
- package/dist/types/path/eager.d.ts.map +1 -1
- package/dist/types/utils.d.ts +0 -1
- package/dist/types/utils.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.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 +4 -4
package/dist/index.esm.mjs
CHANGED
@@ -122,7 +122,10 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
122
122
|
* }
|
123
123
|
* ```
|
124
124
|
*/
|
125
|
-
const FormProvider = (
|
125
|
+
const FormProvider = (props) => {
|
126
|
+
const { children, ...data } = props;
|
127
|
+
return (React.createElement(HookFormContext.Provider, { value: data }, children));
|
128
|
+
};
|
126
129
|
|
127
130
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
128
131
|
const result = {
|
@@ -170,7 +173,7 @@ function useSubscribe(props) {
|
|
170
173
|
React.useEffect(() => {
|
171
174
|
const subscription = !props.disabled &&
|
172
175
|
_props.current.subject.subscribe({
|
173
|
-
next: _props.current.
|
176
|
+
next: _props.current.callback,
|
174
177
|
});
|
175
178
|
return () => {
|
176
179
|
subscription && subscription.unsubscribe();
|
@@ -225,13 +228,13 @@ function useFormState(props) {
|
|
225
228
|
_name.current = name;
|
226
229
|
useSubscribe({
|
227
230
|
disabled,
|
228
|
-
|
231
|
+
callback: React.useCallback((value) => _mounted.current &&
|
229
232
|
shouldSubscribeByName(_name.current, value.name, exact) &&
|
230
233
|
shouldRenderFormState(value, _localProxyFormState.current) &&
|
231
234
|
updateFormState({
|
232
235
|
...control._formState,
|
233
236
|
...value,
|
234
|
-
}),
|
237
|
+
}), [control, exact]),
|
235
238
|
subject: control._subjects.state,
|
236
239
|
});
|
237
240
|
React.useEffect(() => {
|
@@ -260,7 +263,7 @@ var generateWatchOutput = (names, _names, formValues, isGlobal) => {
|
|
260
263
|
if (Array.isArray(names)) {
|
261
264
|
return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)));
|
262
265
|
}
|
263
|
-
_names.watchAll =
|
266
|
+
isGlobal && (_names.watchAll = true);
|
264
267
|
return formValues;
|
265
268
|
};
|
266
269
|
|
@@ -324,14 +327,10 @@ function useWatch(props) {
|
|
324
327
|
useSubscribe({
|
325
328
|
disabled,
|
326
329
|
subject: control._subjects.watch,
|
327
|
-
|
330
|
+
callback: (formState) => {
|
328
331
|
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
329
332
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
330
|
-
updateValue(isUndefined(
|
331
|
-
? cloneObject(fieldValues)
|
332
|
-
: isUndefined(fieldValues)
|
333
|
-
? defaultValue
|
334
|
-
: fieldValues);
|
333
|
+
updateValue(isUndefined(fieldValues) ? defaultValue : cloneObject(fieldValues));
|
335
334
|
}
|
336
335
|
},
|
337
336
|
});
|
@@ -981,16 +980,17 @@ function useFieldArray(props) {
|
|
981
980
|
control._names.array.add(name);
|
982
981
|
props.rules &&
|
983
982
|
control.register(name, props.rules);
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
ids.current = fieldValues.map(generateId);
|
991
|
-
}
|
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);
|
992
989
|
}
|
993
|
-
}
|
990
|
+
}
|
991
|
+
}, []);
|
992
|
+
useSubscribe({
|
993
|
+
callback,
|
994
994
|
subject: control._subjects.array,
|
995
995
|
});
|
996
996
|
const updateValues = React.useCallback((updatedFieldArrayValues) => {
|
@@ -1115,7 +1115,7 @@ function useFieldArray(props) {
|
|
1115
1115
|
values: control._formValues,
|
1116
1116
|
});
|
1117
1117
|
control._names.focus &&
|
1118
|
-
focusFieldBy(control._fields, (key) => !!key && key.startsWith(control._names.focus));
|
1118
|
+
focusFieldBy(control._fields, (key) => !!key && key.startsWith(control._names.focus || ''));
|
1119
1119
|
control._names.focus = '';
|
1120
1120
|
control._proxyFormState.isValid && control._updateValid();
|
1121
1121
|
}, [fields, name, control]);
|
@@ -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
|
+
const ElementClass = owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement;
|
1209
|
+
return value instanceof ElementClass;
|
1210
1210
|
};
|
1211
1211
|
|
1212
1212
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
@@ -1391,7 +1391,6 @@ function createFormControl(props = {}) {
|
|
1391
1391
|
...defaultOptions,
|
1392
1392
|
...props,
|
1393
1393
|
};
|
1394
|
-
const shouldCaptureDirtyFields = props.resetOptions && props.resetOptions.keepDirtyValues;
|
1395
1394
|
let _formState = {
|
1396
1395
|
submitCount: 0,
|
1397
1396
|
isDirty: false,
|
@@ -1405,9 +1404,7 @@ function createFormControl(props = {}) {
|
|
1405
1404
|
errors: {},
|
1406
1405
|
};
|
1407
1406
|
let _fields = {};
|
1408
|
-
let _defaultValues =
|
1409
|
-
? cloneObject(_options.defaultValues) || {}
|
1410
|
-
: {};
|
1407
|
+
let _defaultValues = cloneObject(_options.defaultValues) || {};
|
1411
1408
|
let _formValues = _options.shouldUnregister
|
1412
1409
|
? {}
|
1413
1410
|
: cloneObject(_defaultValues);
|
@@ -1424,7 +1421,6 @@ function createFormControl(props = {}) {
|
|
1424
1421
|
};
|
1425
1422
|
let delayErrorCallback;
|
1426
1423
|
let timer = 0;
|
1427
|
-
let validateFields = {};
|
1428
1424
|
const _proxyFormState = {
|
1429
1425
|
isDirty: false,
|
1430
1426
|
dirtyFields: false,
|
@@ -1449,7 +1445,7 @@ function createFormControl(props = {}) {
|
|
1449
1445
|
if (_proxyFormState.isValid) {
|
1450
1446
|
const isValid = _options.resolver
|
1451
1447
|
? isEmptyObject((await _executeSchema()).errors)
|
1452
|
-
:
|
1448
|
+
: await executeBuiltInValidation(_fields, true);
|
1453
1449
|
if (isValid !== _formState.isValid) {
|
1454
1450
|
_formState.isValid = isValid;
|
1455
1451
|
_subjects.state.next({
|
@@ -1458,6 +1454,11 @@ function createFormControl(props = {}) {
|
|
1458
1454
|
}
|
1459
1455
|
}
|
1460
1456
|
};
|
1457
|
+
const _updateIsValidating = (value) => _proxyFormState.isValidating &&
|
1458
|
+
value !== _formState.isValidating &&
|
1459
|
+
_subjects.state.next({
|
1460
|
+
isValidating: value,
|
1461
|
+
});
|
1461
1462
|
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
1462
1463
|
if (args && method) {
|
1463
1464
|
_stateFlags.action = true;
|
@@ -1481,6 +1482,7 @@ function createFormControl(props = {}) {
|
|
1481
1482
|
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
1482
1483
|
}
|
1483
1484
|
_subjects.state.next({
|
1485
|
+
name,
|
1484
1486
|
isDirty: _getDirty(name, values),
|
1485
1487
|
dirtyFields: _formState.dirtyFields,
|
1486
1488
|
errors: _formState.errors,
|
@@ -1515,22 +1517,22 @@ function createFormControl(props = {}) {
|
|
1515
1517
|
const output = {
|
1516
1518
|
name,
|
1517
1519
|
};
|
1518
|
-
if (_proxyFormState.isDirty) {
|
1519
|
-
isPreviousDirty = _formState.isDirty;
|
1520
|
-
_formState.isDirty = output.isDirty = _getDirty();
|
1521
|
-
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
1522
|
-
}
|
1523
1520
|
if (!isBlurEvent || shouldDirty) {
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1521
|
+
if (_proxyFormState.isDirty) {
|
1522
|
+
isPreviousDirty = _formState.isDirty;
|
1523
|
+
_formState.isDirty = output.isDirty = _getDirty();
|
1524
|
+
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
1525
|
+
}
|
1526
|
+
if (_proxyFormState.dirtyFields) {
|
1527
|
+
isPreviousDirty = get(_formState.dirtyFields, name);
|
1528
|
+
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
1529
|
+
isCurrentFieldPristine
|
1530
|
+
? unset(_formState.dirtyFields, name)
|
1531
|
+
: set(_formState.dirtyFields, name, true);
|
1532
|
+
output.dirtyFields = _formState.dirtyFields;
|
1533
|
+
shouldUpdateField =
|
1534
|
+
shouldUpdateField || isPreviousDirty !== !isCurrentFieldPristine;
|
1535
|
+
}
|
1534
1536
|
}
|
1535
1537
|
if (isBlurEvent) {
|
1536
1538
|
const isPreviousFieldTouched = get(_formState.touchedFields, name);
|
@@ -1577,18 +1579,9 @@ function createFormControl(props = {}) {
|
|
1577
1579
|
};
|
1578
1580
|
_subjects.state.next(updatedFormState);
|
1579
1581
|
}
|
1580
|
-
|
1581
|
-
if (_proxyFormState.isValidating &&
|
1582
|
-
!Object.values(validateFields).some((v) => v)) {
|
1583
|
-
_subjects.state.next({
|
1584
|
-
isValidating: false,
|
1585
|
-
});
|
1586
|
-
validateFields = {};
|
1587
|
-
}
|
1582
|
+
_updateIsValidating(false);
|
1588
1583
|
};
|
1589
|
-
const _executeSchema = async (name) => _options.resolver
|
1590
|
-
? await _options.resolver({ ..._formValues }, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
|
1591
|
-
: {};
|
1584
|
+
const _executeSchema = async (name) => await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
|
1592
1585
|
const executeSchemaAndUpdateState = async (names) => {
|
1593
1586
|
const { errors } = await _executeSchema();
|
1594
1587
|
if (names) {
|
@@ -1615,9 +1608,6 @@ function createFormControl(props = {}) {
|
|
1615
1608
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
1616
1609
|
const fieldError = await validateField(field, get(_formValues, _f.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
|
1617
1610
|
if (fieldError[_f.name]) {
|
1618
|
-
if (_f.name === context.name) {
|
1619
|
-
context.error = fieldError[context.name];
|
1620
|
-
}
|
1621
1611
|
context.valid = false;
|
1622
1612
|
if (shouldOnlyCheckValid) {
|
1623
1613
|
break;
|
@@ -1634,7 +1624,7 @@ function createFormControl(props = {}) {
|
|
1634
1624
|
(await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
|
1635
1625
|
}
|
1636
1626
|
}
|
1637
|
-
return context;
|
1627
|
+
return context.valid;
|
1638
1628
|
};
|
1639
1629
|
const _removeUnmounted = () => {
|
1640
1630
|
for (const name of _names.unMount) {
|
@@ -1703,8 +1693,7 @@ function createFormControl(props = {}) {
|
|
1703
1693
|
}
|
1704
1694
|
(options.shouldDirty || options.shouldTouch) &&
|
1705
1695
|
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
|
1706
|
-
options.shouldValidate &&
|
1707
|
-
trigger(name);
|
1696
|
+
options.shouldValidate && trigger(name);
|
1708
1697
|
};
|
1709
1698
|
const setValues = (name, value, options) => {
|
1710
1699
|
for (const fieldKey in value) {
|
@@ -1753,12 +1742,11 @@ function createFormControl(props = {}) {
|
|
1753
1742
|
const target = event.target;
|
1754
1743
|
let name = target.name;
|
1755
1744
|
const field = get(_fields, name);
|
1745
|
+
const getCurrentFieldValue = () => target.type ? getFieldValue(field._f) : getEventValue(event);
|
1756
1746
|
if (field) {
|
1757
1747
|
let error;
|
1758
1748
|
let isValid;
|
1759
|
-
const fieldValue =
|
1760
|
-
? getFieldValue(field._f)
|
1761
|
-
: getEventValue(event);
|
1749
|
+
const fieldValue = getCurrentFieldValue();
|
1762
1750
|
const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
|
1763
1751
|
const shouldSkipValidation = (!hasValidation(field._f) &&
|
1764
1752
|
!_options.resolver &&
|
@@ -1787,12 +1775,7 @@ function createFormControl(props = {}) {
|
|
1787
1775
|
_subjects.state.next({ name, ...(watched ? {} : fieldState) }));
|
1788
1776
|
}
|
1789
1777
|
!isBlurEvent && watched && _subjects.state.next({});
|
1790
|
-
|
1791
|
-
? validateFields[name] + 1
|
1792
|
-
: 1;
|
1793
|
-
_subjects.state.next({
|
1794
|
-
isValidating: true,
|
1795
|
-
});
|
1778
|
+
_updateIsValidating(true);
|
1796
1779
|
if (_options.resolver) {
|
1797
1780
|
const { errors } = await _executeSchema([name]);
|
1798
1781
|
const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
|
@@ -1802,30 +1785,29 @@ function createFormControl(props = {}) {
|
|
1802
1785
|
isValid = isEmptyObject(errors);
|
1803
1786
|
}
|
1804
1787
|
else {
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
valid: true,
|
1809
|
-
});
|
1810
|
-
error = buildInValidationResult.error || {};
|
1811
|
-
isValid = buildInValidationResult.valid;
|
1788
|
+
error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1789
|
+
if (error) {
|
1790
|
+
isValid = false;
|
1812
1791
|
}
|
1813
|
-
if (
|
1814
|
-
|
1792
|
+
else if (_proxyFormState.isValid) {
|
1793
|
+
isValid = await executeBuiltInValidation(_fields, true);
|
1815
1794
|
}
|
1816
1795
|
}
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1796
|
+
if (!isPrimitive(fieldValue) || getCurrentFieldValue() === fieldValue) {
|
1797
|
+
field._f.deps &&
|
1798
|
+
trigger(field._f.deps);
|
1799
|
+
shouldRenderByError(name, isValid, error, fieldState);
|
1800
|
+
}
|
1801
|
+
else {
|
1802
|
+
_updateIsValidating(false);
|
1803
|
+
}
|
1820
1804
|
}
|
1821
1805
|
};
|
1822
1806
|
const trigger = async (name, options = {}) => {
|
1823
1807
|
let isValid;
|
1824
1808
|
let validationResult;
|
1825
1809
|
const fieldNames = convertToArrayPayload(name);
|
1826
|
-
|
1827
|
-
isValidating: true,
|
1828
|
-
});
|
1810
|
+
_updateIsValidating(true);
|
1829
1811
|
if (_options.resolver) {
|
1830
1812
|
const errors = await executeSchemaAndUpdateState(isUndefined(name) ? name : fieldNames);
|
1831
1813
|
isValid = isEmptyObject(errors);
|
@@ -1836,13 +1818,12 @@ function createFormControl(props = {}) {
|
|
1836
1818
|
else if (name) {
|
1837
1819
|
validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
|
1838
1820
|
const field = get(_fields, fieldName);
|
1839
|
-
return
|
1821
|
+
return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
|
1840
1822
|
}))).every(Boolean);
|
1841
1823
|
!(!validationResult && !_formState.isValid) && _updateValid();
|
1842
1824
|
}
|
1843
1825
|
else {
|
1844
|
-
validationResult = isValid =
|
1845
|
-
.valid;
|
1826
|
+
validationResult = isValid = await executeBuiltInValidation(_fields);
|
1846
1827
|
}
|
1847
1828
|
_subjects.state.next({
|
1848
1829
|
...(!isString(name) ||
|
@@ -1898,7 +1879,7 @@ function createFormControl(props = {}) {
|
|
1898
1879
|
};
|
1899
1880
|
const watch = (name, defaultValue) => isFunction(name)
|
1900
1881
|
? _subjects.watch.subscribe({
|
1901
|
-
next: (
|
1882
|
+
next: (payload) => name(_getWatch(undefined, defaultValue), payload),
|
1902
1883
|
})
|
1903
1884
|
: _getWatch(name, defaultValue, true);
|
1904
1885
|
const unregister = (name, options = {}) => {
|
@@ -1983,9 +1964,7 @@ function createFormControl(props = {}) {
|
|
1983
1964
|
refs: [
|
1984
1965
|
...refs.filter(live),
|
1985
1966
|
fieldRef,
|
1986
|
-
...(
|
1987
|
-
? [{}]
|
1988
|
-
: []),
|
1967
|
+
...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
|
1989
1968
|
],
|
1990
1969
|
ref: { type: fieldRef.type, name },
|
1991
1970
|
}
|
@@ -2091,7 +2070,7 @@ function createFormControl(props = {}) {
|
|
2091
2070
|
_defaultValues = updatedValues;
|
2092
2071
|
}
|
2093
2072
|
if (!keepStateOptions.keepValues) {
|
2094
|
-
if (keepStateOptions.keepDirtyValues
|
2073
|
+
if (keepStateOptions.keepDirtyValues) {
|
2095
2074
|
for (const fieldName of _names.mount) {
|
2096
2075
|
get(_formState.dirtyFields, fieldName)
|
2097
2076
|
? set(values, fieldName, get(_formValues, fieldName))
|
@@ -2181,11 +2160,6 @@ function createFormControl(props = {}) {
|
|
2181
2160
|
}
|
2182
2161
|
}
|
2183
2162
|
};
|
2184
|
-
if (isFunction(_options.defaultValues)) {
|
2185
|
-
_options.defaultValues().then((values) => {
|
2186
|
-
reset(values, _options.resetOptions);
|
2187
|
-
});
|
2188
|
-
}
|
2189
2163
|
return {
|
2190
2164
|
control: {
|
2191
2165
|
register,
|
@@ -2199,7 +2173,6 @@ function createFormControl(props = {}) {
|
|
2199
2173
|
_removeUnmounted,
|
2200
2174
|
_updateFieldArray,
|
2201
2175
|
_getFieldArray,
|
2202
|
-
_reset,
|
2203
2176
|
_subjects,
|
2204
2177
|
_proxyFormState,
|
2205
2178
|
get _fields() {
|
@@ -2297,9 +2270,7 @@ function useForm(props = {}) {
|
|
2297
2270
|
dirtyFields: {},
|
2298
2271
|
touchedFields: {},
|
2299
2272
|
errors: {},
|
2300
|
-
defaultValues:
|
2301
|
-
? undefined
|
2302
|
-
: props.defaultValues,
|
2273
|
+
defaultValues: props.defaultValues,
|
2303
2274
|
});
|
2304
2275
|
if (!_formControl.current) {
|
2305
2276
|
_formControl.current = {
|
@@ -2311,7 +2282,7 @@ function useForm(props = {}) {
|
|
2311
2282
|
control._options = props;
|
2312
2283
|
useSubscribe({
|
2313
2284
|
subject: control._subjects.state,
|
2314
|
-
|
2285
|
+
callback: React.useCallback((value) => {
|
2315
2286
|
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2316
2287
|
control._formState = {
|
2317
2288
|
...control._formState,
|
@@ -2319,7 +2290,7 @@ function useForm(props = {}) {
|
|
2319
2290
|
};
|
2320
2291
|
updateFormState({ ...control._formState });
|
2321
2292
|
}
|
2322
|
-
},
|
2293
|
+
}, [control]),
|
2323
2294
|
});
|
2324
2295
|
React.useEffect(() => {
|
2325
2296
|
if (!control._stateFlags.mount) {
|
@@ -2332,11 +2303,6 @@ function useForm(props = {}) {
|
|
2332
2303
|
}
|
2333
2304
|
control._removeUnmounted();
|
2334
2305
|
});
|
2335
|
-
React.useEffect(() => {
|
2336
|
-
if (props.values && !deepEqual(props.values, control._defaultValues)) {
|
2337
|
-
control._reset(props.values, control._options.resetOptions);
|
2338
|
-
}
|
2339
|
-
}, [props.values, control]);
|
2340
2306
|
React.useEffect(() => {
|
2341
2307
|
formState.submitCount && control._focusError();
|
2342
2308
|
}, [control, formState.submitCount]);
|