react-hook-form 7.36.1 → 7.37.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 +3 -32
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +92 -98
- 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/focusFieldBy.d.ts.map +1 -1
- package/dist/logic/getProxyFormState.d.ts +2 -2
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +2 -2
- package/dist/types/form.d.ts +4 -3
- 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/useSubscribe.d.ts.map +1 -1
- package/dist/useWatch.d.ts +2 -2
- package/dist/useWatch.d.ts.map +1 -1
- package/dist/utils/cloneObject.d.ts.map +1 -1
- package/dist/utils/isPlainObject.d.ts +3 -0
- package/dist/utils/isPlainObject.d.ts.map +1 -0
- package/package.json +21 -28
package/dist/index.esm.mjs
CHANGED
@@ -127,14 +127,16 @@ const FormProvider = (props) => {
|
|
127
127
|
return (React.createElement(HookFormContext.Provider, { value: data }, children));
|
128
128
|
};
|
129
129
|
|
130
|
-
var getProxyFormState = (formState,
|
131
|
-
const result = {
|
130
|
+
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
131
|
+
const result = {
|
132
|
+
defaultValues: control._defaultValues,
|
133
|
+
};
|
132
134
|
for (const key in formState) {
|
133
135
|
Object.defineProperty(result, key, {
|
134
136
|
get: () => {
|
135
137
|
const _key = key;
|
136
|
-
if (_proxyFormState[_key] !== VALIDATION_MODE.all) {
|
137
|
-
_proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
|
138
|
+
if (control._proxyFormState[_key] !== VALIDATION_MODE.all) {
|
139
|
+
control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
|
138
140
|
}
|
139
141
|
localProxyFormState && (localProxyFormState[_key] = true);
|
140
142
|
return formState[_key];
|
@@ -169,16 +171,13 @@ function useSubscribe(props) {
|
|
169
171
|
const _props = React.useRef(props);
|
170
172
|
_props.current = props;
|
171
173
|
React.useEffect(() => {
|
172
|
-
const tearDown = (subscription) => {
|
173
|
-
if (subscription) {
|
174
|
-
subscription.unsubscribe();
|
175
|
-
}
|
176
|
-
};
|
177
174
|
const subscription = !props.disabled &&
|
178
175
|
_props.current.subject.subscribe({
|
179
176
|
next: _props.current.callback,
|
180
177
|
});
|
181
|
-
return () =>
|
178
|
+
return () => {
|
179
|
+
subscription && subscription.unsubscribe();
|
180
|
+
};
|
182
181
|
}, [props.disabled]);
|
183
182
|
}
|
184
183
|
|
@@ -216,6 +215,7 @@ function useFormState(props) {
|
|
216
215
|
const methods = useFormContext();
|
217
216
|
const { control = methods.control, disabled, name, exact } = props || {};
|
218
217
|
const [formState, updateFormState] = React.useState(control._formState);
|
218
|
+
const _mounted = React.useRef(true);
|
219
219
|
const _localProxyFormState = React.useRef({
|
220
220
|
isDirty: false,
|
221
221
|
dirtyFields: false,
|
@@ -225,18 +225,16 @@ function useFormState(props) {
|
|
225
225
|
errors: false,
|
226
226
|
});
|
227
227
|
const _name = React.useRef(name);
|
228
|
-
const _mounted = React.useRef(true);
|
229
228
|
_name.current = name;
|
230
|
-
const callback = React.useCallback((value) => _mounted.current &&
|
231
|
-
shouldSubscribeByName(_name.current, value.name, exact) &&
|
232
|
-
shouldRenderFormState(value, _localProxyFormState.current) &&
|
233
|
-
updateFormState({
|
234
|
-
...control._formState,
|
235
|
-
...value,
|
236
|
-
}), [control, exact]);
|
237
229
|
useSubscribe({
|
238
230
|
disabled,
|
239
|
-
callback
|
231
|
+
callback: React.useCallback((value) => _mounted.current &&
|
232
|
+
shouldSubscribeByName(_name.current, value.name, exact) &&
|
233
|
+
shouldRenderFormState(value, _localProxyFormState.current) &&
|
234
|
+
updateFormState({
|
235
|
+
...control._formState,
|
236
|
+
...value,
|
237
|
+
}), [control, exact]),
|
240
238
|
subject: control._subjects.state,
|
241
239
|
});
|
242
240
|
React.useEffect(() => {
|
@@ -245,7 +243,7 @@ function useFormState(props) {
|
|
245
243
|
_mounted.current = false;
|
246
244
|
};
|
247
245
|
}, []);
|
248
|
-
return getProxyFormState(formState, control
|
246
|
+
return getProxyFormState(formState, control, _localProxyFormState.current, false);
|
249
247
|
}
|
250
248
|
|
251
249
|
var isString = (value) => typeof value === 'string';
|
@@ -296,30 +294,27 @@ function useWatch(props) {
|
|
296
294
|
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
297
295
|
const _name = React.useRef(name);
|
298
296
|
_name.current = name;
|
299
|
-
const callback = React.useCallback((formState) => {
|
300
|
-
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
301
|
-
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
302
|
-
updateValue(isUndefined(_name.current) ||
|
303
|
-
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
304
|
-
? { ...fieldValues }
|
305
|
-
: Array.isArray(fieldValues)
|
306
|
-
? [...fieldValues]
|
307
|
-
: isUndefined(fieldValues)
|
308
|
-
? defaultValue
|
309
|
-
: fieldValues);
|
310
|
-
}
|
311
|
-
}, [control, exact, defaultValue]);
|
312
297
|
useSubscribe({
|
313
298
|
disabled,
|
314
299
|
subject: control._subjects.watch,
|
315
|
-
callback
|
300
|
+
callback: React.useCallback((formState) => {
|
301
|
+
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
302
|
+
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
303
|
+
updateValue(isUndefined(_name.current) ||
|
304
|
+
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
305
|
+
? { ...fieldValues }
|
306
|
+
: Array.isArray(fieldValues)
|
307
|
+
? [...fieldValues]
|
308
|
+
: isUndefined(fieldValues)
|
309
|
+
? defaultValue
|
310
|
+
: fieldValues);
|
311
|
+
}
|
312
|
+
}, [control, exact, defaultValue]),
|
316
313
|
});
|
317
314
|
const [value, updateValue] = React.useState(isUndefined(defaultValue)
|
318
315
|
? control._getWatch(name)
|
319
316
|
: defaultValue);
|
320
|
-
React.useEffect(() =>
|
321
|
-
control._removeUnmounted();
|
322
|
-
});
|
317
|
+
React.useEffect(() => control._removeUnmounted());
|
323
318
|
return value;
|
324
319
|
}
|
325
320
|
|
@@ -386,27 +381,23 @@ function useController(props) {
|
|
386
381
|
field: {
|
387
382
|
name,
|
388
383
|
value,
|
389
|
-
onChange: React.useCallback((event) => {
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
type: EVENTS.BLUR,
|
405
|
-
});
|
406
|
-
}, [name, control]),
|
407
|
-
ref: React.useCallback((elm) => {
|
384
|
+
onChange: React.useCallback((event) => _registerProps.current.onChange({
|
385
|
+
target: {
|
386
|
+
value: getEventValue(event),
|
387
|
+
name: name,
|
388
|
+
},
|
389
|
+
type: EVENTS.CHANGE,
|
390
|
+
}), [name]),
|
391
|
+
onBlur: React.useCallback(() => _registerProps.current.onBlur({
|
392
|
+
target: {
|
393
|
+
value: get(control._formValues, name),
|
394
|
+
name: name,
|
395
|
+
},
|
396
|
+
type: EVENTS.BLUR,
|
397
|
+
}), [name, control]),
|
398
|
+
ref: (elm) => {
|
408
399
|
const field = get(control._fields, name);
|
409
|
-
if (
|
400
|
+
if (field && elm) {
|
410
401
|
field._f.ref = {
|
411
402
|
focus: () => elm.focus(),
|
412
403
|
select: () => elm.select(),
|
@@ -414,7 +405,7 @@ function useController(props) {
|
|
414
405
|
reportValidity: () => elm.reportValidity(),
|
415
406
|
};
|
416
407
|
}
|
417
|
-
},
|
408
|
+
},
|
418
409
|
},
|
419
410
|
formState,
|
420
411
|
fieldState: Object.defineProperties({}, {
|
@@ -525,10 +516,11 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
525
516
|
if (field) {
|
526
517
|
const { _f, ...currentField } = field;
|
527
518
|
if (_f && callback(_f.name)) {
|
528
|
-
if (_f.ref.focus
|
519
|
+
if (_f.ref.focus) {
|
520
|
+
_f.ref.focus();
|
529
521
|
break;
|
530
522
|
}
|
531
|
-
else if (_f.refs) {
|
523
|
+
else if (_f.refs && _f.refs[0].focus) {
|
532
524
|
_f.refs[0].focus();
|
533
525
|
break;
|
534
526
|
}
|
@@ -801,6 +793,11 @@ function append(data, value) {
|
|
801
793
|
return [...data, ...convertToArrayPayload(value)];
|
802
794
|
}
|
803
795
|
|
796
|
+
var isPlainObject = (tempObject) => {
|
797
|
+
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
798
|
+
return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
|
799
|
+
};
|
800
|
+
|
804
801
|
var isWeb = typeof window !== 'undefined' &&
|
805
802
|
typeof window.HTMLElement !== 'undefined' &&
|
806
803
|
typeof document !== 'undefined';
|
@@ -817,12 +814,13 @@ function cloneObject(data) {
|
|
817
814
|
else if (!(isWeb && (data instanceof Blob || data instanceof FileList)) &&
|
818
815
|
(isArray || isObject(data))) {
|
819
816
|
copy = isArray ? [] : {};
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
817
|
+
if (!Array.isArray(data) && !isPlainObject(data)) {
|
818
|
+
copy = data;
|
819
|
+
}
|
820
|
+
else {
|
821
|
+
for (const key in data) {
|
822
|
+
copy[key] = cloneObject(data[key]);
|
824
823
|
}
|
825
|
-
copy[key] = cloneObject(data[key]);
|
826
824
|
}
|
827
825
|
}
|
828
826
|
else {
|
@@ -1083,7 +1081,9 @@ function useFieldArray(props) {
|
|
1083
1081
|
React.useEffect(() => {
|
1084
1082
|
control._stateFlags.action = false;
|
1085
1083
|
isWatched(name, control._names) && control._subjects.state.next({});
|
1086
|
-
if (_actioned.current
|
1084
|
+
if (_actioned.current &&
|
1085
|
+
(!getValidationModes(control._options.mode).isOnSubmit ||
|
1086
|
+
control._formState.isSubmitted)) {
|
1087
1087
|
if (control._options.resolver) {
|
1088
1088
|
control._executeSchema([name]).then((result) => {
|
1089
1089
|
const error = get(result.errors, name);
|
@@ -1100,11 +1100,7 @@ function useFieldArray(props) {
|
|
1100
1100
|
}
|
1101
1101
|
else {
|
1102
1102
|
const field = get(control._fields, name);
|
1103
|
-
|
1104
|
-
if ((!validationModeBeforeSubmit.isOnSubmit ||
|
1105
|
-
control._formState.isSubmitted) &&
|
1106
|
-
field &&
|
1107
|
-
field._f) {
|
1103
|
+
if (field && field._f) {
|
1108
1104
|
validateField(field, get(control._formValues, name), control._options.criteriaMode === VALIDATION_MODE.all, control._options.shouldUseNativeValidation, true).then((error) => !isEmptyObject(error) &&
|
1109
1105
|
control._subjects.state.next({
|
1110
1106
|
errors: updateFieldArrayRootError(control._formState.errors, error, name),
|
@@ -1383,15 +1379,15 @@ function createFormControl(props = {}) {
|
|
1383
1379
|
...props,
|
1384
1380
|
};
|
1385
1381
|
let _formState = {
|
1382
|
+
submitCount: 0,
|
1386
1383
|
isDirty: false,
|
1387
1384
|
isValidating: false,
|
1388
|
-
dirtyFields: {},
|
1389
1385
|
isSubmitted: false,
|
1390
|
-
submitCount: 0,
|
1391
|
-
touchedFields: {},
|
1392
1386
|
isSubmitting: false,
|
1393
1387
|
isSubmitSuccessful: false,
|
1394
1388
|
isValid: false,
|
1389
|
+
touchedFields: {},
|
1390
|
+
dirtyFields: {},
|
1395
1391
|
errors: {},
|
1396
1392
|
};
|
1397
1393
|
let _fields = {};
|
@@ -1657,7 +1653,7 @@ function createFormControl(props = {}) {
|
|
1657
1653
|
? ''
|
1658
1654
|
: value;
|
1659
1655
|
if (isMultipleSelect(fieldReference.ref)) {
|
1660
|
-
[...fieldReference.ref.options].forEach((
|
1656
|
+
[...fieldReference.ref.options].forEach((optionRef) => (optionRef.selected = fieldValue.includes(optionRef.value)));
|
1661
1657
|
}
|
1662
1658
|
else if (fieldReference.refs) {
|
1663
1659
|
if (isCheckBoxInput(fieldReference.ref)) {
|
@@ -2130,9 +2126,7 @@ function createFormControl(props = {}) {
|
|
2130
2126
|
touchedFields: keepStateOptions.keepTouched
|
2131
2127
|
? _formState.touchedFields
|
2132
2128
|
: {},
|
2133
|
-
errors: keepStateOptions.keepErrors
|
2134
|
-
? _formState.errors
|
2135
|
-
: {},
|
2129
|
+
errors: keepStateOptions.keepErrors ? _formState.errors : {},
|
2136
2130
|
isSubmitting: false,
|
2137
2131
|
isSubmitSuccessful: false,
|
2138
2132
|
});
|
@@ -2147,8 +2141,10 @@ function createFormControl(props = {}) {
|
|
2147
2141
|
const fieldRef = fieldReference.refs
|
2148
2142
|
? fieldReference.refs[0]
|
2149
2143
|
: fieldReference.ref;
|
2150
|
-
fieldRef.focus
|
2151
|
-
|
2144
|
+
if (fieldRef.focus) {
|
2145
|
+
fieldRef.focus();
|
2146
|
+
options.shouldSelect && fieldRef.select();
|
2147
|
+
}
|
2152
2148
|
}
|
2153
2149
|
};
|
2154
2150
|
return {
|
@@ -2252,37 +2248,35 @@ function useForm(props = {}) {
|
|
2252
2248
|
const [formState, updateFormState] = React.useState({
|
2253
2249
|
isDirty: false,
|
2254
2250
|
isValidating: false,
|
2255
|
-
dirtyFields: {},
|
2256
2251
|
isSubmitted: false,
|
2257
|
-
submitCount: 0,
|
2258
|
-
touchedFields: {},
|
2259
2252
|
isSubmitting: false,
|
2260
2253
|
isSubmitSuccessful: false,
|
2261
2254
|
isValid: false,
|
2255
|
+
submitCount: 0,
|
2256
|
+
dirtyFields: {},
|
2257
|
+
touchedFields: {},
|
2262
2258
|
errors: {},
|
2259
|
+
defaultValues: props.defaultValues,
|
2263
2260
|
});
|
2264
|
-
if (_formControl.current) {
|
2265
|
-
_formControl.current.control._options = props;
|
2266
|
-
}
|
2267
|
-
else {
|
2261
|
+
if (!_formControl.current) {
|
2268
2262
|
_formControl.current = {
|
2269
2263
|
...createFormControl(props),
|
2270
2264
|
formState,
|
2271
2265
|
};
|
2272
2266
|
}
|
2273
2267
|
const control = _formControl.current.control;
|
2274
|
-
|
2275
|
-
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2276
|
-
control._formState = {
|
2277
|
-
...control._formState,
|
2278
|
-
...value,
|
2279
|
-
};
|
2280
|
-
updateFormState({ ...control._formState });
|
2281
|
-
}
|
2282
|
-
}, [control]);
|
2268
|
+
control._options = props;
|
2283
2269
|
useSubscribe({
|
2284
2270
|
subject: control._subjects.state,
|
2285
|
-
callback
|
2271
|
+
callback: React.useCallback((value) => {
|
2272
|
+
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2273
|
+
control._formState = {
|
2274
|
+
...control._formState,
|
2275
|
+
...value,
|
2276
|
+
};
|
2277
|
+
updateFormState({ ...control._formState });
|
2278
|
+
}
|
2279
|
+
}, [control]),
|
2286
2280
|
});
|
2287
2281
|
React.useEffect(() => {
|
2288
2282
|
if (!control._stateFlags.mount) {
|
@@ -2295,7 +2289,7 @@ function useForm(props = {}) {
|
|
2295
2289
|
}
|
2296
2290
|
control._removeUnmounted();
|
2297
2291
|
});
|
2298
|
-
_formControl.current.formState = getProxyFormState(formState, control
|
2292
|
+
_formControl.current.formState = getProxyFormState(formState, control);
|
2299
2293
|
return _formControl.current;
|
2300
2294
|
}
|
2301
2295
|
|