react-f0rm 0.5.1 → 0.6.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 +33 -0
- package/dist/{form-rTlcIiWH.d.ts → form-D9COEt0-.d.ts} +2 -2
- package/dist/index.cjs.js +13 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +23 -4
- package/dist/index.mjs +13 -5
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +13 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +2 -2
- package/dist/index.umd.min.js.map +1 -1
- package/dist/resolvers/yup.d.ts +1 -1
- package/dist/resolvers/zod.d.ts +1 -1
- package/dist/{validate-CQX7BJOD.d.ts → validate-Cu43SqhV.d.ts} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -349,6 +349,39 @@ const form = createForm({
|
|
|
349
349
|
});
|
|
350
350
|
```
|
|
351
351
|
|
|
352
|
+
#### Per-field mode override
|
|
353
|
+
|
|
354
|
+
Sometimes one field deserves a different schedule than the rest of the form — a signup form that validates on submit, except the email field whose check should fire as soon as the user leaves the input. Any field can declare its own `mode`: it replaces the form-level `mode` for that field only, while every other field keeps the form's timing.
|
|
355
|
+
|
|
356
|
+
```jsx
|
|
357
|
+
import {Form, Field, useForm} from 'react-f0rm';
|
|
358
|
+
|
|
359
|
+
function Register() {
|
|
360
|
+
// Form default: validate on submit.
|
|
361
|
+
const form = useForm({initialValues: {email: '', bio: ''}});
|
|
362
|
+
|
|
363
|
+
return (
|
|
364
|
+
<Form form={form}>
|
|
365
|
+
{/* This field alone validates on blur... */}
|
|
366
|
+
<Field name="email" mode="onBlur" validate={checkEmail} />
|
|
367
|
+
{/* ...while every other field waits for submit. */}
|
|
368
|
+
<Field name="bio" />
|
|
369
|
+
</Form>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
The same option exists on `useField` (and `Checkbox` / `Select`):
|
|
375
|
+
|
|
376
|
+
```jsx
|
|
377
|
+
const email = useField({name: 'email', mode: 'onBlur', validate: checkEmail});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
- Accepted values are the same `ValidationMode` union as the form's `mode`; omit it and the field follows `form.mode` exactly as before.
|
|
381
|
+
- Precedence is per field: `field.mode ?? form.mode`. A field cannot change another field's timing, and declaring `mode: 'onSubmit'` opts a field out of an `'onChange'` form.
|
|
382
|
+
- `reValidateMode` stays form-level for every field: once a field has an error (after a failed submit, say), re-validation follows the form's `reValidateMode` regardless of the field's own `mode` — a `mode: 'onBlur'` field with the default `reValidateMode: 'onChange'` still re-validates on every keystroke while errored.
|
|
383
|
+
- Manual `trigger` and submit validation are unaffected — they always run the field's validators regardless of any mode.
|
|
384
|
+
|
|
352
385
|
### Triggering validation manually
|
|
353
386
|
|
|
354
387
|
`trigger` runs field validators on demand. Without a name it runs every registered validator; a single name — or an array of names — narrows it to those fields:
|
|
@@ -603,5 +603,5 @@ interface SetFocusOptions {
|
|
|
603
603
|
*/
|
|
604
604
|
declare function setFocus(form: Form, name: Name, options?: SetFocusOptions): void;
|
|
605
605
|
|
|
606
|
-
export { setServerErrors as $, getValueByPath as A, getValues as B, handleSubmit as C, hasErrors as D, hasTouched as E, hasTouchedByPath as G, incrementSubmitCount as I, isDirty as J, isTouched as K, removeField as L, removeFieldByPath as M, reset as Q, resetField as T, setDisabled as U,
|
|
607
|
-
export type { Form as F, HandleSubmitOptions as H, Name as N, Options as O, PathValueOf as P, ReValidateMode as R, SetFieldOptions as S, FieldPath as a, FieldError as b, Path as c, FieldErrorEntry as d, FieldState as e, PathValue as f, ResetFieldOptions as g, ResetOptions as h, SetFocusOptions as i, SetServerErrorsOptions as j, ValidateResult as
|
|
606
|
+
export { setServerErrors as $, getValueByPath as A, getValues as B, handleSubmit as C, hasErrors as D, hasTouched as E, hasTouchedByPath as G, incrementSubmitCount as I, isDirty as J, isTouched as K, removeField as L, removeFieldByPath as M, reset as Q, resetField as T, setDisabled as U, setError as W, setErrorByPath as X, setFocus as Y, setInitialValues as Z, setIsSubmitting as _, setSubmitSuccessful as a0, setTouched as a1, setTouchedByPath as a2, setValidatingByPath as a3, setValue as a4, setValueByPath as a5, trigger as a6, unsetValidatingByPath as a7, validate as a8, VALIDATION_OUTCOME as k, clearErrors as n, create as o, ensureValidate as p, getDirtyFields as q, getError as r, getErrorByPath as s, getErrors as t, getFieldErrors as u, getFieldErrorsByPath as v, getFieldState as w, getFirstError as x, getTouchedFields as y, getValue as z };
|
|
607
|
+
export type { Form as F, HandleSubmitOptions as H, Name as N, Options as O, PathValueOf as P, ReValidateMode as R, SetFieldOptions as S, ValidationMode as V, FieldPath as a, FieldError as b, Path as c, FieldErrorEntry as d, FieldState as e, PathValue as f, ResetFieldOptions as g, ResetOptions as h, SetFocusOptions as i, SetServerErrorsOptions as j, ValidateResult as l, ValidationOutcome as m };
|
package/dist/index.cjs.js
CHANGED
|
@@ -1280,7 +1280,8 @@ function useFieldCore({
|
|
|
1280
1280
|
rules,
|
|
1281
1281
|
validateDebounce,
|
|
1282
1282
|
delayError,
|
|
1283
|
-
disabled
|
|
1283
|
+
disabled,
|
|
1284
|
+
mode: modeOption
|
|
1284
1285
|
}, Context) {
|
|
1285
1286
|
const contextForm = React.useContext(Context);
|
|
1286
1287
|
const form = f1 || contextForm;
|
|
@@ -1300,6 +1301,7 @@ function useFieldCore({
|
|
|
1300
1301
|
const error = errorObject?.message;
|
|
1301
1302
|
const value = useValueByPath(form, path);
|
|
1302
1303
|
const formDisabled = useWatch(form.emitter, "disabled", () => form.disabled);
|
|
1304
|
+
const mode = modeOption ?? form.mode;
|
|
1303
1305
|
React.useEffect(() => {
|
|
1304
1306
|
if (initialValue === void 0) return;
|
|
1305
1307
|
if (getValueByPath(form, path) === void 0) {
|
|
@@ -1308,12 +1310,12 @@ function useFieldCore({
|
|
|
1308
1310
|
}, [form, path, initialValue]);
|
|
1309
1311
|
const onChange = useStageFn((v) => {
|
|
1310
1312
|
setValueByPath(form, path, v);
|
|
1311
|
-
if (
|
|
1313
|
+
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || liveErrors.length > 0 && form.reValidateMode === "onChange")
|
|
1312
1314
|
validator();
|
|
1313
1315
|
});
|
|
1314
1316
|
const onBlur = useStageFn(() => {
|
|
1315
1317
|
setTouchedByPath(form, path);
|
|
1316
|
-
if (
|
|
1318
|
+
if (mode === "onBlur" || mode === "onTouched" || mode === "all" || liveErrors.length > 0 && form.reValidateMode === "onBlur")
|
|
1317
1319
|
validator();
|
|
1318
1320
|
});
|
|
1319
1321
|
React.useEffect(
|
|
@@ -1532,6 +1534,7 @@ const Field = React__namespace.forwardRef(
|
|
|
1532
1534
|
validateDebounce,
|
|
1533
1535
|
disabled,
|
|
1534
1536
|
delayError,
|
|
1537
|
+
mode,
|
|
1535
1538
|
...props
|
|
1536
1539
|
}, ref) => {
|
|
1537
1540
|
const innerRef = React__namespace.useRef(null);
|
|
@@ -1560,6 +1563,7 @@ const Field = React__namespace.forwardRef(
|
|
|
1560
1563
|
validateDebounce,
|
|
1561
1564
|
delayError,
|
|
1562
1565
|
disabled,
|
|
1566
|
+
mode,
|
|
1563
1567
|
validate: (...params) => {
|
|
1564
1568
|
const el = innerRef.current;
|
|
1565
1569
|
if (el && typeof el.checkValidity === "function") {
|
|
@@ -1633,6 +1637,7 @@ const Checkbox = React__namespace.forwardRef(
|
|
|
1633
1637
|
validateDebounce,
|
|
1634
1638
|
disabled,
|
|
1635
1639
|
delayError,
|
|
1640
|
+
mode,
|
|
1636
1641
|
...props
|
|
1637
1642
|
}, ref) => {
|
|
1638
1643
|
const {
|
|
@@ -1651,7 +1656,8 @@ const Checkbox = React__namespace.forwardRef(
|
|
|
1651
1656
|
rules,
|
|
1652
1657
|
validateDebounce,
|
|
1653
1658
|
delayError,
|
|
1654
|
-
disabled
|
|
1659
|
+
disabled,
|
|
1660
|
+
mode
|
|
1655
1661
|
});
|
|
1656
1662
|
return /* @__PURE__ */ React__namespace.createElement(
|
|
1657
1663
|
"input",
|
|
@@ -1687,6 +1693,7 @@ const Select = React__namespace.forwardRef(
|
|
|
1687
1693
|
validateDebounce,
|
|
1688
1694
|
disabled,
|
|
1689
1695
|
delayError,
|
|
1696
|
+
mode,
|
|
1690
1697
|
...props
|
|
1691
1698
|
}, ref) => {
|
|
1692
1699
|
const {
|
|
@@ -1705,7 +1712,8 @@ const Select = React__namespace.forwardRef(
|
|
|
1705
1712
|
rules,
|
|
1706
1713
|
validateDebounce,
|
|
1707
1714
|
delayError,
|
|
1708
|
-
disabled
|
|
1715
|
+
disabled,
|
|
1716
|
+
mode
|
|
1709
1717
|
});
|
|
1710
1718
|
return /* @__PURE__ */ React__namespace.createElement(
|
|
1711
1719
|
"select",
|