react-hook-form 7.18.1 → 7.19.2
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 +12 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +147 -150
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/generateWatchOutput.d.ts +2 -0
- package/dist/logic/shouldSubscribeByName.d.ts +1 -1
- package/dist/types/form.d.ts +7 -4
- package/dist/useSubscribe.d.ts +0 -1
- package/dist/utils/createSubject.d.ts +3 -8
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
@@ -105,37 +105,35 @@ var convertToArrayPayload = (value) => (Array.isArray(value) ? value : [value]);
|
|
105
105
|
|
106
106
|
var shouldSubscribeByName = (name, signalName) => !name ||
|
107
107
|
!signalName ||
|
108
|
+
name === signalName ||
|
108
109
|
convertToArrayPayload(name).some((currentName) => currentName &&
|
109
110
|
(currentName.startsWith(signalName) ||
|
110
111
|
signalName.startsWith(currentName)));
|
111
112
|
|
112
|
-
const tearDown = (
|
113
|
-
if (
|
114
|
-
|
115
|
-
|
113
|
+
const tearDown = (_subscription) => {
|
114
|
+
if (_subscription.current) {
|
115
|
+
_subscription.current.unsubscribe();
|
116
|
+
_subscription.current = undefined;
|
116
117
|
}
|
117
118
|
};
|
118
|
-
const updateSubscriptionProps = ({
|
119
|
+
const updateSubscriptionProps = ({ _subscription, props }) => {
|
119
120
|
if (props.disabled) {
|
120
|
-
tearDown(
|
121
|
+
tearDown(_subscription);
|
121
122
|
}
|
122
|
-
else if (!
|
123
|
-
|
123
|
+
else if (!_subscription.current) {
|
124
|
+
_subscription.current = props.subject.subscribe({
|
124
125
|
next: props.callback,
|
125
126
|
});
|
126
127
|
}
|
127
128
|
};
|
128
129
|
function useSubscribe(props) {
|
129
|
-
const
|
130
|
-
|
131
|
-
|
132
|
-
_unsubscribe,
|
130
|
+
const _subscription = React.useRef();
|
131
|
+
updateSubscriptionProps({
|
132
|
+
_subscription,
|
133
133
|
props,
|
134
134
|
});
|
135
|
-
!props.skipEarlySubscription && _updateSubscription.current();
|
136
135
|
React.useEffect(() => {
|
137
|
-
|
138
|
-
return () => tearDown(_unsubscribe);
|
136
|
+
return () => tearDown(_subscription);
|
139
137
|
}, []);
|
140
138
|
}
|
141
139
|
|
@@ -159,56 +157,123 @@ function useFormState(props) {
|
|
159
157
|
shouldRenderFormState(formState, _localProxyFormState.current) &&
|
160
158
|
updateFormState(Object.assign(Object.assign({}, control._formState), formState)),
|
161
159
|
subject: control._subjects.state,
|
162
|
-
skipEarlySubscription: true,
|
163
160
|
});
|
164
161
|
return getProxyFormState(formState, control._proxyFormState, _localProxyFormState.current, false);
|
165
162
|
}
|
166
163
|
|
164
|
+
var isString = (value) => typeof value === 'string';
|
165
|
+
|
166
|
+
function generateWatchOutput(names, _names, formValues, isGlobal) {
|
167
|
+
const isArray = Array.isArray(names);
|
168
|
+
if (isString(names)) {
|
169
|
+
isGlobal && _names.watch.add(names);
|
170
|
+
return get(formValues, names);
|
171
|
+
}
|
172
|
+
if (isArray) {
|
173
|
+
return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName),
|
174
|
+
get(formValues, fieldName)));
|
175
|
+
}
|
176
|
+
isGlobal && (_names.watchAll = true);
|
177
|
+
return formValues;
|
178
|
+
}
|
179
|
+
|
180
|
+
var isKey = (value) => /^\w*$/.test(value);
|
181
|
+
|
182
|
+
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
|
183
|
+
|
184
|
+
function set(object, path, value) {
|
185
|
+
let index = -1;
|
186
|
+
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
187
|
+
const length = tempPath.length;
|
188
|
+
const lastIndex = length - 1;
|
189
|
+
while (++index < length) {
|
190
|
+
const key = tempPath[index];
|
191
|
+
let newValue = value;
|
192
|
+
if (index !== lastIndex) {
|
193
|
+
const objValue = object[key];
|
194
|
+
newValue =
|
195
|
+
isObject(objValue) || Array.isArray(objValue)
|
196
|
+
? objValue
|
197
|
+
: !isNaN(+tempPath[index + 1])
|
198
|
+
? []
|
199
|
+
: {};
|
200
|
+
}
|
201
|
+
object[key] = newValue;
|
202
|
+
object = object[key];
|
203
|
+
}
|
204
|
+
return object;
|
205
|
+
}
|
206
|
+
|
207
|
+
function useWatch(props) {
|
208
|
+
const methods = useFormContext();
|
209
|
+
const { control = methods.control, name, defaultValue, disabled, } = props || {};
|
210
|
+
const _name = React.useRef(name);
|
211
|
+
_name.current = name;
|
212
|
+
useSubscribe({
|
213
|
+
disabled,
|
214
|
+
subject: control._subjects.watch,
|
215
|
+
callback: (formState) => {
|
216
|
+
if (shouldSubscribeByName(_name.current, formState.name)) {
|
217
|
+
const fieldValues = generateWatchOutput(_name.current, control._names, control._formValues);
|
218
|
+
updateValue(isObject(fieldValues) &&
|
219
|
+
!(isString(_name.current) &&
|
220
|
+
get(control._fields, _name.current, {})._f)
|
221
|
+
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
222
|
+
? [...fieldValues]
|
223
|
+
: fieldValues);
|
224
|
+
}
|
225
|
+
},
|
226
|
+
});
|
227
|
+
const [value, updateValue] = React.useState(isUndefined(defaultValue)
|
228
|
+
? control._getWatch(name)
|
229
|
+
: defaultValue);
|
230
|
+
React.useEffect(() => {
|
231
|
+
control._removeUnmounted();
|
232
|
+
});
|
233
|
+
return value;
|
234
|
+
}
|
235
|
+
|
167
236
|
function useController(props) {
|
168
237
|
const methods = useFormContext();
|
169
238
|
const { name, control = methods.control, shouldUnregister } = props;
|
170
|
-
const
|
239
|
+
const value = useWatch({
|
240
|
+
control,
|
241
|
+
name,
|
242
|
+
defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
|
243
|
+
});
|
171
244
|
const formState = useFormState({
|
172
|
-
control
|
245
|
+
control,
|
173
246
|
name,
|
174
247
|
});
|
175
248
|
const _name = React.useRef(name);
|
176
249
|
_name.current = name;
|
177
|
-
useSubscribe({
|
178
|
-
subject: control._subjects.control,
|
179
|
-
callback: (data) => (!data.name || _name.current === data.name) &&
|
180
|
-
setInputStateValue(get(data.values, _name.current)),
|
181
|
-
skipEarlySubscription: true,
|
182
|
-
});
|
183
250
|
const registerProps = control.register(name, Object.assign(Object.assign({}, props.rules), { value }));
|
184
|
-
const updateMounted = React.useCallback((name, value) => {
|
185
|
-
const field = get(control._fields, name);
|
186
|
-
if (field) {
|
187
|
-
field._f.mount = value;
|
188
|
-
}
|
189
|
-
}, [control]);
|
190
251
|
React.useEffect(() => {
|
252
|
+
const updateMounted = (name, value) => {
|
253
|
+
const field = get(control._fields, name);
|
254
|
+
if (field) {
|
255
|
+
field._f.mount = value;
|
256
|
+
}
|
257
|
+
};
|
191
258
|
updateMounted(name, true);
|
192
259
|
return () => {
|
193
260
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
194
261
|
if (isNameInFieldArray(control._names.array, name)
|
195
262
|
? _shouldUnregisterField && !control._stateFlags.action
|
196
263
|
: _shouldUnregisterField) {
|
197
|
-
control.unregister(name);
|
264
|
+
control.unregister(name, { keepDefaultValue: true });
|
198
265
|
}
|
199
266
|
else {
|
200
267
|
updateMounted(name, false);
|
201
268
|
}
|
202
269
|
};
|
203
|
-
}, [name, control, shouldUnregister
|
270
|
+
}, [name, control, shouldUnregister]);
|
204
271
|
return {
|
205
272
|
field: {
|
206
273
|
onChange: (event) => {
|
207
|
-
const value = getControllerValue(event);
|
208
|
-
setInputStateValue(value);
|
209
274
|
registerProps.onChange({
|
210
275
|
target: {
|
211
|
-
value,
|
276
|
+
value: getControllerValue(event),
|
212
277
|
name: name,
|
213
278
|
},
|
214
279
|
type: EVENTS.CHANGE,
|
@@ -251,33 +316,6 @@ const Controller = (props) => props.render(useController(props));
|
|
251
316
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
252
317
|
? Object.assign(Object.assign({}, errors[name]), { types: Object.assign(Object.assign({}, (errors[name] && errors[name].types ? errors[name].types : {})), { [type]: message || true }) }) : {};
|
253
318
|
|
254
|
-
var isKey = (value) => /^\w*$/.test(value);
|
255
|
-
|
256
|
-
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
|
257
|
-
|
258
|
-
function set(object, path, value) {
|
259
|
-
let index = -1;
|
260
|
-
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
261
|
-
const length = tempPath.length;
|
262
|
-
const lastIndex = length - 1;
|
263
|
-
while (++index < length) {
|
264
|
-
const key = tempPath[index];
|
265
|
-
let newValue = value;
|
266
|
-
if (index !== lastIndex) {
|
267
|
-
const objValue = object[key];
|
268
|
-
newValue =
|
269
|
-
isObject(objValue) || Array.isArray(objValue)
|
270
|
-
? objValue
|
271
|
-
: !isNaN(+tempPath[index + 1])
|
272
|
-
? []
|
273
|
-
: {};
|
274
|
-
}
|
275
|
-
object[key] = newValue;
|
276
|
-
object = object[key];
|
277
|
-
}
|
278
|
-
return object;
|
279
|
-
}
|
280
|
-
|
281
319
|
const focusFieldBy = (fields, callback, fieldsNames) => {
|
282
320
|
for (const key of fieldsNames || Object.keys(fields)) {
|
283
321
|
const field = get(fields, key);
|
@@ -390,7 +428,6 @@ const useFieldArray = (props) => {
|
|
390
428
|
}
|
391
429
|
},
|
392
430
|
subject: control._subjects.array,
|
393
|
-
skipEarlySubscription: true,
|
394
431
|
});
|
395
432
|
const updateValues = React.useCallback((updatedFieldArrayValuesWithKey) => {
|
396
433
|
const updatedFieldArrayValues = omitKeys(updatedFieldArrayValuesWithKey, keyName);
|
@@ -538,34 +575,6 @@ function cloneObject(data) {
|
|
538
575
|
return copy;
|
539
576
|
}
|
540
577
|
|
541
|
-
function createSubscription() {
|
542
|
-
let tearDowns = [];
|
543
|
-
const add = (tearDown) => {
|
544
|
-
tearDowns.push(tearDown);
|
545
|
-
};
|
546
|
-
const unsubscribe = () => {
|
547
|
-
for (const teardown of tearDowns) {
|
548
|
-
teardown();
|
549
|
-
}
|
550
|
-
tearDowns = [];
|
551
|
-
};
|
552
|
-
return {
|
553
|
-
add,
|
554
|
-
unsubscribe,
|
555
|
-
};
|
556
|
-
}
|
557
|
-
function createSubscriber(observer, subscription) {
|
558
|
-
let closed = false;
|
559
|
-
subscription.add(() => (closed = true));
|
560
|
-
const next = (value) => {
|
561
|
-
if (!closed) {
|
562
|
-
observer.next(value);
|
563
|
-
}
|
564
|
-
};
|
565
|
-
return {
|
566
|
-
next,
|
567
|
-
};
|
568
|
-
}
|
569
578
|
function createSubject() {
|
570
579
|
let _observers = [];
|
571
580
|
const next = (value) => {
|
@@ -574,10 +583,12 @@ function createSubject() {
|
|
574
583
|
}
|
575
584
|
};
|
576
585
|
const subscribe = (observer) => {
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
586
|
+
_observers.push(observer);
|
587
|
+
return {
|
588
|
+
unsubscribe: () => {
|
589
|
+
_observers = _observers.filter((o) => o !== observer);
|
590
|
+
},
|
591
|
+
};
|
581
592
|
};
|
582
593
|
const unsubscribe = () => {
|
583
594
|
_observers = [];
|
@@ -645,8 +656,6 @@ var isRadioInput = (element) => element.type === 'radio';
|
|
645
656
|
|
646
657
|
var isRadioOrCheckboxFunction = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
647
658
|
|
648
|
-
var isString = (value) => typeof value === 'string';
|
649
|
-
|
650
659
|
var isWeb = typeof window !== 'undefined' &&
|
651
660
|
typeof window.HTMLElement !== 'undefined' &&
|
652
661
|
typeof document !== 'undefined';
|
@@ -1084,7 +1093,6 @@ function createFormControl(props = {}) {
|
|
1084
1093
|
};
|
1085
1094
|
const _subjects = {
|
1086
1095
|
watch: createSubject(),
|
1087
|
-
control: createSubject(),
|
1088
1096
|
array: createSubject(),
|
1089
1097
|
state: createSubject(),
|
1090
1098
|
};
|
@@ -1289,16 +1297,10 @@ function createFormControl(props = {}) {
|
|
1289
1297
|
: isString(names)
|
1290
1298
|
? { [names]: defaultValue }
|
1291
1299
|
: defaultValue));
|
1292
|
-
|
1293
|
-
const result = convertToArrayPayload(names).map((fieldName) => (isGlobal && _names.watch.add(fieldName),
|
1294
|
-
get(fieldValues, fieldName)));
|
1295
|
-
return Array.isArray(names) ? result : result[0];
|
1296
|
-
}
|
1297
|
-
isGlobal && (_names.watchAll = true);
|
1298
|
-
return fieldValues;
|
1300
|
+
return generateWatchOutput(names, _names, fieldValues, isGlobal);
|
1299
1301
|
};
|
1300
1302
|
const _getFieldArray = (name) => get(_stateFlags.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []);
|
1301
|
-
const setFieldValue = (name, value, options = {}
|
1303
|
+
const setFieldValue = (name, value, options = {}) => {
|
1302
1304
|
const field = get(_fields, name);
|
1303
1305
|
let fieldValue = value;
|
1304
1306
|
if (field) {
|
@@ -1330,11 +1332,6 @@ function createFormControl(props = {}) {
|
|
1330
1332
|
else {
|
1331
1333
|
fieldReference.ref.value = fieldValue;
|
1332
1334
|
}
|
1333
|
-
shouldRender &&
|
1334
|
-
_subjects.control.next({
|
1335
|
-
values: _formValues,
|
1336
|
-
name,
|
1337
|
-
});
|
1338
1335
|
}
|
1339
1336
|
}
|
1340
1337
|
(options.shouldDirty || options.shouldTouch) &&
|
@@ -1351,7 +1348,7 @@ function createFormControl(props = {}) {
|
|
1351
1348
|
(field && !field._f)) &&
|
1352
1349
|
!isDateObject(fieldValue)
|
1353
1350
|
? setValues(fieldName, fieldValue, options)
|
1354
|
-
: setFieldValue(fieldName, fieldValue, options
|
1351
|
+
: setFieldValue(fieldName, fieldValue, options);
|
1355
1352
|
}
|
1356
1353
|
};
|
1357
1354
|
const setValue = (name, value, options = {}) => {
|
@@ -1376,7 +1373,7 @@ function createFormControl(props = {}) {
|
|
1376
1373
|
else {
|
1377
1374
|
field && !field._f && !isNullOrUndefined(value)
|
1378
1375
|
? setValues(name, value, options)
|
1379
|
-
: setFieldValue(name, value, options
|
1376
|
+
: setFieldValue(name, value, options);
|
1380
1377
|
}
|
1381
1378
|
isFieldWatched(name) && _subjects.state.next({});
|
1382
1379
|
_subjects.watch.next({
|
@@ -1457,7 +1454,7 @@ function createFormControl(props = {}) {
|
|
1457
1454
|
const field = get(_fields, fieldName);
|
1458
1455
|
return await executeBuildInValidation(field && field._f ? { [fieldName]: field } : field);
|
1459
1456
|
}))).every(Boolean);
|
1460
|
-
_updateValid();
|
1457
|
+
!(!validationResult && !_formState.isValid) && _updateValid();
|
1461
1458
|
}
|
1462
1459
|
else {
|
1463
1460
|
validationResult = isValid = await executeBuildInValidation(_fields);
|
@@ -1530,7 +1527,9 @@ function createFormControl(props = {}) {
|
|
1530
1527
|
_f: Object.assign(Object.assign(Object.assign({}, (field && field._f ? field._f : { ref: { name } })), { name, mount: true }), options),
|
1531
1528
|
});
|
1532
1529
|
_names.mount.add(name);
|
1533
|
-
!isUndefined(options.value) &&
|
1530
|
+
!isUndefined(options.value) &&
|
1531
|
+
!options.disabled &&
|
1532
|
+
set(_formValues, name, get(_formValues, name, options.value));
|
1534
1533
|
field
|
1535
1534
|
? isBoolean(options.disabled) &&
|
1536
1535
|
set(_formValues, name, options.disabled
|
@@ -1586,7 +1585,9 @@ function createFormControl(props = {}) {
|
|
1586
1585
|
e.persist && e.persist();
|
1587
1586
|
}
|
1588
1587
|
let hasNoPromiseError = true;
|
1589
|
-
let fieldValues =
|
1588
|
+
let fieldValues = _options.shouldUnregister
|
1589
|
+
? cloneObject(_formValues)
|
1590
|
+
: Object.assign({}, _formValues);
|
1590
1591
|
_subjects.state.next({
|
1591
1592
|
isSubmitting: true,
|
1592
1593
|
});
|
@@ -1628,10 +1629,35 @@ function createFormControl(props = {}) {
|
|
1628
1629
|
});
|
1629
1630
|
}
|
1630
1631
|
};
|
1632
|
+
const resetField = (name, options = {}) => {
|
1633
|
+
if (isUndefined(options.defaultValue)) {
|
1634
|
+
setValue(name, get(_defaultValues, name));
|
1635
|
+
}
|
1636
|
+
else {
|
1637
|
+
setValue(name, options.defaultValue);
|
1638
|
+
set(_defaultValues, name, options.defaultValue);
|
1639
|
+
}
|
1640
|
+
if (!options.keepTouched) {
|
1641
|
+
unset(_formState.touchedFields, name);
|
1642
|
+
}
|
1643
|
+
if (!options.keepDirty) {
|
1644
|
+
unset(_formState.dirtyFields, name);
|
1645
|
+
_formState.isDirty = options.defaultValue
|
1646
|
+
? _getDirty(name, get(_defaultValues, name))
|
1647
|
+
: _getDirty();
|
1648
|
+
}
|
1649
|
+
if (!options.keepError) {
|
1650
|
+
unset(_formState.errors, name);
|
1651
|
+
_proxyFormState.isValid && _updateValid();
|
1652
|
+
}
|
1653
|
+
_subjects.state.next(Object.assign({}, _formState));
|
1654
|
+
};
|
1631
1655
|
const reset = (formValues, keepStateOptions = {}) => {
|
1632
|
-
const hasUpdatedFormValues = !isEmptyObject(formValues);
|
1633
1656
|
const updatedValues = formValues || _defaultValues;
|
1634
1657
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
1658
|
+
const values = !isEmptyObject(formValues)
|
1659
|
+
? cloneUpdatedValues
|
1660
|
+
: _defaultValues;
|
1635
1661
|
if (!keepStateOptions.keepDefaultValues) {
|
1636
1662
|
_defaultValues = updatedValues;
|
1637
1663
|
}
|
@@ -1658,12 +1684,11 @@ function createFormControl(props = {}) {
|
|
1658
1684
|
: {}
|
1659
1685
|
: cloneUpdatedValues;
|
1660
1686
|
_fields = {};
|
1661
|
-
_subjects.
|
1662
|
-
values
|
1687
|
+
_subjects.watch.next({
|
1688
|
+
values,
|
1663
1689
|
});
|
1664
|
-
_subjects.watch.next({});
|
1665
1690
|
_subjects.array.next({
|
1666
|
-
values
|
1691
|
+
values,
|
1667
1692
|
});
|
1668
1693
|
}
|
1669
1694
|
_names = {
|
@@ -1771,6 +1796,7 @@ function createFormControl(props = {}) {
|
|
1771
1796
|
setValue,
|
1772
1797
|
getValues,
|
1773
1798
|
reset,
|
1799
|
+
resetField,
|
1774
1800
|
clearErrors,
|
1775
1801
|
unregister,
|
1776
1802
|
setError,
|
@@ -1819,38 +1845,9 @@ function useForm(props = {}) {
|
|
1819
1845
|
}
|
1820
1846
|
control._removeUnmounted();
|
1821
1847
|
});
|
1822
|
-
React.useEffect(() => () => Object.values(control._subjects).forEach((subject) => subject.unsubscribe()), [control]);
|
1823
1848
|
_formControl.current.formState = getProxyFormState(formState, control._proxyFormState);
|
1824
1849
|
return _formControl.current;
|
1825
1850
|
}
|
1826
1851
|
|
1827
|
-
function useWatch(props) {
|
1828
|
-
const methods = useFormContext();
|
1829
|
-
const { control = methods.control, name, defaultValue, disabled, } = props || {};
|
1830
|
-
const _name = React.useRef(name);
|
1831
|
-
_name.current = name;
|
1832
|
-
useSubscribe({
|
1833
|
-
disabled,
|
1834
|
-
subject: control._subjects.watch,
|
1835
|
-
callback: (formState) => {
|
1836
|
-
if (shouldSubscribeByName(_name.current, formState.name)) {
|
1837
|
-
control._stateFlags.mount = true;
|
1838
|
-
const fieldValues = control._getWatch(_name.current, defaultValue);
|
1839
|
-
updateValue(isObject(fieldValues)
|
1840
|
-
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
1841
|
-
? [...fieldValues]
|
1842
|
-
: fieldValues);
|
1843
|
-
}
|
1844
|
-
},
|
1845
|
-
});
|
1846
|
-
const [value, updateValue] = React.useState(isUndefined(defaultValue)
|
1847
|
-
? control._getWatch(name)
|
1848
|
-
: defaultValue);
|
1849
|
-
React.useEffect(() => {
|
1850
|
-
control._removeUnmounted();
|
1851
|
-
});
|
1852
|
-
return value;
|
1853
|
-
}
|
1854
|
-
|
1855
1852
|
export { Controller, FormProvider, appendErrors, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
|
1856
1853
|
//# sourceMappingURL=index.esm.js.map
|