react-hook-form 7.83.0 → 7.84.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/fieldArray.d.ts +2 -1
- package/dist/fieldArray.d.ts.map +1 -1
- package/dist/form.d.ts +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/formStateSubscribe.d.ts +8 -3
- package/dist/formStateSubscribe.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.mjs +113 -59
- 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/collectDirtyFieldNames.d.ts +3 -0
- package/dist/logic/collectDirtyFieldNames.d.ts.map +1 -0
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getFieldValue.d.ts.map +1 -1
- package/dist/logic/iterateFieldsByAction.d.ts.map +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +39 -11
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/form.d.ts +5 -4
- package/dist/types/form.d.ts.map +1 -1
- package/dist/utils/formData.d.ts +3 -0
- package/dist/utils/formData.d.ts.map +1 -0
- package/dist/utils/json.d.ts +9 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/package.json +1 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from './controller';
|
|
2
2
|
export { FieldArray } from './fieldArray';
|
|
3
3
|
export * from './form';
|
|
4
|
-
export
|
|
4
|
+
export type { FormStateProps, FormStateSubscribeProps, } from './formStateSubscribe';
|
|
5
|
+
export { FormState, FormStateSubscribe } from './formStateSubscribe';
|
|
5
6
|
export * from './logic';
|
|
6
7
|
export * from './types';
|
|
7
8
|
export * from './useController';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,cAAc,QAAQ,CAAC;AACvB,cAAc,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,cAAc,QAAQ,CAAC;AACvB,YAAY,EACV,cAAc,EACd,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
package/dist/index.esm.mjs
CHANGED
|
@@ -644,9 +644,12 @@ var isWatched = (name, _names, isBlurEvent) => {
|
|
|
644
644
|
|
|
645
645
|
const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
646
646
|
for (const key of fieldsNames || Object.keys(fields)) {
|
|
647
|
-
|
|
647
|
+
if (key === '_f') {
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
650
|
+
const field = fieldsNames ? get(fields, key) : fields[key];
|
|
648
651
|
if (field) {
|
|
649
|
-
const { _f
|
|
652
|
+
const { _f } = field;
|
|
650
653
|
if (_f) {
|
|
651
654
|
if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
|
|
652
655
|
return true;
|
|
@@ -655,13 +658,13 @@ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
|
655
658
|
return true;
|
|
656
659
|
}
|
|
657
660
|
else {
|
|
658
|
-
if (iterateFieldsByAction(
|
|
661
|
+
if (iterateFieldsByAction(field, action)) {
|
|
659
662
|
break;
|
|
660
663
|
}
|
|
661
664
|
}
|
|
662
665
|
}
|
|
663
|
-
else if (isObject(
|
|
664
|
-
if (iterateFieldsByAction(
|
|
666
|
+
else if (isObject(field) || Array.isArray(field)) {
|
|
667
|
+
if (iterateFieldsByAction(field, action)) {
|
|
665
668
|
break;
|
|
666
669
|
}
|
|
667
670
|
}
|
|
@@ -998,7 +1001,7 @@ var swapArrayAt = (data, indexA, indexB) => {
|
|
|
998
1001
|
};
|
|
999
1002
|
|
|
1000
1003
|
function baseGet(object, updatePath) {
|
|
1001
|
-
const length = updatePath.
|
|
1004
|
+
const length = updatePath.length - 1;
|
|
1002
1005
|
let index = 0;
|
|
1003
1006
|
while (index < length) {
|
|
1004
1007
|
if (isNullOrUndefined(object)) {
|
|
@@ -1417,6 +1420,26 @@ const flatten = (obj) => {
|
|
|
1417
1420
|
return output;
|
|
1418
1421
|
};
|
|
1419
1422
|
|
|
1423
|
+
function jsonToFormData(json) {
|
|
1424
|
+
const result = new FormData();
|
|
1425
|
+
const flattenFormValues = flatten(json);
|
|
1426
|
+
for (const key in flattenFormValues) {
|
|
1427
|
+
result.append(key, flattenFormValues[key]);
|
|
1428
|
+
}
|
|
1429
|
+
return result;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
function safeJSONStringify(value) {
|
|
1433
|
+
try {
|
|
1434
|
+
return JSON.stringify(value);
|
|
1435
|
+
}
|
|
1436
|
+
catch (_a) {
|
|
1437
|
+
return '';
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
function noop() { }
|
|
1442
|
+
|
|
1420
1443
|
const HookFormContext = React.createContext(null);
|
|
1421
1444
|
HookFormContext.displayName = 'HookFormContext';
|
|
1422
1445
|
/**
|
|
@@ -1525,6 +1548,9 @@ const FormProvider = ({ children, watch, getValues, getFieldState, setError, cle
|
|
|
1525
1548
|
};
|
|
1526
1549
|
|
|
1527
1550
|
const POST_REQUEST = 'post';
|
|
1551
|
+
function defaultValidateStatus(status) {
|
|
1552
|
+
return status >= 200 && status < 300;
|
|
1553
|
+
}
|
|
1528
1554
|
/**
|
|
1529
1555
|
* Form component to manage submission.
|
|
1530
1556
|
*
|
|
@@ -1550,21 +1576,11 @@ const POST_REQUEST = 'post';
|
|
|
1550
1576
|
function Form(props) {
|
|
1551
1577
|
const methods = useFormContext();
|
|
1552
1578
|
const [mounted, setMounted] = React.useState(false);
|
|
1553
|
-
const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, ...rest } = props;
|
|
1554
|
-
const
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
const formData = new FormData();
|
|
1559
|
-
let formDataJson = '';
|
|
1560
|
-
try {
|
|
1561
|
-
formDataJson = JSON.stringify(data);
|
|
1562
|
-
}
|
|
1563
|
-
catch (_a) { }
|
|
1564
|
-
const flattenFormValues = flatten(data);
|
|
1565
|
-
for (const key in flattenFormValues) {
|
|
1566
|
-
formData.append(key, flattenFormValues[key]);
|
|
1567
|
-
}
|
|
1579
|
+
const { control = methods.control, onSubmit = noop, children, action, method = POST_REQUEST, headers, encType, onError = noop, render, onSuccess = noop, validateStatus = defaultValidateStatus, ...rest } = props;
|
|
1580
|
+
const handleSubmit = React.useMemo(() => {
|
|
1581
|
+
return control.handleSubmit(async (data, event) => {
|
|
1582
|
+
const formData = jsonToFormData(data);
|
|
1583
|
+
const formDataJson = safeJSONStringify(data);
|
|
1568
1584
|
if (onSubmit) {
|
|
1569
1585
|
await onSubmit({
|
|
1570
1586
|
data,
|
|
@@ -1574,48 +1590,48 @@ function Form(props) {
|
|
|
1574
1590
|
formDataJson,
|
|
1575
1591
|
});
|
|
1576
1592
|
}
|
|
1577
|
-
if (action) {
|
|
1593
|
+
if (isString(action)) {
|
|
1578
1594
|
try {
|
|
1579
|
-
const shouldStringifySubmissionData =
|
|
1580
|
-
headers
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
const response = await fetch(
|
|
1595
|
+
const shouldStringifySubmissionData = (headers &&
|
|
1596
|
+
headers['Content-Type'] &&
|
|
1597
|
+
headers['Content-Type'].includes('json')) ||
|
|
1598
|
+
(encType && encType.includes('json'));
|
|
1599
|
+
const response = await fetch(action, {
|
|
1584
1600
|
method,
|
|
1585
1601
|
headers: {
|
|
1586
1602
|
...headers,
|
|
1587
|
-
...(encType &&
|
|
1588
|
-
|
|
1589
|
-
:
|
|
1603
|
+
...(encType &&
|
|
1604
|
+
encType !== 'multipart/form-data' && {
|
|
1605
|
+
'Content-Type': encType,
|
|
1606
|
+
}),
|
|
1590
1607
|
},
|
|
1591
1608
|
body: shouldStringifySubmissionData ? formDataJson : formData,
|
|
1592
1609
|
});
|
|
1593
|
-
if (response &&
|
|
1594
|
-
(
|
|
1595
|
-
|
|
1596
|
-
: response.status < 200 || response.status >= 300)) {
|
|
1597
|
-
hasError = true;
|
|
1598
|
-
onError && onError({ response });
|
|
1599
|
-
type = String(response.status);
|
|
1610
|
+
if (response && !validateStatus(response.status)) {
|
|
1611
|
+
onError({ response });
|
|
1612
|
+
return { type: String(response.status) };
|
|
1600
1613
|
}
|
|
1601
1614
|
else {
|
|
1602
|
-
onSuccess
|
|
1615
|
+
onSuccess({ response });
|
|
1603
1616
|
}
|
|
1604
1617
|
}
|
|
1605
1618
|
catch (error) {
|
|
1606
|
-
|
|
1607
|
-
|
|
1619
|
+
onError({ error });
|
|
1620
|
+
return { type: '' };
|
|
1608
1621
|
}
|
|
1609
1622
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1623
|
+
if (isFunction(action)) {
|
|
1624
|
+
try {
|
|
1625
|
+
await action(formData);
|
|
1626
|
+
}
|
|
1627
|
+
catch (error) {
|
|
1628
|
+
onError({ error });
|
|
1629
|
+
return { type: '' };
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
// Return nothing when successful.
|
|
1633
|
+
return;
|
|
1634
|
+
});
|
|
1619
1635
|
}, [
|
|
1620
1636
|
control,
|
|
1621
1637
|
onSubmit,
|
|
@@ -1627,15 +1643,28 @@ function Form(props) {
|
|
|
1627
1643
|
onError,
|
|
1628
1644
|
onSuccess,
|
|
1629
1645
|
]);
|
|
1646
|
+
const submit = React.useCallback(async (event) => {
|
|
1647
|
+
const err = await handleSubmit(event);
|
|
1648
|
+
if (err && control) {
|
|
1649
|
+
control._subjects.state.next({ isSubmitSuccessful: false });
|
|
1650
|
+
control.setError('root.server', err);
|
|
1651
|
+
}
|
|
1652
|
+
}, [handleSubmit, control]);
|
|
1630
1653
|
React.useEffect(() => {
|
|
1631
1654
|
setMounted(true);
|
|
1632
1655
|
}, []);
|
|
1633
|
-
|
|
1634
|
-
submit
|
|
1635
|
-
}
|
|
1656
|
+
if (render) {
|
|
1657
|
+
return render({ submit });
|
|
1658
|
+
}
|
|
1659
|
+
// React forbids passing `method`/`encType` alongside a function `action`
|
|
1660
|
+
// (a Server-Action-style submission) -- it manages those itself and warns
|
|
1661
|
+
// if they're present, so they're only rendered for string/URL actions.
|
|
1662
|
+
return (React.createElement("form", { noValidate: mounted, action: action, ...(!isFunction(action) && { method, encType }), onSubmit: submit, ...rest }, children));
|
|
1636
1663
|
}
|
|
1637
1664
|
|
|
1638
|
-
const
|
|
1665
|
+
const FormState = ({ control, disabled, exact, name, render, }) => render(useFormState({ control, name, disabled, exact }));
|
|
1666
|
+
/** @deprecated Use `FormState` instead. Kept as an alias for backward compatibility. */
|
|
1667
|
+
const FormStateSubscribe = FormState;
|
|
1639
1668
|
|
|
1640
1669
|
var createSubject = () => {
|
|
1641
1670
|
let _observers = [];
|
|
@@ -1691,6 +1720,24 @@ var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
|
|
1691
1720
|
|
|
1692
1721
|
var live = (ref) => isHTMLElement(ref) && ref.isConnected;
|
|
1693
1722
|
|
|
1723
|
+
function isDirtyContainer(value) {
|
|
1724
|
+
return Array.isArray(value) || isObject(value);
|
|
1725
|
+
}
|
|
1726
|
+
function collectDirtyFieldNames(dirtyTree, cachedDirtyFields, prefix = '', names = []) {
|
|
1727
|
+
for (const key in dirtyTree) {
|
|
1728
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
1729
|
+
const value = dirtyTree[key];
|
|
1730
|
+
if (isDirtyContainer(value) &&
|
|
1731
|
+
isDirtyContainer(get(cachedDirtyFields, path))) {
|
|
1732
|
+
collectDirtyFieldNames(value, cachedDirtyFields, path, names);
|
|
1733
|
+
}
|
|
1734
|
+
else {
|
|
1735
|
+
names.push(path);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
return names;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1694
1741
|
var objectHasFunction = (data) => {
|
|
1695
1742
|
for (const key in data) {
|
|
1696
1743
|
if (isFunction(data[key])) {
|
|
@@ -1794,7 +1841,7 @@ function getFieldValue(_f) {
|
|
|
1794
1841
|
if (isCheckBoxInput(ref)) {
|
|
1795
1842
|
return getCheckboxValue(_f.refs).value;
|
|
1796
1843
|
}
|
|
1797
|
-
return getFieldValueAs(
|
|
1844
|
+
return getFieldValueAs(ref.value, _f);
|
|
1798
1845
|
}
|
|
1799
1846
|
|
|
1800
1847
|
var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
|
|
@@ -1885,8 +1932,7 @@ function schemaErrorLookup(errors, _fields, name) {
|
|
|
1885
1932
|
|
|
1886
1933
|
var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
|
|
1887
1934
|
updateFormState(formStateData);
|
|
1888
|
-
const
|
|
1889
|
-
const keys = Object.keys(formState);
|
|
1935
|
+
const keys = Object.keys(formStateData).filter((key) => key !== 'name');
|
|
1890
1936
|
return (!keys.length ||
|
|
1891
1937
|
(isRoot && keys.length >= Object.keys(_proxyFormState).length) ||
|
|
1892
1938
|
keys.find((key) => _proxyFormState[key] ===
|
|
@@ -2437,6 +2483,12 @@ function createFormControl(props = {}) {
|
|
|
2437
2483
|
});
|
|
2438
2484
|
};
|
|
2439
2485
|
const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
|
|
2486
|
+
if (_names.array.has(name)) {
|
|
2487
|
+
_subjects.array.next({
|
|
2488
|
+
name,
|
|
2489
|
+
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2440
2492
|
for (const fieldKey in value) {
|
|
2441
2493
|
if (!value.hasOwnProperty(fieldKey)) {
|
|
2442
2494
|
return;
|
|
@@ -2972,6 +3024,7 @@ function createFormControl(props = {}) {
|
|
|
2972
3024
|
}
|
|
2973
3025
|
};
|
|
2974
3026
|
const handleSubmit = (onValid, onInvalid) => async (e) => {
|
|
3027
|
+
let result = undefined;
|
|
2975
3028
|
let onValidError = undefined;
|
|
2976
3029
|
if (e) {
|
|
2977
3030
|
e.preventDefault && e.preventDefault();
|
|
@@ -3005,7 +3058,7 @@ function createFormControl(props = {}) {
|
|
|
3005
3058
|
errors: {},
|
|
3006
3059
|
});
|
|
3007
3060
|
try {
|
|
3008
|
-
await onValid(fieldValues, e);
|
|
3061
|
+
result = await onValid(fieldValues, e);
|
|
3009
3062
|
}
|
|
3010
3063
|
catch (error) {
|
|
3011
3064
|
onValidError = error;
|
|
@@ -3028,6 +3081,7 @@ function createFormControl(props = {}) {
|
|
|
3028
3081
|
if (onValidError) {
|
|
3029
3082
|
throw onValidError;
|
|
3030
3083
|
}
|
|
3084
|
+
return result;
|
|
3031
3085
|
};
|
|
3032
3086
|
const resetField = (name, options = {}) => {
|
|
3033
3087
|
if (get(_fields, name)) {
|
|
@@ -3067,7 +3121,7 @@ function createFormControl(props = {}) {
|
|
|
3067
3121
|
if (keepStateOptions.keepDirtyValues) {
|
|
3068
3122
|
const fieldsToCheck = new Set([
|
|
3069
3123
|
..._names.mount,
|
|
3070
|
-
...
|
|
3124
|
+
...collectDirtyFieldNames(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs), _formState.dirtyFields),
|
|
3071
3125
|
]);
|
|
3072
3126
|
for (const fieldName of Array.from(fieldsToCheck)) {
|
|
3073
3127
|
const isDirty = get(_formState.dirtyFields, fieldName);
|
|
@@ -3496,5 +3550,5 @@ function useForm(props = {}) {
|
|
|
3496
3550
|
*/
|
|
3497
3551
|
const Watch = (props) => props.render(useWatch({ name: props.names, ...props }));
|
|
3498
3552
|
|
|
3499
|
-
export { Controller, FieldArray, Form, FormProvider, FormStateSubscribe, Watch, appendErrors, createFormControl, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
|
|
3553
|
+
export { Controller, FieldArray, Form, FormProvider, FormState, FormStateSubscribe, Watch, appendErrors, createFormControl, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
|
|
3500
3554
|
//# sourceMappingURL=index.esm.mjs.map
|