react-hook-form 7.39.5 → 7.40.0-next.1
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 +69 -39
- 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/types/form.d.ts +8 -4
- 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 +1 -0
- 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 +2 -2
package/dist/index.esm.mjs
CHANGED
@@ -122,10 +122,7 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
122
122
|
* }
|
123
123
|
* ```
|
124
124
|
*/
|
125
|
-
const FormProvider = (
|
126
|
-
const { children, ...data } = props;
|
127
|
-
return (React.createElement(HookFormContext.Provider, { value: data }, children));
|
128
|
-
};
|
125
|
+
const FormProvider = ({ children, ...data }) => (React.createElement(HookFormContext.Provider, { value: React.useState(data)[0] }, children));
|
129
126
|
|
130
127
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
131
128
|
const result = {
|
@@ -173,7 +170,7 @@ function useSubscribe(props) {
|
|
173
170
|
React.useEffect(() => {
|
174
171
|
const subscription = !props.disabled &&
|
175
172
|
_props.current.subject.subscribe({
|
176
|
-
next: _props.current.
|
173
|
+
next: _props.current.next,
|
177
174
|
});
|
178
175
|
return () => {
|
179
176
|
subscription && subscription.unsubscribe();
|
@@ -228,13 +225,13 @@ function useFormState(props) {
|
|
228
225
|
_name.current = name;
|
229
226
|
useSubscribe({
|
230
227
|
disabled,
|
231
|
-
|
228
|
+
next: (value) => _mounted.current &&
|
232
229
|
shouldSubscribeByName(_name.current, value.name, exact) &&
|
233
230
|
shouldRenderFormState(value, _localProxyFormState.current) &&
|
234
231
|
updateFormState({
|
235
232
|
...control._formState,
|
236
233
|
...value,
|
237
|
-
}),
|
234
|
+
}),
|
238
235
|
subject: control._subjects.state,
|
239
236
|
});
|
240
237
|
React.useEffect(() => {
|
@@ -327,10 +324,14 @@ function useWatch(props) {
|
|
327
324
|
useSubscribe({
|
328
325
|
disabled,
|
329
326
|
subject: control._subjects.watch,
|
330
|
-
|
327
|
+
next: (formState) => {
|
331
328
|
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
332
329
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
333
|
-
updateValue(isUndefined(
|
330
|
+
updateValue(isUndefined(_name.current) || !isUndefined(fieldValues)
|
331
|
+
? cloneObject(fieldValues)
|
332
|
+
: isUndefined(fieldValues)
|
333
|
+
? defaultValue
|
334
|
+
: fieldValues);
|
334
335
|
}
|
335
336
|
},
|
336
337
|
});
|
@@ -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`;
|
@@ -1391,6 +1391,7 @@ function createFormControl(props = {}) {
|
|
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,
|
@@ -1404,7 +1405,9 @@ function createFormControl(props = {}) {
|
|
1404
1405
|
errors: {},
|
1405
1406
|
};
|
1406
1407
|
let _fields = {};
|
1407
|
-
let _defaultValues =
|
1408
|
+
let _defaultValues = isObject(_options.defaultValues)
|
1409
|
+
? cloneObject(_options.defaultValues) || {}
|
1410
|
+
: {};
|
1408
1411
|
let _formValues = _options.shouldUnregister
|
1409
1412
|
? {}
|
1410
1413
|
: cloneObject(_defaultValues);
|
@@ -1443,11 +1446,10 @@ function createFormControl(props = {}) {
|
|
1443
1446
|
timer = window.setTimeout(callback, wait);
|
1444
1447
|
};
|
1445
1448
|
const _updateValid = async () => {
|
1446
|
-
let isValid = false;
|
1447
1449
|
if (_proxyFormState.isValid) {
|
1448
|
-
isValid = _options.resolver
|
1450
|
+
const isValid = _options.resolver
|
1449
1451
|
? isEmptyObject((await _executeSchema()).errors)
|
1450
|
-
: await executeBuiltInValidation(_fields, true);
|
1452
|
+
: (await executeBuiltInValidation(_fields, true)).valid;
|
1451
1453
|
if (isValid !== _formState.isValid) {
|
1452
1454
|
_formState.isValid = isValid;
|
1453
1455
|
_subjects.state.next({
|
@@ -1455,7 +1457,6 @@ function createFormControl(props = {}) {
|
|
1455
1457
|
});
|
1456
1458
|
}
|
1457
1459
|
}
|
1458
|
-
return isValid;
|
1459
1460
|
};
|
1460
1461
|
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
1461
1462
|
if (args && method) {
|
@@ -1519,15 +1520,17 @@ function createFormControl(props = {}) {
|
|
1519
1520
|
_formState.isDirty = output.isDirty = _getDirty();
|
1520
1521
|
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
1521
1522
|
}
|
1522
|
-
if (
|
1523
|
-
isPreviousDirty = get(_formState.dirtyFields, name);
|
1523
|
+
if (!isBlurEvent || shouldDirty) {
|
1524
1524
|
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
1525
|
+
isPreviousDirty = get(_formState.dirtyFields, name);
|
1525
1526
|
isCurrentFieldPristine
|
1526
1527
|
? unset(_formState.dirtyFields, name)
|
1527
1528
|
: set(_formState.dirtyFields, name, true);
|
1528
1529
|
output.dirtyFields = _formState.dirtyFields;
|
1529
1530
|
shouldUpdateField =
|
1530
|
-
shouldUpdateField ||
|
1531
|
+
shouldUpdateField ||
|
1532
|
+
(_proxyFormState.dirtyFields &&
|
1533
|
+
isPreviousDirty !== !isCurrentFieldPristine);
|
1531
1534
|
}
|
1532
1535
|
if (isBlurEvent) {
|
1533
1536
|
const isPreviousFieldTouched = get(_formState.touchedFields, name);
|
@@ -1612,6 +1615,9 @@ function createFormControl(props = {}) {
|
|
1612
1615
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
1613
1616
|
const fieldError = await validateField(field, get(_formValues, _f.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
|
1614
1617
|
if (fieldError[_f.name]) {
|
1618
|
+
if (_f.name === context.name) {
|
1619
|
+
context.error = fieldError[context.name];
|
1620
|
+
}
|
1615
1621
|
context.valid = false;
|
1616
1622
|
if (shouldOnlyCheckValid) {
|
1617
1623
|
break;
|
@@ -1628,7 +1634,7 @@ function createFormControl(props = {}) {
|
|
1628
1634
|
(await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
|
1629
1635
|
}
|
1630
1636
|
}
|
1631
|
-
return context
|
1637
|
+
return context;
|
1632
1638
|
};
|
1633
1639
|
const _removeUnmounted = () => {
|
1634
1640
|
for (const name of _names.unMount) {
|
@@ -1697,7 +1703,8 @@ function createFormControl(props = {}) {
|
|
1697
1703
|
}
|
1698
1704
|
(options.shouldDirty || options.shouldTouch) &&
|
1699
1705
|
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
|
1700
|
-
options.shouldValidate &&
|
1706
|
+
options.shouldValidate &&
|
1707
|
+
trigger(name);
|
1701
1708
|
};
|
1702
1709
|
const setValues = (name, value, options) => {
|
1703
1710
|
for (const fieldKey in value) {
|
@@ -1795,8 +1802,17 @@ function createFormControl(props = {}) {
|
|
1795
1802
|
isValid = isEmptyObject(errors);
|
1796
1803
|
}
|
1797
1804
|
else {
|
1798
|
-
|
1799
|
-
|
1805
|
+
if (_proxyFormState.isValid) {
|
1806
|
+
const buildInValidationResult = await executeBuiltInValidation(_fields, true, {
|
1807
|
+
name,
|
1808
|
+
valid: true,
|
1809
|
+
});
|
1810
|
+
error = buildInValidationResult.error || {};
|
1811
|
+
isValid = buildInValidationResult.valid;
|
1812
|
+
}
|
1813
|
+
if (!error || isEmptyObject(error)) {
|
1814
|
+
error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1815
|
+
}
|
1800
1816
|
}
|
1801
1817
|
field._f.deps &&
|
1802
1818
|
trigger(field._f.deps);
|
@@ -1820,12 +1836,13 @@ function createFormControl(props = {}) {
|
|
1820
1836
|
else if (name) {
|
1821
1837
|
validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
|
1822
1838
|
const field = get(_fields, fieldName);
|
1823
|
-
return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
|
1839
|
+
return (await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field)).valid;
|
1824
1840
|
}))).every(Boolean);
|
1825
1841
|
!(!validationResult && !_formState.isValid) && _updateValid();
|
1826
1842
|
}
|
1827
1843
|
else {
|
1828
|
-
validationResult = isValid = await executeBuiltInValidation(_fields)
|
1844
|
+
validationResult = isValid = (await executeBuiltInValidation(_fields))
|
1845
|
+
.valid;
|
1829
1846
|
}
|
1830
1847
|
_subjects.state.next({
|
1831
1848
|
...(!isString(name) ||
|
@@ -2074,7 +2091,7 @@ function createFormControl(props = {}) {
|
|
2074
2091
|
_defaultValues = updatedValues;
|
2075
2092
|
}
|
2076
2093
|
if (!keepStateOptions.keepValues) {
|
2077
|
-
if (keepStateOptions.keepDirtyValues) {
|
2094
|
+
if (keepStateOptions.keepDirtyValues || shouldCaptureDirtyFields) {
|
2078
2095
|
for (const fieldName of _names.mount) {
|
2079
2096
|
get(_formState.dirtyFields, fieldName)
|
2080
2097
|
? set(values, fieldName, get(_formValues, fieldName))
|
@@ -2164,6 +2181,11 @@ function createFormControl(props = {}) {
|
|
2164
2181
|
}
|
2165
2182
|
}
|
2166
2183
|
};
|
2184
|
+
if (isFunction(_options.defaultValues)) {
|
2185
|
+
_options.defaultValues().then((values) => {
|
2186
|
+
reset(values, _options.resetOptions);
|
2187
|
+
});
|
2188
|
+
}
|
2167
2189
|
return {
|
2168
2190
|
control: {
|
2169
2191
|
register,
|
@@ -2177,6 +2199,7 @@ function createFormControl(props = {}) {
|
|
2177
2199
|
_removeUnmounted,
|
2178
2200
|
_updateFieldArray,
|
2179
2201
|
_getFieldArray,
|
2202
|
+
_reset,
|
2180
2203
|
_subjects,
|
2181
2204
|
_proxyFormState,
|
2182
2205
|
get _fields() {
|
@@ -2274,7 +2297,9 @@ function useForm(props = {}) {
|
|
2274
2297
|
dirtyFields: {},
|
2275
2298
|
touchedFields: {},
|
2276
2299
|
errors: {},
|
2277
|
-
defaultValues: props.defaultValues
|
2300
|
+
defaultValues: isFunction(props.defaultValues)
|
2301
|
+
? undefined
|
2302
|
+
: props.defaultValues,
|
2278
2303
|
});
|
2279
2304
|
if (!_formControl.current) {
|
2280
2305
|
_formControl.current = {
|
@@ -2286,7 +2311,7 @@ function useForm(props = {}) {
|
|
2286
2311
|
control._options = props;
|
2287
2312
|
useSubscribe({
|
2288
2313
|
subject: control._subjects.state,
|
2289
|
-
|
2314
|
+
next: (value) => {
|
2290
2315
|
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2291
2316
|
control._formState = {
|
2292
2317
|
...control._formState,
|
@@ -2294,7 +2319,7 @@ function useForm(props = {}) {
|
|
2294
2319
|
};
|
2295
2320
|
updateFormState({ ...control._formState });
|
2296
2321
|
}
|
2297
|
-
},
|
2322
|
+
},
|
2298
2323
|
});
|
2299
2324
|
React.useEffect(() => {
|
2300
2325
|
if (!control._stateFlags.mount) {
|
@@ -2307,6 +2332,11 @@ function useForm(props = {}) {
|
|
2307
2332
|
}
|
2308
2333
|
control._removeUnmounted();
|
2309
2334
|
});
|
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]);
|
2310
2340
|
React.useEffect(() => {
|
2311
2341
|
formState.submitCount && control._focusError();
|
2312
2342
|
}, [control, formState.submitCount]);
|