react-hook-form 7.18.0 → 7.19.0-next.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/CHANGELOG.md +24 -0
- package/README.md +23 -6
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +125 -128
- 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,35 +157,75 @@ 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
|
+
function useWatch(props) {
|
181
|
+
const methods = useFormContext();
|
182
|
+
const { control = methods.control, name, defaultValue, disabled, } = props || {};
|
183
|
+
const _name = React.useRef(name);
|
184
|
+
_name.current = name;
|
185
|
+
useSubscribe({
|
186
|
+
disabled,
|
187
|
+
subject: control._subjects.watch,
|
188
|
+
callback: (formState) => {
|
189
|
+
if (shouldSubscribeByName(_name.current, formState.name)) {
|
190
|
+
const fieldValues = generateWatchOutput(_name.current, control._names, control._formValues);
|
191
|
+
updateValue(isObject(fieldValues)
|
192
|
+
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
193
|
+
? [...fieldValues]
|
194
|
+
: fieldValues);
|
195
|
+
}
|
196
|
+
},
|
197
|
+
});
|
198
|
+
const [value, updateValue] = React.useState(isUndefined(defaultValue)
|
199
|
+
? control._getWatch(name)
|
200
|
+
: defaultValue);
|
201
|
+
React.useEffect(() => {
|
202
|
+
control._removeUnmounted();
|
203
|
+
});
|
204
|
+
return value;
|
205
|
+
}
|
206
|
+
|
167
207
|
function useController(props) {
|
168
208
|
const methods = useFormContext();
|
169
209
|
const { name, control = methods.control, shouldUnregister } = props;
|
170
|
-
const
|
210
|
+
const value = useWatch({
|
211
|
+
control,
|
212
|
+
name,
|
213
|
+
defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
|
214
|
+
});
|
171
215
|
const formState = useFormState({
|
172
|
-
control
|
216
|
+
control,
|
173
217
|
name,
|
174
218
|
});
|
175
219
|
const _name = React.useRef(name);
|
176
220
|
_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
221
|
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
222
|
React.useEffect(() => {
|
223
|
+
const updateMounted = (name, value) => {
|
224
|
+
const field = get(control._fields, name);
|
225
|
+
if (field) {
|
226
|
+
field._f.mount = value;
|
227
|
+
}
|
228
|
+
};
|
191
229
|
updateMounted(name, true);
|
192
230
|
return () => {
|
193
231
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
@@ -200,15 +238,13 @@ function useController(props) {
|
|
200
238
|
updateMounted(name, false);
|
201
239
|
}
|
202
240
|
};
|
203
|
-
}, [name, control, shouldUnregister
|
241
|
+
}, [name, control, shouldUnregister]);
|
204
242
|
return {
|
205
243
|
field: {
|
206
244
|
onChange: (event) => {
|
207
|
-
const value = getControllerValue(event);
|
208
|
-
setInputStateValue(value);
|
209
245
|
registerProps.onChange({
|
210
246
|
target: {
|
211
|
-
value,
|
247
|
+
value: getControllerValue(event),
|
212
248
|
name: name,
|
213
249
|
},
|
214
250
|
type: EVENTS.CHANGE,
|
@@ -379,6 +415,7 @@ const useFieldArray = (props) => {
|
|
379
415
|
const [fields, setFields] = React.useState(mapIds(control._getFieldArray(name), keyName));
|
380
416
|
const _fieldIds = React.useRef(fields);
|
381
417
|
const _name = React.useRef(name);
|
418
|
+
const _actioned = React.useRef(false);
|
382
419
|
_name.current = name;
|
383
420
|
_fieldIds.current = fields;
|
384
421
|
control._names.array.add(name);
|
@@ -389,10 +426,10 @@ const useFieldArray = (props) => {
|
|
389
426
|
}
|
390
427
|
},
|
391
428
|
subject: control._subjects.array,
|
392
|
-
skipEarlySubscription: true,
|
393
429
|
});
|
394
430
|
const updateValues = React.useCallback((updatedFieldArrayValuesWithKey) => {
|
395
431
|
const updatedFieldArrayValues = omitKeys(updatedFieldArrayValuesWithKey, keyName);
|
432
|
+
_actioned.current = true;
|
396
433
|
set(control._formValues, name, updatedFieldArrayValues);
|
397
434
|
setFields(updatedFieldArrayValuesWithKey);
|
398
435
|
return updatedFieldArrayValues;
|
@@ -468,15 +505,17 @@ const useFieldArray = (props) => {
|
|
468
505
|
}
|
469
506
|
}
|
470
507
|
}
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
508
|
+
if (_actioned.current) {
|
509
|
+
control._executeSchema([name]).then((result) => {
|
510
|
+
const error = get(result.errors, name);
|
511
|
+
if (error && error.type && !get(control._formState.errors, name)) {
|
512
|
+
set(control._formState.errors, name, error);
|
513
|
+
control._subjects.state.next({
|
514
|
+
errors: control._formState.errors,
|
515
|
+
});
|
516
|
+
}
|
517
|
+
});
|
518
|
+
}
|
480
519
|
control._subjects.watch.next({
|
481
520
|
name,
|
482
521
|
values: control._formValues,
|
@@ -534,34 +573,6 @@ function cloneObject(data) {
|
|
534
573
|
return copy;
|
535
574
|
}
|
536
575
|
|
537
|
-
function createSubscription() {
|
538
|
-
let tearDowns = [];
|
539
|
-
const add = (tearDown) => {
|
540
|
-
tearDowns.push(tearDown);
|
541
|
-
};
|
542
|
-
const unsubscribe = () => {
|
543
|
-
for (const teardown of tearDowns) {
|
544
|
-
teardown();
|
545
|
-
}
|
546
|
-
tearDowns = [];
|
547
|
-
};
|
548
|
-
return {
|
549
|
-
add,
|
550
|
-
unsubscribe,
|
551
|
-
};
|
552
|
-
}
|
553
|
-
function createSubscriber(observer, subscription) {
|
554
|
-
let closed = false;
|
555
|
-
subscription.add(() => (closed = true));
|
556
|
-
const next = (value) => {
|
557
|
-
if (!closed) {
|
558
|
-
observer.next(value);
|
559
|
-
}
|
560
|
-
};
|
561
|
-
return {
|
562
|
-
next,
|
563
|
-
};
|
564
|
-
}
|
565
576
|
function createSubject() {
|
566
577
|
let _observers = [];
|
567
578
|
const next = (value) => {
|
@@ -570,10 +581,12 @@ function createSubject() {
|
|
570
581
|
}
|
571
582
|
};
|
572
583
|
const subscribe = (observer) => {
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
584
|
+
_observers.push(observer);
|
585
|
+
return {
|
586
|
+
unsubscribe: () => {
|
587
|
+
_observers = _observers.filter((o) => o !== observer);
|
588
|
+
},
|
589
|
+
};
|
577
590
|
};
|
578
591
|
const unsubscribe = () => {
|
579
592
|
_observers = [];
|
@@ -641,8 +654,6 @@ var isRadioInput = (element) => element.type === 'radio';
|
|
641
654
|
|
642
655
|
var isRadioOrCheckboxFunction = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
643
656
|
|
644
|
-
var isString = (value) => typeof value === 'string';
|
645
|
-
|
646
657
|
var isWeb = typeof window !== 'undefined' &&
|
647
658
|
typeof window.HTMLElement !== 'undefined' &&
|
648
659
|
typeof document !== 'undefined';
|
@@ -1080,7 +1091,6 @@ function createFormControl(props = {}) {
|
|
1080
1091
|
};
|
1081
1092
|
const _subjects = {
|
1082
1093
|
watch: createSubject(),
|
1083
|
-
control: createSubject(),
|
1084
1094
|
array: createSubject(),
|
1085
1095
|
state: createSubject(),
|
1086
1096
|
};
|
@@ -1285,16 +1295,10 @@ function createFormControl(props = {}) {
|
|
1285
1295
|
: isString(names)
|
1286
1296
|
? { [names]: defaultValue }
|
1287
1297
|
: defaultValue));
|
1288
|
-
|
1289
|
-
const result = convertToArrayPayload(names).map((fieldName) => (isGlobal && _names.watch.add(fieldName),
|
1290
|
-
get(fieldValues, fieldName)));
|
1291
|
-
return Array.isArray(names) ? result : result[0];
|
1292
|
-
}
|
1293
|
-
isGlobal && (_names.watchAll = true);
|
1294
|
-
return fieldValues;
|
1298
|
+
return generateWatchOutput(names, _names, fieldValues, isGlobal);
|
1295
1299
|
};
|
1296
1300
|
const _getFieldArray = (name) => get(_stateFlags.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []);
|
1297
|
-
const setFieldValue = (name, value, options = {}
|
1301
|
+
const setFieldValue = (name, value, options = {}) => {
|
1298
1302
|
const field = get(_fields, name);
|
1299
1303
|
let fieldValue = value;
|
1300
1304
|
if (field) {
|
@@ -1326,11 +1330,6 @@ function createFormControl(props = {}) {
|
|
1326
1330
|
else {
|
1327
1331
|
fieldReference.ref.value = fieldValue;
|
1328
1332
|
}
|
1329
|
-
shouldRender &&
|
1330
|
-
_subjects.control.next({
|
1331
|
-
values: _formValues,
|
1332
|
-
name,
|
1333
|
-
});
|
1334
1333
|
}
|
1335
1334
|
}
|
1336
1335
|
(options.shouldDirty || options.shouldTouch) &&
|
@@ -1347,7 +1346,7 @@ function createFormControl(props = {}) {
|
|
1347
1346
|
(field && !field._f)) &&
|
1348
1347
|
!isDateObject(fieldValue)
|
1349
1348
|
? setValues(fieldName, fieldValue, options)
|
1350
|
-
: setFieldValue(fieldName, fieldValue, options
|
1349
|
+
: setFieldValue(fieldName, fieldValue, options);
|
1351
1350
|
}
|
1352
1351
|
};
|
1353
1352
|
const setValue = (name, value, options = {}) => {
|
@@ -1372,7 +1371,7 @@ function createFormControl(props = {}) {
|
|
1372
1371
|
else {
|
1373
1372
|
field && !field._f && !isNullOrUndefined(value)
|
1374
1373
|
? setValues(name, value, options)
|
1375
|
-
: setFieldValue(name, value, options
|
1374
|
+
: setFieldValue(name, value, options);
|
1376
1375
|
}
|
1377
1376
|
isFieldWatched(name) && _subjects.state.next({});
|
1378
1377
|
_subjects.watch.next({
|
@@ -1526,7 +1525,8 @@ function createFormControl(props = {}) {
|
|
1526
1525
|
_f: Object.assign(Object.assign(Object.assign({}, (field && field._f ? field._f : { ref: { name } })), { name, mount: true }), options),
|
1527
1526
|
});
|
1528
1527
|
_names.mount.add(name);
|
1529
|
-
!isUndefined(options.value) &&
|
1528
|
+
!isUndefined(options.value) &&
|
1529
|
+
set(_formValues, name, get(_formValues, name, options.value));
|
1530
1530
|
field
|
1531
1531
|
? isBoolean(options.disabled) &&
|
1532
1532
|
set(_formValues, name, options.disabled
|
@@ -1624,10 +1624,35 @@ function createFormControl(props = {}) {
|
|
1624
1624
|
});
|
1625
1625
|
}
|
1626
1626
|
};
|
1627
|
+
const resetField = (name, options = {}) => {
|
1628
|
+
if (isUndefined(options.defaultValue)) {
|
1629
|
+
setValue(name, get(_defaultValues, name));
|
1630
|
+
}
|
1631
|
+
else {
|
1632
|
+
setValue(name, options.defaultValue);
|
1633
|
+
set(_defaultValues, name, options.defaultValue);
|
1634
|
+
}
|
1635
|
+
if (!options.keepTouched) {
|
1636
|
+
unset(_formState.touchedFields, name);
|
1637
|
+
}
|
1638
|
+
if (!options.keepDirty) {
|
1639
|
+
unset(_formState.dirtyFields, name);
|
1640
|
+
_formState.isDirty = options.defaultValue
|
1641
|
+
? _getDirty(name, get(_defaultValues, name))
|
1642
|
+
: _getDirty();
|
1643
|
+
}
|
1644
|
+
if (!options.keepError) {
|
1645
|
+
unset(_formState.errors, name);
|
1646
|
+
_proxyFormState.isValid && _updateValid();
|
1647
|
+
}
|
1648
|
+
_subjects.state.next(Object.assign({}, _formState));
|
1649
|
+
};
|
1627
1650
|
const reset = (formValues, keepStateOptions = {}) => {
|
1628
|
-
const hasUpdatedFormValues = !isEmptyObject(formValues);
|
1629
1651
|
const updatedValues = formValues || _defaultValues;
|
1630
1652
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
1653
|
+
const values = !isEmptyObject(formValues)
|
1654
|
+
? cloneUpdatedValues
|
1655
|
+
: _defaultValues;
|
1631
1656
|
if (!keepStateOptions.keepDefaultValues) {
|
1632
1657
|
_defaultValues = updatedValues;
|
1633
1658
|
}
|
@@ -1654,12 +1679,11 @@ function createFormControl(props = {}) {
|
|
1654
1679
|
: {}
|
1655
1680
|
: cloneUpdatedValues;
|
1656
1681
|
_fields = {};
|
1657
|
-
_subjects.
|
1658
|
-
values
|
1682
|
+
_subjects.watch.next({
|
1683
|
+
values,
|
1659
1684
|
});
|
1660
|
-
_subjects.watch.next({});
|
1661
1685
|
_subjects.array.next({
|
1662
|
-
values
|
1686
|
+
values,
|
1663
1687
|
});
|
1664
1688
|
}
|
1665
1689
|
_names = {
|
@@ -1767,6 +1791,7 @@ function createFormControl(props = {}) {
|
|
1767
1791
|
setValue,
|
1768
1792
|
getValues,
|
1769
1793
|
reset,
|
1794
|
+
resetField,
|
1770
1795
|
clearErrors,
|
1771
1796
|
unregister,
|
1772
1797
|
setError,
|
@@ -1820,33 +1845,5 @@ function useForm(props = {}) {
|
|
1820
1845
|
return _formControl.current;
|
1821
1846
|
}
|
1822
1847
|
|
1823
|
-
function useWatch(props) {
|
1824
|
-
const methods = useFormContext();
|
1825
|
-
const { control = methods.control, name, defaultValue, disabled, } = props || {};
|
1826
|
-
const _name = React.useRef(name);
|
1827
|
-
_name.current = name;
|
1828
|
-
useSubscribe({
|
1829
|
-
disabled,
|
1830
|
-
subject: control._subjects.watch,
|
1831
|
-
callback: (formState) => {
|
1832
|
-
if (shouldSubscribeByName(_name.current, formState.name)) {
|
1833
|
-
control._stateFlags.mount = true;
|
1834
|
-
const fieldValues = control._getWatch(_name.current, defaultValue);
|
1835
|
-
updateValue(isObject(fieldValues)
|
1836
|
-
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
1837
|
-
? [...fieldValues]
|
1838
|
-
: fieldValues);
|
1839
|
-
}
|
1840
|
-
},
|
1841
|
-
});
|
1842
|
-
const [value, updateValue] = React.useState(isUndefined(defaultValue)
|
1843
|
-
? control._getWatch(name)
|
1844
|
-
: defaultValue);
|
1845
|
-
React.useEffect(() => {
|
1846
|
-
control._removeUnmounted();
|
1847
|
-
});
|
1848
|
-
return value;
|
1849
|
-
}
|
1850
|
-
|
1851
1848
|
export { Controller, FormProvider, appendErrors, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
|
1852
1849
|
//# sourceMappingURL=index.esm.js.map
|