react-f0rm 0.8.0 → 0.10.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 +90 -4
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.mjs +1 -1
- package/dist/{form-B2pyaLdK.d.ts → form-BNqHYba-.d.ts} +72 -9
- package/dist/form-BQsb2CuG.mjs +2 -0
- package/dist/form-BQsb2CuG.mjs.map +1 -0
- package/dist/form-DZK8HgZ7.cjs.js +2 -0
- package/dist/form-DZK8HgZ7.cjs.js.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +102 -14
- 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/standard-schema.cjs.js +1 -1
- package/dist/resolvers/standard-schema.mjs +1 -1
- package/dist/resolvers/yup.cjs.js +1 -1
- package/dist/resolvers/yup.d.ts +1 -1
- package/dist/resolvers/yup.mjs +1 -1
- package/dist/resolvers/zod.cjs.js +1 -1
- package/dist/resolvers/zod.d.ts +1 -1
- package/dist/resolvers/zod.mjs +1 -1
- package/dist/{validate-BhOEz8BS.d.ts → validate-CbteZ-Jb.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/form-DnM4ONxf.cjs.js +0 -2
- package/dist/form-DnM4ONxf.cjs.js.map +0 -1
- package/dist/form-O5yKsVPM.mjs +0 -2
- package/dist/form-O5yKsVPM.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
A headless, event-driven React form library with field-level subscriptions.
|
|
9
9
|
|
|
10
|
+
Coming from TanStack Form? [Migrating from TanStack Form](./docs/from-tanstack-form.md) is the one-page concept map — the core mapping table, known differences, and common pitfalls.
|
|
11
|
+
|
|
10
12
|
## Features
|
|
11
13
|
|
|
12
14
|
- **Field-level subscriptions.** Editing one field re-renders exactly that field's component, not the whole form. State is read through `useSyncExternalStore`, so snapshots stay consistent under concurrent rendering (no tearing).
|
|
@@ -70,7 +72,7 @@ react-f0rm vs the established options. react-f0rm figures come from this repo (s
|
|
|
70
72
|
| Async validation | `validateDebounce` per field + `meta.signal` (`AbortSignal`) handed to every validator — superseded rounds cancel their in-flight work; pending debounce counts as validating so submit waits | Async validators supported, but no built-in debounce and no cancellation signal — both are hand-rolled per project | Built in: `asyncDebounceMs` debounces and the validator meta carries an `AbortSignal` | Async `validate` supported; no debounce, no signal |
|
|
71
73
|
| Multiple errors per field | Native: every field holds `FieldError[]`; `getFieldErrors`/`useFieldErrors` read them; resolvers forward every schema issue | `criteriaMode: 'all'` collects all failing rules per field | Errors are arrays of messages per field | — |
|
|
72
74
|
| SSR / hydration | `renderToString` renders initial values out of the box; server snapshot matches the client's first render | SSR-safe | SSR-safe | SSR-safe |
|
|
73
|
-
| React 19 / Server Actions | Bridge pattern: dispatch the action from `onValidSubmit` via `startTransition`/`useActionState`, passing the values object rather than FormData (see the React 19 Server Actions guide); no submit before JS loads | `<Form>` accepts a function `action` prop (server-action-style submit) since v7.84, and ships a `react-server` export | Documented server action integration (`createServerValidate` for server-side validation, Next.js examples) | — |
|
|
75
|
+
| React 19 / Server Actions | Bridge pattern: dispatch the action from `onValidSubmit` via `startTransition`/`useActionState`, passing the values object rather than FormData (see the stance above and the React 19 Server Actions guide); no submit before JS loads — first-class `action` prop support is not on the 0.x roadmap | `<Form>` accepts a function `action` prop (server-action-style submit) since v7.84, and ships a `react-server` export | Documented server action integration (`createServerValidate` for server-side validation, Next.js examples) | — |
|
|
74
76
|
| Bundle size | 11.18 KB gzip (7.1 KB brotli, minified), full core | ~11 KB gzip | ~17.5 KB gzip | ~12.8 KB gzip |
|
|
75
77
|
| Devtools | `<Devtools />` from `react-f0rm/devtools` — separate entry point, tree-shakeable, never lands in the main bundle | `@hookform/devtools` (separate package) | Built-in devtools panel | None (official) |
|
|
76
78
|
| Ecosystem maturity | New, 0.x — small audience, few integrations so far | Most mature: massive adoption, resolvers, UI-kit integrations, abundant examples and answers | Backed by the TanStack family, actively growing | Maintenance mode; the author recommends considering RHF or Final Form for new projects |
|
|
@@ -83,6 +85,8 @@ Bundle-size basis: every column is gzip. react-f0rm is measured on the local bui
|
|
|
83
85
|
|
|
84
86
|
**Pick React Hook Form** when uncontrolled inputs are an option: its raw `register` performs no per-field re-render at all and floors at 21µs/change vs our 113µs (see [Benchmarks](#benchmarks)) — uncontrolled is simply a cheaper rendering model. RHF is also the right call when you need its mature ecosystem of resolvers, UI-library integrations and community answers today. TanStack Form sits in between: choose it when the deepest possible type inference (including validator signatures) matters more to you than bundle size.
|
|
85
87
|
|
|
88
|
+
**Server Actions: bridge, not first-class.** RHF-style `action` prop support, a `react-server` entry point, or a TanStack-style `createServerValidate` helper are **not on the 0.x roadmap** — a deliberate stance, not a gap. react-f0rm's source of truth is the values store, not the DOM: an `action`-prop submit would ship FormData keyed by JSON-stringified path keys, drop every store-only value, and skip the validation gate entirely (the [React 19 Server Actions guide](docs-site/docs/guides/react19-server-actions.md) unpacks all four failure modes). The recommended shape is the bridge — dispatch from `onValidSubmit` via `startTransition`/`useActionState`, passing the values object rather than FormData — which keeps validation gating the action and types/nesting intact. If submitting without JavaScript loaded is a hard requirement, RHF's `action` prop support is the better fit today.
|
|
89
|
+
|
|
86
90
|
## Usage
|
|
87
91
|
|
|
88
92
|
```jsx
|
|
@@ -466,7 +470,7 @@ setError(form, 'password', [
|
|
|
466
470
|
|
|
467
471
|
### `setValue` options
|
|
468
472
|
|
|
469
|
-
The fourth argument to `setValue` opts into side effects.
|
|
473
|
+
The fourth argument to `setValue` opts into side effects. `shouldValidate`/`shouldTouch` default to `false`; omitting the object keeps the plain set-value behavior:
|
|
470
474
|
|
|
471
475
|
```jsx
|
|
472
476
|
import {setValue} from 'react-f0rm';
|
|
@@ -474,10 +478,24 @@ import {setValue} from 'react-f0rm';
|
|
|
474
478
|
setValue(form, 'email', 'a@b.com', {
|
|
475
479
|
shouldValidate: true, // run the field's registered validator after the value lands
|
|
476
480
|
shouldTouch: true, // mark the field as touched
|
|
477
|
-
shouldDirty:
|
|
481
|
+
shouldDirty: false // land the value as a commit: it becomes the field's dirty baseline
|
|
478
482
|
});
|
|
479
483
|
```
|
|
480
484
|
|
|
485
|
+
Dirty state is derived, not marked: a field is dirty while its live value differs from `initialValues` (reverting to the initial value makes it clean again). That makes `shouldDirty` a one-sided flag. `shouldDirty: false` declares this write a **commit instead of an edit** — the written value becomes that field's dirty-comparison baseline, so `getDirtyFields`/`isDirty`/`getFieldState().isDirty` read the field as clean immediately, and a later write dirties it only by differing from the new baseline:
|
|
486
|
+
|
|
487
|
+
```jsx
|
|
488
|
+
setValue(form, 'email', 'normalized@x.com', {shouldDirty: false});
|
|
489
|
+
getDirtyFields(form); // {} — the normalization is not a user edit
|
|
490
|
+
|
|
491
|
+
setValue(form, 'email', 'normalized@x.com'); // still clean: equal to the baseline
|
|
492
|
+
setValue(form, 'email', 'a@b.com'); // dirty: differs from it
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Use it whenever a programmatic write is not user input — normalized/formatted values, autofill, defaults applied after mount — and you don't want it to trip the "unsaved changes" state. `shouldDirty: true` (or omitting the flag) is the default derived behavior spelled out; unlike react-hook-form, where `setValue` skips dirty marking unless opted in, react-f0rm always derives dirty from the comparison and `false` is the opt-out.
|
|
496
|
+
|
|
497
|
+
Committed baselines follow the form's lifecycle: `reset`, `setInitialValues` and `resetField`/`removeField` drop them (the state they measured against is gone), and a wholesale write at an ancestor path — a `useFieldArray` rewrite, say — drops baselines beneath it, since the subtree they were committed against no longer exists.
|
|
498
|
+
|
|
481
499
|
### Writing as a user change (`changeValue`)
|
|
482
500
|
|
|
483
501
|
`setValue` is the imperative channel — `shouldValidate` kicks the field's validator unconditionally, ignoring any mode. `changeValue` is the user-change channel: the write routes through the mounted field's own `onChange`, so it fires exactly the validation a user typing into the field would fire — the field's effective `mode` (per-field override included) and the form's `reValidateMode`. With no mounted field on the path it degrades to a plain `setValue`.
|
|
@@ -492,6 +510,12 @@ changeValue(form, 'email', 'a@b.com');
|
|
|
492
510
|
|
|
493
511
|
This is the channel component libraries need when they hand a control a plain setter bound to a field (a `Control`/controlled-bridge over `useField`'s value): the mode gating — per-field override and live-error view — lives inside `useField`'s `onChange` closure and cannot be rebuilt from public form state, so `useField` publishes its `onChange` on the form (`form.changeHandlers`) and `changeValue`/`changeValueByPath` route through it.
|
|
494
512
|
|
|
513
|
+
`changeValue` takes the same options object as `setValue` (see [`setValue` options](#setvalue-options)). With a field mounted on the path, `shouldDirty: false` applies — the write lands as a commit while the field's own mode gating keeps driving validation, which is the point of this channel (`shouldValidate`/`shouldTouch` have no meaning there: forcing them would defeat the gating). With no mounted field, the options forward to the plain `setValue` fallback wholesale:
|
|
514
|
+
|
|
515
|
+
```jsx
|
|
516
|
+
changeValue(form, 'email', 'normalized@x.com', {shouldDirty: false});
|
|
517
|
+
```
|
|
518
|
+
|
|
495
519
|
### Field-level validation
|
|
496
520
|
|
|
497
521
|
Pass a `validate` function to `Field` or `useField`. Return an error string, a `FieldError` object or `undefined` — sync or async:
|
|
@@ -576,6 +600,39 @@ const form = useForm({
|
|
|
576
600
|
|
|
577
601
|
The `AbortSignal` fires as soon as the round is superseded — a newer round started, which under a positive `validateDebounce` means a kick landed during the in-flight round's window — so async validators can cancel their underlying work instead of racing a stale result home. Stale results are dropped independently by the round gate, so validators that ignore the signal stay correct too. Without `validateDebounce` (`0`/omitted) the validate runs once per `trigger`/submit exactly as before; it still receives the meta argument, but nothing supersedes an immediate round, so its signal never fires.
|
|
578
602
|
|
|
603
|
+
#### Re-running on dependent field changes (`validateDeps`)
|
|
604
|
+
|
|
605
|
+
By default the form-level `validate` runs on `trigger` and submit only — a cross-field error stays on screen even after the user edits the field that would fix it. `validateDeps` declares the fields whose **user changes re-run the form-level `validate`**:
|
|
606
|
+
|
|
607
|
+
```jsx
|
|
608
|
+
const form = useForm({
|
|
609
|
+
initialValues: {password: '', confirm: ''},
|
|
610
|
+
validate: values =>
|
|
611
|
+
values.password !== values.confirm
|
|
612
|
+
? {confirm: 'Passwords do not match'}
|
|
613
|
+
: {},
|
|
614
|
+
validateDeps: ['password']
|
|
615
|
+
});
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
Now the submit-then-fix flow works: submit lands the mismatch on `confirm`, editing `password` re-runs the validate, and the passing round makes the error disappear. The re-run timing rides the same mode matrix as any field validator, evaluated against the changed field's effective `mode` (per-field override included) and the form's `reValidateMode`:
|
|
619
|
+
|
|
620
|
+
| Situation | Dep change re-runs the form validate? |
|
|
621
|
+
|---|---|
|
|
622
|
+
| `mode: 'onChange'` / `'all'` (form or the dep field) | yes, error state or not |
|
|
623
|
+
| `mode: 'onTouched'`, dep field touched | yes |
|
|
624
|
+
| otherwise, the last round's error is live **and** `reValidateMode: 'onChange'` (default) | yes — the submit-then-fix flow |
|
|
625
|
+
| `reValidateMode: 'onBlur'` / `'onSubmit'` | no — a change is not a blur; re-runs wait for their own trigger |
|
|
626
|
+
|
|
627
|
+
Details that fall out of the plumbing:
|
|
628
|
+
|
|
629
|
+
- **User changes only.** The kick rides the mounted field's own change pipeline, so typing and `changeValue` (component-library bridges) both fire it, while programmatic `setValue` does not — exactly like field validators. A dep path with no mounted field never re-runs the validate.
|
|
630
|
+
- **Round-scoped error ownership.** Opting in changes what a re-run may clear: each round first drops the errors the *previous round* wrote, then lands its own result — so a passing re-run clears the stale mismatch. Errors the round never wrote (field validators', `setServerErrors`, manual `setError`) survive it, and a foreign write onto a round-owned path takes the key out of the round's ownership.
|
|
631
|
+
- **`validateDebounce` applies.** Dep-change kicks are ordinary kicks: they merge inside the debounce window like `trigger`/submit kicks do.
|
|
632
|
+
- Forms that don't set `validateDeps` keep the historical behavior untouched — the form validate runs on `trigger`/submit only, and re-runs never clear earlier errors.
|
|
633
|
+
|
|
634
|
+
TanStack Form's counterpart is `onChangeListenTo` (v1) / validator `triggers` (v2 alpha); both re-run a validator when listed fields change. react-f0rm keeps the declaration at the form level (the validate belongs to the form) and gates the re-run by the library's own `mode`/`reValidateMode` semantics instead of adding an always-on listener.
|
|
635
|
+
|
|
579
636
|
### Schema validation
|
|
580
637
|
|
|
581
638
|
Any library implementing [Standard Schema v1](https://standardschema.dev) — zod v3.24+/v4, valibot v1, arktype and more — works through one adapter, imported from its own tree-shakeable entry point:
|
|
@@ -607,6 +664,35 @@ Schema errors come back as `{type: 'standard', message}`.
|
|
|
607
664
|
|
|
608
665
|
On success the adapter returns the schema's parsed output, which the form stores as its `parsedValues` baseline: `getValues()` and submit callbacks (`onSubmit`/`onValidSubmit`) read coerced/transformed values — `z.coerce.number()` hands back a real `number`, not the raw string. The baseline sits between `initialValues` and live edits, so fields the user changes afterwards still win, and dirty state keeps comparing live edits against `initialValues` only — parsing never marks a field dirty. `reset()` and `setInitialValues()` clear the baseline.
|
|
609
666
|
|
|
667
|
+
#### Schema defaults
|
|
668
|
+
|
|
669
|
+
**Standard Schema v1 has no default-value metadata.** The interface carries types and `validate` and nothing else — whether a field declares a default, and how to read it, is vendor territory: zod v3.24 exposes `.getDefault()` per field, zod v4 wraps defaulted fields in a `ZodDefault` whose `.def.defaultValue` is a de-facto-public field rather than a documented accessor, valibot ships a `getDefault` util. None of it is reachable through the standard surface, and react-f0rm reads schemas only through `~standard.validate` — probing `schema.shape`/`.def` internals per vendor is exactly the adapter-per-library tree this library refuses to grow. So `defaultValues` derived from a schema is deliberately **not** a library feature: pass `initialValues` explicitly.
|
|
670
|
+
|
|
671
|
+
What you do get for free: defaults flow through `validate`. A schema's parsed output contains every declared default, so after the first successful validation the `parsedValues` baseline already serves them — `getValues()` reads `z.string().default('anon')` fields as `'anon'` without any seeding. The gap is only the render before the first validation round, and two recipes close it user-side:
|
|
672
|
+
|
|
673
|
+
```jsx
|
|
674
|
+
// 1. Vendor-neutral: one parse of an empty object materializes every
|
|
675
|
+
// default the schema declares (nested ones included).
|
|
676
|
+
const result = schema['~standard'].validate({});
|
|
677
|
+
const initialValues = result.issues ? {} : result.value;
|
|
678
|
+
|
|
679
|
+
const form = useForm({initialValues, validate: standardSchemaFormValidator(schema)});
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
The empty parse succeeds only where defaults cover everything; a required field without a default fails it, and `{}` is the honest seed in that case. For per-field extraction instead of a whole-object parse, do it through the vendor's own API — zod v4:
|
|
683
|
+
|
|
684
|
+
```jsx
|
|
685
|
+
// 2. zod v4: ZodDefault wrappers expose their default on .def
|
|
686
|
+
const defaultValues = Object.fromEntries(
|
|
687
|
+
Object.entries(schema.shape).map(([key, field]) => [
|
|
688
|
+
key,
|
|
689
|
+
field.def?.type === 'default' ? field.def.defaultValue : undefined
|
|
690
|
+
])
|
|
691
|
+
);
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
(zod v3.24: the same loop calling `field.getDefault()`. That this loop is version-specific is the point — it is your schema and your vendor, not the form library's, contract to maintain.)
|
|
695
|
+
|
|
610
696
|
### Delaying error display
|
|
611
697
|
|
|
612
698
|
`delayError` (milliseconds) holds a newly appearing error back from the render for a short window — users typing through a field are not interrupted by an error the next keystroke may already fix:
|
|
@@ -846,7 +932,7 @@ const html = renderToString(<ProfileForm initialValues={{name: 'ada', city: 'lon
|
|
|
846
932
|
|
|
847
933
|
## Migrating
|
|
848
934
|
|
|
849
|
-
Coming from another library? Step-by-step migration guides live in the docs site:
|
|
935
|
+
Coming from another library? [Migrating from TanStack Form](./docs/from-tanstack-form.md) is the repo-level concept map — core mapping table, known differences, common pitfalls. Step-by-step migration guides live in the docs site:
|
|
850
936
|
|
|
851
937
|
- [Migrating from Formik](docs-site/docs/migration/from-formik.md)
|
|
852
938
|
- [Migrating from React Hook Form](docs-site/docs/migration/from-react-hook-form.md)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react"),t=require("../form-DnM4ONxf.cjs.js");function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var r,o=n(e),a={exports:{}},l={};var s,i,d={};var c=(i||(i=1,"production"===process.env.NODE_ENV?a.exports=function(){if(r)return l;r=1;var t=e,n="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=t.useState,a=t.useEffect,s=t.useLayoutEffect,i=t.useDebugValue;function d(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!n(e,r)}catch(e){return!0}}var c="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=o({inst:{value:n,getSnapshot:t}}),l=r[0].inst,c=r[1];return s(function(){l.value=n,l.getSnapshot=t,d(l)&&c({inst:l})},[e,n,t]),a(function(){return d(l)&&c({inst:l}),e(function(){d(l)&&c({inst:l})})},[e]),i(n),n};return l.useSyncExternalStore=void 0!==t.useSyncExternalStore?t.useSyncExternalStore:c,l}():a.exports=(s||(s=1,"production"!==process.env.NODE_ENV&&function(){function t(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch(e){return!0}}"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var n=e,r="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=n.useState,a=n.useEffect,l=n.useLayoutEffect,s=n.useDebugValue,i=!1,c=!1,f="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,d){i||void 0===n.startTransition||(i=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var f=d();if(!c){var p=d();r(f,p)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),c=!0)}var u=(p=o({inst:{value:f,getSnapshot:d}}))[0].inst,m=p[1];return l(function(){u.value=f,u.getSnapshot=d,t(u)&&m({inst:u})},[e,f,d]),a(function(){return t(u)&&m({inst:u}),e(function(){t(u)&&m({inst:u})})},[e]),s(f),f};d.useSyncExternalStore=void 0!==n.useSyncExternalStore?n.useSyncExternalStore:f,"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),d)),a.exports);function f(n,r,o){return function(t,n){const r=e.useRef(null);null===r.current&&(r.current={hasValue:!1});const o=r.current,a=e.useRef(n);a.current=n;const l=e.useCallback(()=>(o.hasValue||(o.value=a.current(),o.hasValue=!0),o.value),[o]),s=e.useCallback(e=>(o.hasValue=!1,t(()=>{o.hasValue=!1,e()})),[t,o]);return c.useSyncExternalStore(s,l,l)}(e.useCallback(e=>t.on(n,r,e),[n,r]),o)}const p=e.createContext(null);p.Provider;e.createContext(null).Provider;function u({name:t,value:n,depth:r=0}){const[a,l]=e.useState(r<=1),s=void 0===t?null:o.createElement(o.Fragment,null,o.createElement("span",{className:"rf0-dt-key"},String(t)),o.createElement("span",{className:"rf0-dt-punct"},": "));if(null!==n&&"object"==typeof n){const e=Array.isArray(n),t=e?n.map((e,t)=>[t,e]):Object.entries(n),i=e?"[":"{",d=e?"]":"}",c=a?"":`${i}…${d} ${t.length}`;return o.createElement("div",{className:"rf0-dt-row",style:{paddingLeft:12*r}},o.createElement("button",{type:"button",className:"rf0-dt-node-toggle","aria-expanded":a,onClick:()=>l(!a)},o.createElement("span",{className:"rf0-dt-caret"},a?"▾":"▸"),s,o.createElement("span",{className:"rf0-dt-punct"},a?i:c)),a&&o.createElement(o.Fragment,null,t.map(([e,t])=>o.createElement(u,{key:String(e),name:e,value:t,depth:r+1})),o.createElement("span",{className:"rf0-dt-punct",style:{paddingLeft:12*r}},d)))}return o.createElement("span",{className:"rf0-dt-row",style:{paddingLeft:12*r,display:"block"}},s,o.createElement(m,{value:n}))}function m({value:e}){return void 0===e?o.createElement("span",{className:"rf0-dt-null"},"undefined"):null===e?o.createElement("span",{className:"rf0-dt-null"},"null"):"string"==typeof e?o.createElement("span",{className:"rf0-dt-string"},'"',e,'"'):"boolean"==typeof e?o.createElement("span",{className:"rf0-dt-boolean"},String(e)):o.createElement("span",{className:"rf0-dt-number"},String(e))}const b="react-f0rm-devtools-style";!function(){if("undefined"==typeof document)return;if(document.getElementById(b))return;const e=document.createElement("style");e.id=b,e.textContent="\n.rf0-dt {\n position: fixed;\n z-index: 2147483000;\n box-sizing: border-box;\n width: 308px;\n max-width: calc(100vw - 16px);\n max-height: min(70vh, 560px);\n display: flex;\n flex-direction: column;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 11px;\n line-height: 1.45;\n color: #c7d0dc;\n background: #0c1017;\n border: 1px solid #1f2735;\n border-radius: 4px;\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.4);\n}\n.rf0-dt *,\n.rf0-dt-badge * {\n box-sizing: border-box;\n}\n.rf0-dt--top-right { top: 8px; right: 8px; }\n.rf0-dt--bottom-right { bottom: 8px; right: 8px; }\n.rf0-dt--top-left { top: 8px; left: 8px; }\n.rf0-dt--bottom-left { bottom: 8px; left: 8px; }\n\n/* ---- header -------------------------------------------------------- */\n.rf0-dt-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 6px 5px 9px;\n border-bottom: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-title {\n flex: 1;\n min-width: 0;\n color: #8b96a5;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rf0-dt-title::before {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n margin-right: 6px;\n border-radius: 50%;\n background: #e2b93b;\n vertical-align: 1px;\n}\n.rf0-dt-headerbtn {\n border: 1px solid transparent;\n border-radius: 3px;\n padding: 1px 5px;\n color: #8b96a5;\n background: transparent;\n font: inherit;\n font-size: 10px;\n cursor: pointer;\n}\n.rf0-dt-headerbtn:hover { color: #dce3ec; border-color: #2a3547; }\n.rf0-dt-headerbtn:focus-visible,\n.rf0-dt-tab:focus-visible,\n.rf0-dt-action:focus-visible,\n.rf0-dt-badge:focus-visible,\n.rf0-dt-node-toggle:focus-visible {\n outline: 1px solid #e2b93b;\n outline-offset: 1px;\n}\n\n/* ---- tabs ---------------------------------------------------------- */\n.rf0-dt-tablist {\n display: flex;\n border-bottom: 1px solid #1f2735;\n background: #0e131b;\n}\n.rf0-dt-tab {\n flex: 1;\n padding: 4px 2px 5px;\n border: 0;\n border-bottom: 2px solid transparent;\n background: transparent;\n color: #6b7686;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n white-space: nowrap;\n}\n.rf0-dt-tab:hover { color: #aab5c4; }\n.rf0-dt-tab[aria-selected='true'] {\n color: #e7edf4;\n border-bottom-color: #e2b93b;\n}\n.rf0-dt-tab-count {\n margin-left: 3px;\n color: inherit;\n opacity: 0.75;\n}\n.rf0-dt-tab--danger[aria-selected='true'] {\n border-bottom-color: #f0647c;\n}\n\n/* ---- panels -------------------------------------------------------- */\n.rf0-dt-panel {\n flex: 1;\n min-height: 84px;\n overflow: auto;\n padding: 6px 8px;\n scrollbar-width: thin;\n scrollbar-color: #2a3547 transparent;\n}\n.rf0-dt-empty {\n padding: 10px 2px;\n color: #4d5766;\n font-style: italic;\n}\n\n/* json tree */\n.rf0-dt-row {\n display: block;\n white-space: pre;\n tab-size: 2;\n}\n.rf0-dt-node-toggle {\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n white-space: pre;\n}\n.rf0-dt-node-toggle:hover .rf0-dt-key { color: #dce3ec; }\n.rf0-dt-caret {\n display: inline-block;\n width: 1.2em;\n color: #4d5766;\n}\n.rf0-dt-key { color: #8b96a5; }\n.rf0-dt-punct { color: #4d5766; }\n.rf0-dt-string { color: #8fd68a; }\n.rf0-dt-number { color: #e2b93b; }\n.rf0-dt-boolean { color: #6fb3d9; }\n.rf0-dt-null { color: #55607080; font-style: italic; }\n\n/* errors / touched / dirty lists */\n.rf0-dt-item {\n padding: 3px 2px;\n border-bottom: 1px dotted #1a2230;\n display: flex;\n gap: 8px;\n align-items: baseline;\n}\n.rf0-dt-item:last-child { border-bottom: 0; }\n.rf0-dt-item-path {\n color: #aab5c4;\n word-break: break-all;\n}\n.rf0-dt-item-msg {\n color: #f0647c;\n word-break: break-word;\n}\n.rf0-dt-item-msg--ok { color: #8fd68a; }\n.rf0-dt-item-tag {\n flex: none;\n color: #4d5766;\n font-size: 10px;\n}\n.rf0-dt-item--touched .rf0-dt-item-path { color: #6fb3d9; }\n.rf0-dt-item--dirty .rf0-dt-item-path { color: #e2b93b; }\n\n/* ---- submit status + actions --------------------------------------- */\n.rf0-dt-status {\n display: flex;\n gap: 10px;\n padding: 4px 9px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n color: #6b7686;\n font-size: 10px;\n letter-spacing: 0.04em;\n white-space: nowrap;\n overflow: hidden;\n}\n.rf0-dt-status b { color: #aab5c4; font-weight: 400; }\n.rf0-dt-status .rf0-dt-on { color: #e2b93b; }\n.rf0-dt-status .rf0-dt-ok { color: #8fd68a; }\n.rf0-dt-status .rf0-dt-err { color: #f0647c; }\n.rf0-dt-actions {\n display: flex;\n gap: 6px;\n padding: 6px 8px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-action {\n flex: 1;\n padding: 3px 0;\n border: 1px solid #2a3547;\n border-radius: 3px;\n background: #151b26;\n color: #c7d0dc;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n}\n.rf0-dt-action:hover { border-color: #3b4a61; background: #1a2230; color: #e7edf4; }\n.rf0-dt-action:active { transform: translateY(1px); }\n\n/* ---- collapsed badge ----------------------------------------------- */\n.rf0-dt-badge {\n position: fixed;\n z-index: 2147483000;\n width: 26px;\n height: 26px;\n border: 1px solid #2a3547;\n border-radius: 50%;\n background: #0c1017;\n color: #e2b93b;\n font: inherit;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.02em;\n cursor: pointer;\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);\n}\n.rf0-dt-badge:hover { border-color: #e2b93b; }\n.rf0-dt-badge--top-right { top: 10px; right: 10px; }\n.rf0-dt-badge--bottom-right { bottom: 10px; right: 10px; }\n.rf0-dt-badge--top-left { top: 10px; left: 10px; }\n.rf0-dt-badge--bottom-left { bottom: 10px; left: 10px; }\n.rf0-dt-badge .rf0-dt-dot {\n position: absolute;\n top: 3px;\n right: 3px;\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: #f0647c;\n display: none;\n}\n.rf0-dt-badge--has-errors .rf0-dt-dot { display: block; }\n",document.head.appendChild(e)}();const g=["values","errors","touched","dirty"];function x(e){if(void 0!==e)return e?"rf0-dt-ok":"rf0-dt-err"}function h(e){if(null===e||"object"!=typeof e)return 1;let t=0;for(const n of Object.values(e))t+=h(n);return t}exports.Devtools=function({form:n,position:r="top-right"}){const a=e.useContext(p),l=n??a;if(!l)throw new Error("<Devtools> needs a form: pass the `form` prop or render it inside a <Form> / FormProvider.");const[s,i]=e.useState(!0),[d,c]=e.useState("values"),m=e.useId().replace(/[^a-zA-Z0-9-]/g,""),b=f(l.emitter,"change",t.getValues.bind(null,l)),y=f(l.emitter,"errors",t.getErrors.bind(null,l)),E=function(e){return f(e.emitter,"touched",t.getTouchedFields.bind(null,e))}(l),v=function(e){return f(e.emitter,"change",t.getDirtyFields.bind(null,e))}(l),w=function(e){return f(e.emitter,"submitting",()=>e.isSubmitting)}(l),k=function(e){return f(e.emitter,"submitCount",()=>e.submitCount)}(l),S=f(l.emitter,"submitSuccessful",()=>l.isSubmitSuccessful);if(!s)return o.createElement("button",{type:"button",className:`rf0-dt-badge rf0-dt-badge--${r}${y.length>0?" rf0-dt-badge--has-errors":""}`,"aria-expanded":!1,"aria-label":`Open react-f0rm devtools (${y.length} errors)`,onClick:()=>i(!0)},"f0",o.createElement("span",{className:"rf0-dt-dot"}));const O={values:h(b),errors:y.length,touched:E.length,dirty:Object.keys(v).length};return o.createElement("section",{className:`rf0-dt rf0-dt--${r}`,"aria-label":"react-f0rm devtools"},o.createElement("header",{className:"rf0-dt-header"},o.createElement("span",{className:"rf0-dt-title"},"react-f0rm"),o.createElement("button",{type:"button",className:"rf0-dt-headerbtn","aria-label":"Collapse devtools",onClick:()=>i(!1)},"–")),o.createElement("div",{className:"rf0-dt-tablist",role:"tablist","aria-label":"Form state",tabIndex:-1,onKeyDown:e=>{const t={ArrowRight:1,ArrowLeft:-1}[e.key];if(!t)return;e.preventDefault();const n=g[(g.indexOf(d)+t+g.length)%g.length];c(n),document.getElementById(`${m}-tab-${n}`)?.focus()}},g.map(e=>o.createElement("button",{key:e,id:`${m}-tab-${e}`,type:"button",role:"tab",className:"rf0-dt-tab"+("errors"===e?" rf0-dt-tab--danger":""),"aria-selected":d===e,"aria-controls":`${m}-panel-${e}`,tabIndex:d===e?0:-1,onClick:()=>c(e)},e,o.createElement("span",{className:"rf0-dt-tab-count"},O[e])))),o.createElement("div",{id:`${m}-panel-${d}`,role:"tabpanel","aria-labelledby":`${m}-tab-${d}`,className:"rf0-dt-panel"},"values"===d&&o.createElement(u,{value:b}),"errors"===d&&(0===y.length?o.createElement("p",{className:"rf0-dt-empty"},"no errors"):y.map(({path:e,type:t,message:n},r)=>o.createElement("div",{key:`${e}:${r}`,className:"rf0-dt-item"},o.createElement("span",{className:"rf0-dt-item-path"},e),o.createElement("span",{className:"rf0-dt-item-msg"},n),o.createElement("span",{className:"rf0-dt-item-tag"},t)))),"touched"===d&&(0===E.length?o.createElement("p",{className:"rf0-dt-empty"},"no touched fields"):E.map(e=>o.createElement("div",{key:e,className:"rf0-dt-item rf0-dt-item--touched"},o.createElement("span",{className:"rf0-dt-item-path"},e)))),"dirty"===d&&(0===Object.keys(v).length?o.createElement("p",{className:"rf0-dt-empty"},"no dirty fields"):Object.keys(v).map(e=>o.createElement("div",{key:e,className:"rf0-dt-item rf0-dt-item--dirty"},o.createElement("span",{className:"rf0-dt-item-path"},e),o.createElement("span",{className:"rf0-dt-item-msg rf0-dt-item-msg--ok"},"changed"))))),o.createElement("p",{className:"rf0-dt-status","aria-live":"polite"},o.createElement("span",{className:w?"rf0-dt-on":void 0},"submitting ",o.createElement("b",null,String(w))),o.createElement("span",null,"submits ",o.createElement("b",null,k)),o.createElement("span",{className:x(S)},"ok"," ",o.createElement("b",null,void 0===S?"–":String(S)))),o.createElement("div",{className:"rf0-dt-actions"},o.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>t.reset(l,l.initialValues)},"Reset"),o.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>t.trigger(l)},"Validate")))};
|
|
1
|
+
"use strict";var e=require("react"),t=require("../form-DZK8HgZ7.cjs.js");function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var r,o=n(e),a={exports:{}},l={};var s,i,d={};var c=(i||(i=1,"production"===process.env.NODE_ENV?a.exports=function(){if(r)return l;r=1;var t=e,n="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=t.useState,a=t.useEffect,s=t.useLayoutEffect,i=t.useDebugValue;function d(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!n(e,r)}catch(e){return!0}}var c="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=o({inst:{value:n,getSnapshot:t}}),l=r[0].inst,c=r[1];return s(function(){l.value=n,l.getSnapshot=t,d(l)&&c({inst:l})},[e,n,t]),a(function(){return d(l)&&c({inst:l}),e(function(){d(l)&&c({inst:l})})},[e]),i(n),n};return l.useSyncExternalStore=void 0!==t.useSyncExternalStore?t.useSyncExternalStore:c,l}():a.exports=(s||(s=1,"production"!==process.env.NODE_ENV&&function(){function t(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch(e){return!0}}"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var n=e,r="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=n.useState,a=n.useEffect,l=n.useLayoutEffect,s=n.useDebugValue,i=!1,c=!1,f="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,d){i||void 0===n.startTransition||(i=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var f=d();if(!c){var p=d();r(f,p)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),c=!0)}var u=(p=o({inst:{value:f,getSnapshot:d}}))[0].inst,m=p[1];return l(function(){u.value=f,u.getSnapshot=d,t(u)&&m({inst:u})},[e,f,d]),a(function(){return t(u)&&m({inst:u}),e(function(){t(u)&&m({inst:u})})},[e]),s(f),f};d.useSyncExternalStore=void 0!==n.useSyncExternalStore?n.useSyncExternalStore:f,"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),d)),a.exports);function f(n,r,o){return function(t,n){const r=e.useRef(null);null===r.current&&(r.current={hasValue:!1});const o=r.current,a=e.useRef(n);a.current=n;const l=e.useCallback(()=>(o.hasValue||(o.value=a.current(),o.hasValue=!0),o.value),[o]),s=e.useCallback(e=>(o.hasValue=!1,t(()=>{o.hasValue=!1,e()})),[t,o]);return c.useSyncExternalStore(s,l,l)}(e.useCallback(e=>t.on(n,r,e),[n,r]),o)}const p=e.createContext(null);p.Provider;e.createContext(null).Provider;function u({name:t,value:n,depth:r=0}){const[a,l]=e.useState(r<=1),s=void 0===t?null:o.createElement(o.Fragment,null,o.createElement("span",{className:"rf0-dt-key"},String(t)),o.createElement("span",{className:"rf0-dt-punct"},": "));if(null!==n&&"object"==typeof n){const e=Array.isArray(n),t=e?n.map((e,t)=>[t,e]):Object.entries(n),i=e?"[":"{",d=e?"]":"}",c=a?"":`${i}…${d} ${t.length}`;return o.createElement("div",{className:"rf0-dt-row",style:{paddingLeft:12*r}},o.createElement("button",{type:"button",className:"rf0-dt-node-toggle","aria-expanded":a,onClick:()=>l(!a)},o.createElement("span",{className:"rf0-dt-caret"},a?"▾":"▸"),s,o.createElement("span",{className:"rf0-dt-punct"},a?i:c)),a&&o.createElement(o.Fragment,null,t.map(([e,t])=>o.createElement(u,{key:String(e),name:e,value:t,depth:r+1})),o.createElement("span",{className:"rf0-dt-punct",style:{paddingLeft:12*r}},d)))}return o.createElement("span",{className:"rf0-dt-row",style:{paddingLeft:12*r,display:"block"}},s,o.createElement(m,{value:n}))}function m({value:e}){return void 0===e?o.createElement("span",{className:"rf0-dt-null"},"undefined"):null===e?o.createElement("span",{className:"rf0-dt-null"},"null"):"string"==typeof e?o.createElement("span",{className:"rf0-dt-string"},'"',e,'"'):"boolean"==typeof e?o.createElement("span",{className:"rf0-dt-boolean"},String(e)):o.createElement("span",{className:"rf0-dt-number"},String(e))}const b="react-f0rm-devtools-style";!function(){if("undefined"==typeof document)return;if(document.getElementById(b))return;const e=document.createElement("style");e.id=b,e.textContent="\n.rf0-dt {\n position: fixed;\n z-index: 2147483000;\n box-sizing: border-box;\n width: 308px;\n max-width: calc(100vw - 16px);\n max-height: min(70vh, 560px);\n display: flex;\n flex-direction: column;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 11px;\n line-height: 1.45;\n color: #c7d0dc;\n background: #0c1017;\n border: 1px solid #1f2735;\n border-radius: 4px;\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.4);\n}\n.rf0-dt *,\n.rf0-dt-badge * {\n box-sizing: border-box;\n}\n.rf0-dt--top-right { top: 8px; right: 8px; }\n.rf0-dt--bottom-right { bottom: 8px; right: 8px; }\n.rf0-dt--top-left { top: 8px; left: 8px; }\n.rf0-dt--bottom-left { bottom: 8px; left: 8px; }\n\n/* ---- header -------------------------------------------------------- */\n.rf0-dt-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 6px 5px 9px;\n border-bottom: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-title {\n flex: 1;\n min-width: 0;\n color: #8b96a5;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rf0-dt-title::before {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n margin-right: 6px;\n border-radius: 50%;\n background: #e2b93b;\n vertical-align: 1px;\n}\n.rf0-dt-headerbtn {\n border: 1px solid transparent;\n border-radius: 3px;\n padding: 1px 5px;\n color: #8b96a5;\n background: transparent;\n font: inherit;\n font-size: 10px;\n cursor: pointer;\n}\n.rf0-dt-headerbtn:hover { color: #dce3ec; border-color: #2a3547; }\n.rf0-dt-headerbtn:focus-visible,\n.rf0-dt-tab:focus-visible,\n.rf0-dt-action:focus-visible,\n.rf0-dt-badge:focus-visible,\n.rf0-dt-node-toggle:focus-visible {\n outline: 1px solid #e2b93b;\n outline-offset: 1px;\n}\n\n/* ---- tabs ---------------------------------------------------------- */\n.rf0-dt-tablist {\n display: flex;\n border-bottom: 1px solid #1f2735;\n background: #0e131b;\n}\n.rf0-dt-tab {\n flex: 1;\n padding: 4px 2px 5px;\n border: 0;\n border-bottom: 2px solid transparent;\n background: transparent;\n color: #6b7686;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n white-space: nowrap;\n}\n.rf0-dt-tab:hover { color: #aab5c4; }\n.rf0-dt-tab[aria-selected='true'] {\n color: #e7edf4;\n border-bottom-color: #e2b93b;\n}\n.rf0-dt-tab-count {\n margin-left: 3px;\n color: inherit;\n opacity: 0.75;\n}\n.rf0-dt-tab--danger[aria-selected='true'] {\n border-bottom-color: #f0647c;\n}\n\n/* ---- panels -------------------------------------------------------- */\n.rf0-dt-panel {\n flex: 1;\n min-height: 84px;\n overflow: auto;\n padding: 6px 8px;\n scrollbar-width: thin;\n scrollbar-color: #2a3547 transparent;\n}\n.rf0-dt-empty {\n padding: 10px 2px;\n color: #4d5766;\n font-style: italic;\n}\n\n/* json tree */\n.rf0-dt-row {\n display: block;\n white-space: pre;\n tab-size: 2;\n}\n.rf0-dt-node-toggle {\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n white-space: pre;\n}\n.rf0-dt-node-toggle:hover .rf0-dt-key { color: #dce3ec; }\n.rf0-dt-caret {\n display: inline-block;\n width: 1.2em;\n color: #4d5766;\n}\n.rf0-dt-key { color: #8b96a5; }\n.rf0-dt-punct { color: #4d5766; }\n.rf0-dt-string { color: #8fd68a; }\n.rf0-dt-number { color: #e2b93b; }\n.rf0-dt-boolean { color: #6fb3d9; }\n.rf0-dt-null { color: #55607080; font-style: italic; }\n\n/* errors / touched / dirty lists */\n.rf0-dt-item {\n padding: 3px 2px;\n border-bottom: 1px dotted #1a2230;\n display: flex;\n gap: 8px;\n align-items: baseline;\n}\n.rf0-dt-item:last-child { border-bottom: 0; }\n.rf0-dt-item-path {\n color: #aab5c4;\n word-break: break-all;\n}\n.rf0-dt-item-msg {\n color: #f0647c;\n word-break: break-word;\n}\n.rf0-dt-item-msg--ok { color: #8fd68a; }\n.rf0-dt-item-tag {\n flex: none;\n color: #4d5766;\n font-size: 10px;\n}\n.rf0-dt-item--touched .rf0-dt-item-path { color: #6fb3d9; }\n.rf0-dt-item--dirty .rf0-dt-item-path { color: #e2b93b; }\n\n/* ---- submit status + actions --------------------------------------- */\n.rf0-dt-status {\n display: flex;\n gap: 10px;\n padding: 4px 9px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n color: #6b7686;\n font-size: 10px;\n letter-spacing: 0.04em;\n white-space: nowrap;\n overflow: hidden;\n}\n.rf0-dt-status b { color: #aab5c4; font-weight: 400; }\n.rf0-dt-status .rf0-dt-on { color: #e2b93b; }\n.rf0-dt-status .rf0-dt-ok { color: #8fd68a; }\n.rf0-dt-status .rf0-dt-err { color: #f0647c; }\n.rf0-dt-actions {\n display: flex;\n gap: 6px;\n padding: 6px 8px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-action {\n flex: 1;\n padding: 3px 0;\n border: 1px solid #2a3547;\n border-radius: 3px;\n background: #151b26;\n color: #c7d0dc;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n}\n.rf0-dt-action:hover { border-color: #3b4a61; background: #1a2230; color: #e7edf4; }\n.rf0-dt-action:active { transform: translateY(1px); }\n\n/* ---- collapsed badge ----------------------------------------------- */\n.rf0-dt-badge {\n position: fixed;\n z-index: 2147483000;\n width: 26px;\n height: 26px;\n border: 1px solid #2a3547;\n border-radius: 50%;\n background: #0c1017;\n color: #e2b93b;\n font: inherit;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.02em;\n cursor: pointer;\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);\n}\n.rf0-dt-badge:hover { border-color: #e2b93b; }\n.rf0-dt-badge--top-right { top: 10px; right: 10px; }\n.rf0-dt-badge--bottom-right { bottom: 10px; right: 10px; }\n.rf0-dt-badge--top-left { top: 10px; left: 10px; }\n.rf0-dt-badge--bottom-left { bottom: 10px; left: 10px; }\n.rf0-dt-badge .rf0-dt-dot {\n position: absolute;\n top: 3px;\n right: 3px;\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: #f0647c;\n display: none;\n}\n.rf0-dt-badge--has-errors .rf0-dt-dot { display: block; }\n",document.head.appendChild(e)}();const g=["values","errors","touched","dirty"];function x(e){if(void 0!==e)return e?"rf0-dt-ok":"rf0-dt-err"}function h(e){if(null===e||"object"!=typeof e)return 1;let t=0;for(const n of Object.values(e))t+=h(n);return t}exports.Devtools=function({form:n,position:r="top-right"}){const a=e.useContext(p),l=n??a;if(!l)throw new Error("<Devtools> needs a form: pass the `form` prop or render it inside a <Form> / FormProvider.");const[s,i]=e.useState(!0),[d,c]=e.useState("values"),m=e.useId().replace(/[^a-zA-Z0-9-]/g,""),b=f(l.emitter,"change",t.getValues.bind(null,l)),y=f(l.emitter,"errors",t.getErrors.bind(null,l)),E=function(e){return f(e.emitter,"touched",t.getTouchedFields.bind(null,e))}(l),v=function(e){return f(e.emitter,"change",t.getDirtyFields.bind(null,e))}(l),w=function(e){return f(e.emitter,"submitting",()=>e.isSubmitting)}(l),k=function(e){return f(e.emitter,"submitCount",()=>e.submitCount)}(l),S=f(l.emitter,"submitSuccessful",()=>l.isSubmitSuccessful);if(!s)return o.createElement("button",{type:"button",className:`rf0-dt-badge rf0-dt-badge--${r}${y.length>0?" rf0-dt-badge--has-errors":""}`,"aria-expanded":!1,"aria-label":`Open react-f0rm devtools (${y.length} errors)`,onClick:()=>i(!0)},"f0",o.createElement("span",{className:"rf0-dt-dot"}));const O={values:h(b),errors:y.length,touched:E.length,dirty:Object.keys(v).length};return o.createElement("section",{className:`rf0-dt rf0-dt--${r}`,"aria-label":"react-f0rm devtools"},o.createElement("header",{className:"rf0-dt-header"},o.createElement("span",{className:"rf0-dt-title"},"react-f0rm"),o.createElement("button",{type:"button",className:"rf0-dt-headerbtn","aria-label":"Collapse devtools",onClick:()=>i(!1)},"–")),o.createElement("div",{className:"rf0-dt-tablist",role:"tablist","aria-label":"Form state",tabIndex:-1,onKeyDown:e=>{const t={ArrowRight:1,ArrowLeft:-1}[e.key];if(!t)return;e.preventDefault();const n=g[(g.indexOf(d)+t+g.length)%g.length];c(n),document.getElementById(`${m}-tab-${n}`)?.focus()}},g.map(e=>o.createElement("button",{key:e,id:`${m}-tab-${e}`,type:"button",role:"tab",className:"rf0-dt-tab"+("errors"===e?" rf0-dt-tab--danger":""),"aria-selected":d===e,"aria-controls":`${m}-panel-${e}`,tabIndex:d===e?0:-1,onClick:()=>c(e)},e,o.createElement("span",{className:"rf0-dt-tab-count"},O[e])))),o.createElement("div",{id:`${m}-panel-${d}`,role:"tabpanel","aria-labelledby":`${m}-tab-${d}`,className:"rf0-dt-panel"},"values"===d&&o.createElement(u,{value:b}),"errors"===d&&(0===y.length?o.createElement("p",{className:"rf0-dt-empty"},"no errors"):y.map(({path:e,type:t,message:n},r)=>o.createElement("div",{key:`${e}:${r}`,className:"rf0-dt-item"},o.createElement("span",{className:"rf0-dt-item-path"},e),o.createElement("span",{className:"rf0-dt-item-msg"},n),o.createElement("span",{className:"rf0-dt-item-tag"},t)))),"touched"===d&&(0===E.length?o.createElement("p",{className:"rf0-dt-empty"},"no touched fields"):E.map(e=>o.createElement("div",{key:e,className:"rf0-dt-item rf0-dt-item--touched"},o.createElement("span",{className:"rf0-dt-item-path"},e)))),"dirty"===d&&(0===Object.keys(v).length?o.createElement("p",{className:"rf0-dt-empty"},"no dirty fields"):Object.keys(v).map(e=>o.createElement("div",{key:e,className:"rf0-dt-item rf0-dt-item--dirty"},o.createElement("span",{className:"rf0-dt-item-path"},e),o.createElement("span",{className:"rf0-dt-item-msg rf0-dt-item-msg--ok"},"changed"))))),o.createElement("p",{className:"rf0-dt-status","aria-live":"polite"},o.createElement("span",{className:w?"rf0-dt-on":void 0},"submitting ",o.createElement("b",null,String(w))),o.createElement("span",null,"submits ",o.createElement("b",null,k)),o.createElement("span",{className:x(S)},"ok"," ",o.createElement("b",null,void 0===S?"–":String(S)))),o.createElement("div",{className:"rf0-dt-actions"},o.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>t.reset(l,l.initialValues)},"Reset"),o.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>t.trigger(l)},"Validate")))};
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/devtools/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as e from"react";import t,{useCallback as n,useRef as r,createContext as o,useState as a,useContext as l,useId as i}from"react";import{o as s,g as d,a as c,b as f,c as p,r as u,t as m}from"../form-O5yKsVPM.mjs";var b,g={exports:{}},x={};var h,E,y={};var v=(E||(E=1,"production"===process.env.NODE_ENV?g.exports=function(){if(b)return x;b=1;var e=t,n="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},r=e.useState,o=e.useEffect,a=e.useLayoutEffect,l=e.useDebugValue;function i(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!n(e,r)}catch(e){return!0}}var s="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),s=r({inst:{value:n,getSnapshot:t}}),d=s[0].inst,c=s[1];return a(function(){d.value=n,d.getSnapshot=t,i(d)&&c({inst:d})},[e,n,t]),o(function(){return i(d)&&c({inst:d}),e(function(){i(d)&&c({inst:d})})},[e]),l(n),n};return x.useSyncExternalStore=void 0!==e.useSyncExternalStore?e.useSyncExternalStore:s,x}():g.exports=(h||(h=1,"production"!==process.env.NODE_ENV&&function(){function e(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch(e){return!0}}"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var n=t,r="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=n.useState,a=n.useEffect,l=n.useLayoutEffect,i=n.useDebugValue,s=!1,d=!1,c="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(t,c){s||void 0===n.startTransition||(s=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var f=c();if(!d){var p=c();r(f,p)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),d=!0)}var u=(p=o({inst:{value:f,getSnapshot:c}}))[0].inst,m=p[1];return l(function(){u.value=f,u.getSnapshot=c,e(u)&&m({inst:u})},[t,f,c]),a(function(){return e(u)&&m({inst:u}),t(function(){e(u)&&m({inst:u})})},[t]),i(f),f};y.useSyncExternalStore=void 0!==n.useSyncExternalStore?n.useSyncExternalStore:c,"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),y)),g.exports);function w(e,t,o){return function(e,t){const o=r(null);null===o.current&&(o.current={hasValue:!1});const a=o.current,l=r(t);l.current=t;const i=n(()=>(a.hasValue||(a.value=l.current(),a.hasValue=!0),a.value),[a]),s=n(t=>(a.hasValue=!1,e(()=>{a.hasValue=!1,t()})),[e,a]);return v.useSyncExternalStore(s,i,i)}(n(n=>s(e,t,n),[e,t]),o)}const S=o(null);S.Provider;o(null).Provider;function k({name:t,value:n,depth:r=0}){const[o,l]=a(r<=1),i=void 0===t?null:e.createElement(e.Fragment,null,e.createElement("span",{className:"rf0-dt-key"},String(t)),e.createElement("span",{className:"rf0-dt-punct"},": "));if(null!==n&&"object"==typeof n){const t=Array.isArray(n),a=t?n.map((e,t)=>[t,e]):Object.entries(n),s=t?"[":"{",d=t?"]":"}",c=o?"":`${s}…${d} ${a.length}`;return e.createElement("div",{className:"rf0-dt-row",style:{paddingLeft:12*r}},e.createElement("button",{type:"button",className:"rf0-dt-node-toggle","aria-expanded":o,onClick:()=>l(!o)},e.createElement("span",{className:"rf0-dt-caret"},o?"▾":"▸"),i,e.createElement("span",{className:"rf0-dt-punct"},o?s:c)),o&&e.createElement(e.Fragment,null,a.map(([t,n])=>e.createElement(k,{key:String(t),name:t,value:n,depth:r+1})),e.createElement("span",{className:"rf0-dt-punct",style:{paddingLeft:12*r}},d)))}return e.createElement("span",{className:"rf0-dt-row",style:{paddingLeft:12*r,display:"block"}},i,e.createElement(N,{value:n}))}function N({value:t}){return void 0===t?e.createElement("span",{className:"rf0-dt-null"},"undefined"):null===t?e.createElement("span",{className:"rf0-dt-null"},"null"):"string"==typeof t?e.createElement("span",{className:"rf0-dt-string"},'"',t,'"'):"boolean"==typeof t?e.createElement("span",{className:"rf0-dt-boolean"},String(t)):e.createElement("span",{className:"rf0-dt-number"},String(t))}const _="react-f0rm-devtools-style";!function(){if("undefined"==typeof document)return;if(document.getElementById(_))return;const e=document.createElement("style");e.id=_,e.textContent="\n.rf0-dt {\n position: fixed;\n z-index: 2147483000;\n box-sizing: border-box;\n width: 308px;\n max-width: calc(100vw - 16px);\n max-height: min(70vh, 560px);\n display: flex;\n flex-direction: column;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 11px;\n line-height: 1.45;\n color: #c7d0dc;\n background: #0c1017;\n border: 1px solid #1f2735;\n border-radius: 4px;\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.4);\n}\n.rf0-dt *,\n.rf0-dt-badge * {\n box-sizing: border-box;\n}\n.rf0-dt--top-right { top: 8px; right: 8px; }\n.rf0-dt--bottom-right { bottom: 8px; right: 8px; }\n.rf0-dt--top-left { top: 8px; left: 8px; }\n.rf0-dt--bottom-left { bottom: 8px; left: 8px; }\n\n/* ---- header -------------------------------------------------------- */\n.rf0-dt-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 6px 5px 9px;\n border-bottom: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-title {\n flex: 1;\n min-width: 0;\n color: #8b96a5;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rf0-dt-title::before {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n margin-right: 6px;\n border-radius: 50%;\n background: #e2b93b;\n vertical-align: 1px;\n}\n.rf0-dt-headerbtn {\n border: 1px solid transparent;\n border-radius: 3px;\n padding: 1px 5px;\n color: #8b96a5;\n background: transparent;\n font: inherit;\n font-size: 10px;\n cursor: pointer;\n}\n.rf0-dt-headerbtn:hover { color: #dce3ec; border-color: #2a3547; }\n.rf0-dt-headerbtn:focus-visible,\n.rf0-dt-tab:focus-visible,\n.rf0-dt-action:focus-visible,\n.rf0-dt-badge:focus-visible,\n.rf0-dt-node-toggle:focus-visible {\n outline: 1px solid #e2b93b;\n outline-offset: 1px;\n}\n\n/* ---- tabs ---------------------------------------------------------- */\n.rf0-dt-tablist {\n display: flex;\n border-bottom: 1px solid #1f2735;\n background: #0e131b;\n}\n.rf0-dt-tab {\n flex: 1;\n padding: 4px 2px 5px;\n border: 0;\n border-bottom: 2px solid transparent;\n background: transparent;\n color: #6b7686;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n white-space: nowrap;\n}\n.rf0-dt-tab:hover { color: #aab5c4; }\n.rf0-dt-tab[aria-selected='true'] {\n color: #e7edf4;\n border-bottom-color: #e2b93b;\n}\n.rf0-dt-tab-count {\n margin-left: 3px;\n color: inherit;\n opacity: 0.75;\n}\n.rf0-dt-tab--danger[aria-selected='true'] {\n border-bottom-color: #f0647c;\n}\n\n/* ---- panels -------------------------------------------------------- */\n.rf0-dt-panel {\n flex: 1;\n min-height: 84px;\n overflow: auto;\n padding: 6px 8px;\n scrollbar-width: thin;\n scrollbar-color: #2a3547 transparent;\n}\n.rf0-dt-empty {\n padding: 10px 2px;\n color: #4d5766;\n font-style: italic;\n}\n\n/* json tree */\n.rf0-dt-row {\n display: block;\n white-space: pre;\n tab-size: 2;\n}\n.rf0-dt-node-toggle {\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n white-space: pre;\n}\n.rf0-dt-node-toggle:hover .rf0-dt-key { color: #dce3ec; }\n.rf0-dt-caret {\n display: inline-block;\n width: 1.2em;\n color: #4d5766;\n}\n.rf0-dt-key { color: #8b96a5; }\n.rf0-dt-punct { color: #4d5766; }\n.rf0-dt-string { color: #8fd68a; }\n.rf0-dt-number { color: #e2b93b; }\n.rf0-dt-boolean { color: #6fb3d9; }\n.rf0-dt-null { color: #55607080; font-style: italic; }\n\n/* errors / touched / dirty lists */\n.rf0-dt-item {\n padding: 3px 2px;\n border-bottom: 1px dotted #1a2230;\n display: flex;\n gap: 8px;\n align-items: baseline;\n}\n.rf0-dt-item:last-child { border-bottom: 0; }\n.rf0-dt-item-path {\n color: #aab5c4;\n word-break: break-all;\n}\n.rf0-dt-item-msg {\n color: #f0647c;\n word-break: break-word;\n}\n.rf0-dt-item-msg--ok { color: #8fd68a; }\n.rf0-dt-item-tag {\n flex: none;\n color: #4d5766;\n font-size: 10px;\n}\n.rf0-dt-item--touched .rf0-dt-item-path { color: #6fb3d9; }\n.rf0-dt-item--dirty .rf0-dt-item-path { color: #e2b93b; }\n\n/* ---- submit status + actions --------------------------------------- */\n.rf0-dt-status {\n display: flex;\n gap: 10px;\n padding: 4px 9px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n color: #6b7686;\n font-size: 10px;\n letter-spacing: 0.04em;\n white-space: nowrap;\n overflow: hidden;\n}\n.rf0-dt-status b { color: #aab5c4; font-weight: 400; }\n.rf0-dt-status .rf0-dt-on { color: #e2b93b; }\n.rf0-dt-status .rf0-dt-ok { color: #8fd68a; }\n.rf0-dt-status .rf0-dt-err { color: #f0647c; }\n.rf0-dt-actions {\n display: flex;\n gap: 6px;\n padding: 6px 8px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-action {\n flex: 1;\n padding: 3px 0;\n border: 1px solid #2a3547;\n border-radius: 3px;\n background: #151b26;\n color: #c7d0dc;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n}\n.rf0-dt-action:hover { border-color: #3b4a61; background: #1a2230; color: #e7edf4; }\n.rf0-dt-action:active { transform: translateY(1px); }\n\n/* ---- collapsed badge ----------------------------------------------- */\n.rf0-dt-badge {\n position: fixed;\n z-index: 2147483000;\n width: 26px;\n height: 26px;\n border: 1px solid #2a3547;\n border-radius: 50%;\n background: #0c1017;\n color: #e2b93b;\n font: inherit;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.02em;\n cursor: pointer;\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);\n}\n.rf0-dt-badge:hover { border-color: #e2b93b; }\n.rf0-dt-badge--top-right { top: 10px; right: 10px; }\n.rf0-dt-badge--bottom-right { bottom: 10px; right: 10px; }\n.rf0-dt-badge--top-left { top: 10px; left: 10px; }\n.rf0-dt-badge--bottom-left { bottom: 10px; left: 10px; }\n.rf0-dt-badge .rf0-dt-dot {\n position: absolute;\n top: 3px;\n right: 3px;\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: #f0647c;\n display: none;\n}\n.rf0-dt-badge--has-errors .rf0-dt-dot { display: block; }\n",document.head.appendChild(e)}();const O=["values","errors","touched","dirty"];function L(e){if(void 0!==e)return e?"rf0-dt-ok":"rf0-dt-err"}function C(e){if(null===e||"object"!=typeof e)return 1;let t=0;for(const n of Object.values(e))t+=C(n);return t}function $({form:t,position:n="top-right"}){const r=l(S),o=t??r;if(!o)throw new Error("<Devtools> needs a form: pass the `form` prop or render it inside a <Form> / FormProvider.");const[s,b]=a(!0),[g,x]=a("values"),h=i().replace(/[^a-zA-Z0-9-]/g,""),E=w(o.emitter,"change",f.bind(null,o)),y=w(o.emitter,"errors",p.bind(null,o)),v=function(e){return w(e.emitter,"touched",d.bind(null,e))}(o),N=function(e){return w(e.emitter,"change",c.bind(null,e))}(o),_=function(e){return w(e.emitter,"submitting",()=>e.isSubmitting)}(o),$=function(e){return w(e.emitter,"submitCount",()=>e.submitCount)}(o),A=w(o.emitter,"submitSuccessful",()=>o.isSubmitSuccessful);if(!s)return e.createElement("button",{type:"button",className:`rf0-dt-badge rf0-dt-badge--${n}${y.length>0?" rf0-dt-badge--has-errors":""}`,"aria-expanded":!1,"aria-label":`Open react-f0rm devtools (${y.length} errors)`,onClick:()=>b(!0)},"f0",e.createElement("span",{className:"rf0-dt-dot"}));const V={values:C(E),errors:y.length,touched:v.length,dirty:Object.keys(N).length};return e.createElement("section",{className:`rf0-dt rf0-dt--${n}`,"aria-label":"react-f0rm devtools"},e.createElement("header",{className:"rf0-dt-header"},e.createElement("span",{className:"rf0-dt-title"},"react-f0rm"),e.createElement("button",{type:"button",className:"rf0-dt-headerbtn","aria-label":"Collapse devtools",onClick:()=>b(!1)},"–")),e.createElement("div",{className:"rf0-dt-tablist",role:"tablist","aria-label":"Form state",tabIndex:-1,onKeyDown:e=>{const t={ArrowRight:1,ArrowLeft:-1}[e.key];if(!t)return;e.preventDefault();const n=O[(O.indexOf(g)+t+O.length)%O.length];x(n),document.getElementById(`${h}-tab-${n}`)?.focus()}},O.map(t=>e.createElement("button",{key:t,id:`${h}-tab-${t}`,type:"button",role:"tab",className:"rf0-dt-tab"+("errors"===t?" rf0-dt-tab--danger":""),"aria-selected":g===t,"aria-controls":`${h}-panel-${t}`,tabIndex:g===t?0:-1,onClick:()=>x(t)},t,e.createElement("span",{className:"rf0-dt-tab-count"},V[t])))),e.createElement("div",{id:`${h}-panel-${g}`,role:"tabpanel","aria-labelledby":`${h}-tab-${g}`,className:"rf0-dt-panel"},"values"===g&&e.createElement(k,{value:E}),"errors"===g&&(0===y.length?e.createElement("p",{className:"rf0-dt-empty"},"no errors"):y.map(({path:t,type:n,message:r},o)=>e.createElement("div",{key:`${t}:${o}`,className:"rf0-dt-item"},e.createElement("span",{className:"rf0-dt-item-path"},t),e.createElement("span",{className:"rf0-dt-item-msg"},r),e.createElement("span",{className:"rf0-dt-item-tag"},n)))),"touched"===g&&(0===v.length?e.createElement("p",{className:"rf0-dt-empty"},"no touched fields"):v.map(t=>e.createElement("div",{key:t,className:"rf0-dt-item rf0-dt-item--touched"},e.createElement("span",{className:"rf0-dt-item-path"},t)))),"dirty"===g&&(0===Object.keys(N).length?e.createElement("p",{className:"rf0-dt-empty"},"no dirty fields"):Object.keys(N).map(t=>e.createElement("div",{key:t,className:"rf0-dt-item rf0-dt-item--dirty"},e.createElement("span",{className:"rf0-dt-item-path"},t),e.createElement("span",{className:"rf0-dt-item-msg rf0-dt-item-msg--ok"},"changed"))))),e.createElement("p",{className:"rf0-dt-status","aria-live":"polite"},e.createElement("span",{className:_?"rf0-dt-on":void 0},"submitting ",e.createElement("b",null,String(_))),e.createElement("span",null,"submits ",e.createElement("b",null,$)),e.createElement("span",{className:L(A)},"ok"," ",e.createElement("b",null,void 0===A?"–":String(A)))),e.createElement("div",{className:"rf0-dt-actions"},e.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>u(o,o.initialValues)},"Reset"),e.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>m(o)},"Validate")))}export{$ as Devtools};
|
|
1
|
+
import*as e from"react";import t,{useCallback as n,useRef as r,createContext as o,useState as a,useContext as l,useId as i}from"react";import{o as s,g as d,a as c,b as f,c as p,r as u,t as m}from"../form-BQsb2CuG.mjs";var b,g={exports:{}},x={};var h,E,y={};var v=(E||(E=1,"production"===process.env.NODE_ENV?g.exports=function(){if(b)return x;b=1;var e=t,n="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},r=e.useState,o=e.useEffect,a=e.useLayoutEffect,l=e.useDebugValue;function i(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!n(e,r)}catch(e){return!0}}var s="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),s=r({inst:{value:n,getSnapshot:t}}),d=s[0].inst,c=s[1];return a(function(){d.value=n,d.getSnapshot=t,i(d)&&c({inst:d})},[e,n,t]),o(function(){return i(d)&&c({inst:d}),e(function(){i(d)&&c({inst:d})})},[e]),l(n),n};return x.useSyncExternalStore=void 0!==e.useSyncExternalStore?e.useSyncExternalStore:s,x}():g.exports=(h||(h=1,"production"!==process.env.NODE_ENV&&function(){function e(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch(e){return!0}}"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var n=t,r="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=n.useState,a=n.useEffect,l=n.useLayoutEffect,i=n.useDebugValue,s=!1,d=!1,c="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(t,c){s||void 0===n.startTransition||(s=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var f=c();if(!d){var p=c();r(f,p)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),d=!0)}var u=(p=o({inst:{value:f,getSnapshot:c}}))[0].inst,m=p[1];return l(function(){u.value=f,u.getSnapshot=c,e(u)&&m({inst:u})},[t,f,c]),a(function(){return e(u)&&m({inst:u}),t(function(){e(u)&&m({inst:u})})},[t]),i(f),f};y.useSyncExternalStore=void 0!==n.useSyncExternalStore?n.useSyncExternalStore:c,"undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),y)),g.exports);function w(e,t,o){return function(e,t){const o=r(null);null===o.current&&(o.current={hasValue:!1});const a=o.current,l=r(t);l.current=t;const i=n(()=>(a.hasValue||(a.value=l.current(),a.hasValue=!0),a.value),[a]),s=n(t=>(a.hasValue=!1,e(()=>{a.hasValue=!1,t()})),[e,a]);return v.useSyncExternalStore(s,i,i)}(n(n=>s(e,t,n),[e,t]),o)}const S=o(null);S.Provider;o(null).Provider;function k({name:t,value:n,depth:r=0}){const[o,l]=a(r<=1),i=void 0===t?null:e.createElement(e.Fragment,null,e.createElement("span",{className:"rf0-dt-key"},String(t)),e.createElement("span",{className:"rf0-dt-punct"},": "));if(null!==n&&"object"==typeof n){const t=Array.isArray(n),a=t?n.map((e,t)=>[t,e]):Object.entries(n),s=t?"[":"{",d=t?"]":"}",c=o?"":`${s}…${d} ${a.length}`;return e.createElement("div",{className:"rf0-dt-row",style:{paddingLeft:12*r}},e.createElement("button",{type:"button",className:"rf0-dt-node-toggle","aria-expanded":o,onClick:()=>l(!o)},e.createElement("span",{className:"rf0-dt-caret"},o?"▾":"▸"),i,e.createElement("span",{className:"rf0-dt-punct"},o?s:c)),o&&e.createElement(e.Fragment,null,a.map(([t,n])=>e.createElement(k,{key:String(t),name:t,value:n,depth:r+1})),e.createElement("span",{className:"rf0-dt-punct",style:{paddingLeft:12*r}},d)))}return e.createElement("span",{className:"rf0-dt-row",style:{paddingLeft:12*r,display:"block"}},i,e.createElement(N,{value:n}))}function N({value:t}){return void 0===t?e.createElement("span",{className:"rf0-dt-null"},"undefined"):null===t?e.createElement("span",{className:"rf0-dt-null"},"null"):"string"==typeof t?e.createElement("span",{className:"rf0-dt-string"},'"',t,'"'):"boolean"==typeof t?e.createElement("span",{className:"rf0-dt-boolean"},String(t)):e.createElement("span",{className:"rf0-dt-number"},String(t))}const _="react-f0rm-devtools-style";!function(){if("undefined"==typeof document)return;if(document.getElementById(_))return;const e=document.createElement("style");e.id=_,e.textContent="\n.rf0-dt {\n position: fixed;\n z-index: 2147483000;\n box-sizing: border-box;\n width: 308px;\n max-width: calc(100vw - 16px);\n max-height: min(70vh, 560px);\n display: flex;\n flex-direction: column;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 11px;\n line-height: 1.45;\n color: #c7d0dc;\n background: #0c1017;\n border: 1px solid #1f2735;\n border-radius: 4px;\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.4);\n}\n.rf0-dt *,\n.rf0-dt-badge * {\n box-sizing: border-box;\n}\n.rf0-dt--top-right { top: 8px; right: 8px; }\n.rf0-dt--bottom-right { bottom: 8px; right: 8px; }\n.rf0-dt--top-left { top: 8px; left: 8px; }\n.rf0-dt--bottom-left { bottom: 8px; left: 8px; }\n\n/* ---- header -------------------------------------------------------- */\n.rf0-dt-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 5px 6px 5px 9px;\n border-bottom: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-title {\n flex: 1;\n min-width: 0;\n color: #8b96a5;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.14em;\n text-transform: uppercase;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rf0-dt-title::before {\n content: '';\n display: inline-block;\n width: 6px;\n height: 6px;\n margin-right: 6px;\n border-radius: 50%;\n background: #e2b93b;\n vertical-align: 1px;\n}\n.rf0-dt-headerbtn {\n border: 1px solid transparent;\n border-radius: 3px;\n padding: 1px 5px;\n color: #8b96a5;\n background: transparent;\n font: inherit;\n font-size: 10px;\n cursor: pointer;\n}\n.rf0-dt-headerbtn:hover { color: #dce3ec; border-color: #2a3547; }\n.rf0-dt-headerbtn:focus-visible,\n.rf0-dt-tab:focus-visible,\n.rf0-dt-action:focus-visible,\n.rf0-dt-badge:focus-visible,\n.rf0-dt-node-toggle:focus-visible {\n outline: 1px solid #e2b93b;\n outline-offset: 1px;\n}\n\n/* ---- tabs ---------------------------------------------------------- */\n.rf0-dt-tablist {\n display: flex;\n border-bottom: 1px solid #1f2735;\n background: #0e131b;\n}\n.rf0-dt-tab {\n flex: 1;\n padding: 4px 2px 5px;\n border: 0;\n border-bottom: 2px solid transparent;\n background: transparent;\n color: #6b7686;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n white-space: nowrap;\n}\n.rf0-dt-tab:hover { color: #aab5c4; }\n.rf0-dt-tab[aria-selected='true'] {\n color: #e7edf4;\n border-bottom-color: #e2b93b;\n}\n.rf0-dt-tab-count {\n margin-left: 3px;\n color: inherit;\n opacity: 0.75;\n}\n.rf0-dt-tab--danger[aria-selected='true'] {\n border-bottom-color: #f0647c;\n}\n\n/* ---- panels -------------------------------------------------------- */\n.rf0-dt-panel {\n flex: 1;\n min-height: 84px;\n overflow: auto;\n padding: 6px 8px;\n scrollbar-width: thin;\n scrollbar-color: #2a3547 transparent;\n}\n.rf0-dt-empty {\n padding: 10px 2px;\n color: #4d5766;\n font-style: italic;\n}\n\n/* json tree */\n.rf0-dt-row {\n display: block;\n white-space: pre;\n tab-size: 2;\n}\n.rf0-dt-node-toggle {\n border: 0;\n padding: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n white-space: pre;\n}\n.rf0-dt-node-toggle:hover .rf0-dt-key { color: #dce3ec; }\n.rf0-dt-caret {\n display: inline-block;\n width: 1.2em;\n color: #4d5766;\n}\n.rf0-dt-key { color: #8b96a5; }\n.rf0-dt-punct { color: #4d5766; }\n.rf0-dt-string { color: #8fd68a; }\n.rf0-dt-number { color: #e2b93b; }\n.rf0-dt-boolean { color: #6fb3d9; }\n.rf0-dt-null { color: #55607080; font-style: italic; }\n\n/* errors / touched / dirty lists */\n.rf0-dt-item {\n padding: 3px 2px;\n border-bottom: 1px dotted #1a2230;\n display: flex;\n gap: 8px;\n align-items: baseline;\n}\n.rf0-dt-item:last-child { border-bottom: 0; }\n.rf0-dt-item-path {\n color: #aab5c4;\n word-break: break-all;\n}\n.rf0-dt-item-msg {\n color: #f0647c;\n word-break: break-word;\n}\n.rf0-dt-item-msg--ok { color: #8fd68a; }\n.rf0-dt-item-tag {\n flex: none;\n color: #4d5766;\n font-size: 10px;\n}\n.rf0-dt-item--touched .rf0-dt-item-path { color: #6fb3d9; }\n.rf0-dt-item--dirty .rf0-dt-item-path { color: #e2b93b; }\n\n/* ---- submit status + actions --------------------------------------- */\n.rf0-dt-status {\n display: flex;\n gap: 10px;\n padding: 4px 9px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n color: #6b7686;\n font-size: 10px;\n letter-spacing: 0.04em;\n white-space: nowrap;\n overflow: hidden;\n}\n.rf0-dt-status b { color: #aab5c4; font-weight: 400; }\n.rf0-dt-status .rf0-dt-on { color: #e2b93b; }\n.rf0-dt-status .rf0-dt-ok { color: #8fd68a; }\n.rf0-dt-status .rf0-dt-err { color: #f0647c; }\n.rf0-dt-actions {\n display: flex;\n gap: 6px;\n padding: 6px 8px;\n border-top: 1px solid #1f2735;\n background: #10151e;\n}\n.rf0-dt-action {\n flex: 1;\n padding: 3px 0;\n border: 1px solid #2a3547;\n border-radius: 3px;\n background: #151b26;\n color: #c7d0dc;\n font: inherit;\n font-size: 10px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n cursor: pointer;\n}\n.rf0-dt-action:hover { border-color: #3b4a61; background: #1a2230; color: #e7edf4; }\n.rf0-dt-action:active { transform: translateY(1px); }\n\n/* ---- collapsed badge ----------------------------------------------- */\n.rf0-dt-badge {\n position: fixed;\n z-index: 2147483000;\n width: 26px;\n height: 26px;\n border: 1px solid #2a3547;\n border-radius: 50%;\n background: #0c1017;\n color: #e2b93b;\n font: inherit;\n font-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'JetBrains Mono',\n Menlo, Consolas, 'Liberation Mono', monospace;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.02em;\n cursor: pointer;\n box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);\n}\n.rf0-dt-badge:hover { border-color: #e2b93b; }\n.rf0-dt-badge--top-right { top: 10px; right: 10px; }\n.rf0-dt-badge--bottom-right { bottom: 10px; right: 10px; }\n.rf0-dt-badge--top-left { top: 10px; left: 10px; }\n.rf0-dt-badge--bottom-left { bottom: 10px; left: 10px; }\n.rf0-dt-badge .rf0-dt-dot {\n position: absolute;\n top: 3px;\n right: 3px;\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background: #f0647c;\n display: none;\n}\n.rf0-dt-badge--has-errors .rf0-dt-dot { display: block; }\n",document.head.appendChild(e)}();const O=["values","errors","touched","dirty"];function L(e){if(void 0!==e)return e?"rf0-dt-ok":"rf0-dt-err"}function C(e){if(null===e||"object"!=typeof e)return 1;let t=0;for(const n of Object.values(e))t+=C(n);return t}function $({form:t,position:n="top-right"}){const r=l(S),o=t??r;if(!o)throw new Error("<Devtools> needs a form: pass the `form` prop or render it inside a <Form> / FormProvider.");const[s,b]=a(!0),[g,x]=a("values"),h=i().replace(/[^a-zA-Z0-9-]/g,""),E=w(o.emitter,"change",f.bind(null,o)),y=w(o.emitter,"errors",p.bind(null,o)),v=function(e){return w(e.emitter,"touched",d.bind(null,e))}(o),N=function(e){return w(e.emitter,"change",c.bind(null,e))}(o),_=function(e){return w(e.emitter,"submitting",()=>e.isSubmitting)}(o),$=function(e){return w(e.emitter,"submitCount",()=>e.submitCount)}(o),A=w(o.emitter,"submitSuccessful",()=>o.isSubmitSuccessful);if(!s)return e.createElement("button",{type:"button",className:`rf0-dt-badge rf0-dt-badge--${n}${y.length>0?" rf0-dt-badge--has-errors":""}`,"aria-expanded":!1,"aria-label":`Open react-f0rm devtools (${y.length} errors)`,onClick:()=>b(!0)},"f0",e.createElement("span",{className:"rf0-dt-dot"}));const V={values:C(E),errors:y.length,touched:v.length,dirty:Object.keys(N).length};return e.createElement("section",{className:`rf0-dt rf0-dt--${n}`,"aria-label":"react-f0rm devtools"},e.createElement("header",{className:"rf0-dt-header"},e.createElement("span",{className:"rf0-dt-title"},"react-f0rm"),e.createElement("button",{type:"button",className:"rf0-dt-headerbtn","aria-label":"Collapse devtools",onClick:()=>b(!1)},"–")),e.createElement("div",{className:"rf0-dt-tablist",role:"tablist","aria-label":"Form state",tabIndex:-1,onKeyDown:e=>{const t={ArrowRight:1,ArrowLeft:-1}[e.key];if(!t)return;e.preventDefault();const n=O[(O.indexOf(g)+t+O.length)%O.length];x(n),document.getElementById(`${h}-tab-${n}`)?.focus()}},O.map(t=>e.createElement("button",{key:t,id:`${h}-tab-${t}`,type:"button",role:"tab",className:"rf0-dt-tab"+("errors"===t?" rf0-dt-tab--danger":""),"aria-selected":g===t,"aria-controls":`${h}-panel-${t}`,tabIndex:g===t?0:-1,onClick:()=>x(t)},t,e.createElement("span",{className:"rf0-dt-tab-count"},V[t])))),e.createElement("div",{id:`${h}-panel-${g}`,role:"tabpanel","aria-labelledby":`${h}-tab-${g}`,className:"rf0-dt-panel"},"values"===g&&e.createElement(k,{value:E}),"errors"===g&&(0===y.length?e.createElement("p",{className:"rf0-dt-empty"},"no errors"):y.map(({path:t,type:n,message:r},o)=>e.createElement("div",{key:`${t}:${o}`,className:"rf0-dt-item"},e.createElement("span",{className:"rf0-dt-item-path"},t),e.createElement("span",{className:"rf0-dt-item-msg"},r),e.createElement("span",{className:"rf0-dt-item-tag"},n)))),"touched"===g&&(0===v.length?e.createElement("p",{className:"rf0-dt-empty"},"no touched fields"):v.map(t=>e.createElement("div",{key:t,className:"rf0-dt-item rf0-dt-item--touched"},e.createElement("span",{className:"rf0-dt-item-path"},t)))),"dirty"===g&&(0===Object.keys(N).length?e.createElement("p",{className:"rf0-dt-empty"},"no dirty fields"):Object.keys(N).map(t=>e.createElement("div",{key:t,className:"rf0-dt-item rf0-dt-item--dirty"},e.createElement("span",{className:"rf0-dt-item-path"},t),e.createElement("span",{className:"rf0-dt-item-msg rf0-dt-item-msg--ok"},"changed"))))),e.createElement("p",{className:"rf0-dt-status","aria-live":"polite"},e.createElement("span",{className:_?"rf0-dt-on":void 0},"submitting ",e.createElement("b",null,String(_))),e.createElement("span",null,"submits ",e.createElement("b",null,$)),e.createElement("span",{className:L(A)},"ok"," ",e.createElement("b",null,void 0===A?"–":String(A)))),e.createElement("div",{className:"rf0-dt-actions"},e.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>u(o,o.initialValues)},"Reset"),e.createElement("button",{type:"button",className:"rf0-dt-action",onClick:()=>m(o)},"Validate")))}export{$ as Devtools};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -151,6 +151,10 @@ interface Form<T extends Record<string, any> = any> {
|
|
|
151
151
|
/** Delay in milliseconds before the form-level `validate` runs; seeded
|
|
152
152
|
* from {@link Options.validateDebounce} and fixed at create time. */
|
|
153
153
|
validateDebounce?: number;
|
|
154
|
+
/** Path keys (JSON-stringified segments) of the fields whose user
|
|
155
|
+
* changes re-run the form-level `validate`; normalized from {@link
|
|
156
|
+
* Options.validateDeps} at create time and fixed thereafter. */
|
|
157
|
+
validateDeps?: ReadonlySet<string>;
|
|
154
158
|
isSubmitting: boolean;
|
|
155
159
|
submitCount: number;
|
|
156
160
|
isSubmitSuccessful: boolean | undefined;
|
|
@@ -190,6 +194,21 @@ type Options<T extends Record<string, any> = any> = {
|
|
|
190
194
|
* (validate runs immediately, exactly as before this option existed).
|
|
191
195
|
*/
|
|
192
196
|
validateDebounce?: number;
|
|
197
|
+
/** Fields whose user changes re-run the form-level `validate` — the
|
|
198
|
+
* cross-field dependency list (password-confirm mismatch and friends).
|
|
199
|
+
* Each entry is a field path ('password', 'user.email', 'items.0.qty');
|
|
200
|
+
* a user change to a listed field re-runs the form-level `validate`
|
|
201
|
+
* under the same mode/`reValidateMode` gating the field's own
|
|
202
|
+
* validator gets. Omit it and the form-level `validate` only runs on
|
|
203
|
+
* `trigger`/submit, exactly as before this option existed.
|
|
204
|
+
*
|
|
205
|
+
* Opting in also changes what a re-run may clear: each round first
|
|
206
|
+
* drops the errors the previous round wrote (paths it flattened onto),
|
|
207
|
+
* so a dep change that fixes the cross-field error makes it disappear.
|
|
208
|
+
* Errors the round never wrote — field validators', `setServerErrors`,
|
|
209
|
+
* manual `setError` — are never touched. TanStack Form's counterpart is
|
|
210
|
+
* `onChangeListenTo` (v1) / validator `triggers` (v2 alpha). */
|
|
211
|
+
validateDeps?: FieldPath<T>[];
|
|
193
212
|
/** Start the form with every bound field disabled — the flag bound
|
|
194
213
|
* fields OR with their own `disabled` option (a field cannot opt out
|
|
195
214
|
* of a disabled form). Toggle later with {@link setDisabled}.
|
|
@@ -237,18 +256,23 @@ declare function getValue<T extends Record<string, any> = any, P extends FieldPa
|
|
|
237
256
|
* @param path
|
|
238
257
|
*/
|
|
239
258
|
declare function getValueByPath({ initialValues, parsedValues, values, deleted }: Form, path: Path): any;
|
|
240
|
-
/** Options accepted by {@link setValue} / {@link setValueByPath}
|
|
241
|
-
*
|
|
242
|
-
*
|
|
259
|
+
/** Options accepted by {@link setValue} / {@link setValueByPath} / {@link
|
|
260
|
+
* changeValue} / {@link changeValueByPath}. `shouldValidate`/`shouldTouch`
|
|
261
|
+
* default to `false`; omitting the options object entirely keeps the plain
|
|
262
|
+
* set-value behavior (no validation, no touched marking, dirty stays
|
|
263
|
+
* derived). */
|
|
243
264
|
interface SetFieldOptions {
|
|
244
265
|
/** Run the field's registered validator (if any) after the value lands,
|
|
245
266
|
* same as triggering that single field. Defaults to `false`. */
|
|
246
267
|
shouldValidate?: boolean;
|
|
247
268
|
/** Mark the field as touched. Defaults to `false`. */
|
|
248
269
|
shouldTouch?: boolean;
|
|
249
|
-
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
270
|
+
/** Land the value as a commit instead of an edit: the value becomes the
|
|
271
|
+
* field's dirty-comparison baseline, so `getDirtyFields`/`isDirty`/
|
|
272
|
+
* `getFieldState().isDirty` read the field as clean, and a later write
|
|
273
|
+
* dirties it only by differing from the new baseline. `true` (or
|
|
274
|
+
* omitting the flag) keeps the default derived behavior — dirty while
|
|
275
|
+
* the live value differs from initialValues. */
|
|
252
276
|
shouldDirty?: boolean;
|
|
253
277
|
}
|
|
254
278
|
/**
|
|
@@ -288,18 +312,26 @@ declare function setValueByPath(form: Form, path: Path, value: any, options?: Se
|
|
|
288
312
|
* ignoring any mode. Functional updaters are the caller's to evaluate
|
|
289
313
|
* ({@link getValue}).
|
|
290
314
|
*
|
|
315
|
+
* `options` carries the same {@link SetFieldOptions}: on the fallback path
|
|
316
|
+
* (no mounted field) they forward to {@link setValueByPath} wholesale,
|
|
317
|
+
* while on the mounted-field path only `shouldDirty: false` applies — the
|
|
318
|
+
* write lands as a commit while the field's own mode gating keeps driving
|
|
319
|
+
* validation, which is the point of this channel.
|
|
320
|
+
*
|
|
291
321
|
* @param form
|
|
292
322
|
* @param name
|
|
293
323
|
* @param value
|
|
324
|
+
* @param options
|
|
294
325
|
*/
|
|
295
|
-
declare function changeValue<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, value: PathValueOf<T, P
|
|
326
|
+
declare function changeValue<T extends Record<string, any> = any, P extends FieldPath<T> | Name = Name>(form: Form<T>, name: P, value: PathValueOf<T, P>, options?: SetFieldOptions): void;
|
|
296
327
|
/**
|
|
297
328
|
* Set a field value as a user change, by parsed path
|
|
298
329
|
* @param form
|
|
299
330
|
* @param path
|
|
300
331
|
* @param value
|
|
332
|
+
* @param options
|
|
301
333
|
*/
|
|
302
|
-
declare function changeValueByPath(form: Form, path: Path, value: any): void;
|
|
334
|
+
declare function changeValueByPath(form: Form, path: Path, value: any, options?: SetFieldOptions): void;
|
|
303
335
|
/**
|
|
304
336
|
* Get field error
|
|
305
337
|
* @param form
|
|
@@ -579,6 +611,37 @@ declare function hasErrors({ errors }: Form): boolean;
|
|
|
579
611
|
* @return whether the triggered scope is error-free once validation settles
|
|
580
612
|
*/
|
|
581
613
|
declare function trigger(form: Form, name?: Name | Name[]): Promise<boolean>;
|
|
614
|
+
/**
|
|
615
|
+
* Form-level twin of the gated validator kick in `useField`'s onChange:
|
|
616
|
+
* re-run the form-level `validate` after a user change to a field listed
|
|
617
|
+
* in `validateDeps`. Called from the field's own change pipeline (typing
|
|
618
|
+
* and `changeValue` alike — both route through the mounted field's
|
|
619
|
+
* onChange), so programmatic `setValue` writes do not re-run it, exactly
|
|
620
|
+
* like they do not re-run field validators.
|
|
621
|
+
*
|
|
622
|
+
* The gate mirrors the per-field matrix with the *changed field's*
|
|
623
|
+
* effective `mode` (a per-field override governs when its changes may
|
|
624
|
+
* fire validation) and the form-level `reValidateMode` against the last
|
|
625
|
+
* round's error footprint ({@link hasFormValidateErrors} — field
|
|
626
|
+
* validators' errors never arm this kick):
|
|
627
|
+
* - `mode` `'onChange'`/`'all'` — every dep change re-runs;
|
|
628
|
+
* - `mode` `'onTouched'` — dep changes re-run once the field was touched;
|
|
629
|
+
* - otherwise the re-run waits for `reValidateMode: 'onChange'` (the
|
|
630
|
+
* default) while the last round's error is still live — the
|
|
631
|
+
* submit-then-fix flow: the mismatch lands on submit, editing the
|
|
632
|
+
* dependency re-runs the validate and clears it.
|
|
633
|
+
* `reValidateMode: 'onBlur'`/`'onSubmit'` never re-run on a change (a
|
|
634
|
+
* change is not a blur; submit re-runs are the submit pipeline's job).
|
|
635
|
+
*
|
|
636
|
+
* The kick is fire-and-forget: async round rejections are swallowed
|
|
637
|
+
* (nothing in an event handler can await them), while a synchronous
|
|
638
|
+
* throw inside the validate callback propagates to the caller exactly
|
|
639
|
+
* like a field validator's does.
|
|
640
|
+
*
|
|
641
|
+
* A no-op unless the form set `validateDeps` listing `path` — forms
|
|
642
|
+
* without the option pay one property check here.
|
|
643
|
+
*/
|
|
644
|
+
declare function revalidateFormOnChange(form: Form, path: Path, mode: ValidationMode): void;
|
|
582
645
|
/**
|
|
583
646
|
* Validate and throw if any field error.
|
|
584
647
|
* @param form
|
|
@@ -676,5 +739,5 @@ interface SetFocusOptions {
|
|
|
676
739
|
*/
|
|
677
740
|
declare function setFocus(form: Form, name: Name, options?: SetFocusOptions): void;
|
|
678
741
|
|
|
679
|
-
export {
|
|
742
|
+
export { setError as $, getFieldState as A, getFirstError as B, getTouchedFields as C, getValue as D, getValueByPath as E, getValues as G, handleSubmit as I, hasErrors as J, hasTouched as K, hasTouchedByPath as L, incrementSubmitCount as M, isDirty as Q, isTouched as T, removeField as U, removeFieldByPath as W, reset as X, resetField as Y, revalidateFormOnChange as Z, setDisabled as _, setErrorByPath as a0, setFocus as a1, setInitialValues as a2, setIsSubmitting as a3, setServerErrors as a4, setSubmitSuccessful as a5, setTouched as a6, setTouchedByPath as a7, setValidatingByPath as a8, setValue as a9, setValueByPath as aa, trigger as ab, unsetValidatingByPath as ac, validate as ad, VALIDATION_OUTCOME as m, changeValue as p, changeValueByPath as q, clearErrors as r, create as s, ensureValidate as t, getDirtyFields as u, getError as v, getErrorByPath as w, getErrors as x, getFieldErrors as y, getFieldErrorsByPath as z };
|
|
680
743
|
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, FormValidateFn as f, FormValidateMeta as g, PathValue as h, ResetFieldOptions as i, ResetOptions as j, SetFocusOptions as k, SetServerErrorsOptions as l, ValidateResult as n, ValidationOutcome as o };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e,t){for(var r=arguments.length,n=new Array(r>2?r-2:0),o=2;o<r;o++)n[o-2]=arguments[o];(e.get(t)||[]).forEach(function(e){return e.apply(void 0,n)})}function t(e,t,r){var n=function(e,t){var r=e.get(t);if(r)return r;var n=new Set;return e.set(t,n),n}(e,t);return n.add(r),function(){return n.delete(r)}}const r=new Map;function n(e){if(Array.isArray(e))return e;const t=r.get(e);if(t)return t;const n=function(e){const t=[];let r="";const n=()=>{t.push(r),r=""};for(let o=0;o<e.length;o++){const s=e[o];if("."===s)""!==r&&n();else if("["===s){""!==r&&n();const s=e[o+1];if('"'===s||"'"===s){const r=e.indexOf(s,o+2);if(-1===r)throw new TypeError(`Unterminated quote in path: ${e}`);if("]"!==e[r+1])throw new TypeError(`Expected "]" after quoted segment in path: ${e}`);t.push(e.slice(o+2,r)),o=r+1}else{const r=e.indexOf("]",o+1);if(-1===r)throw new TypeError(`Unterminated bracket in path: ${e}`);const n=e.slice(o+1,r);t.push(/^-?\d+$/.test(n)?Number(n):n),o=r}}else r+=s}""===r&&0!==t.length||n();return t}(e);return r.set(e,n),n}function o(e,t){if(!t.length||null==e)return e;const[r,...n]=t;if(n.length){const t=o(e[r],n);return t===e[r]?e:s(e,[r],t)}if(Array.isArray(e)){if(!(r in e))return e;const t=e.slice();return delete t[r],t}if("object"!=typeof e||!(r in e))return e;const i={...e};return delete i[r],i}function s(e,t,r){if(!t.length)return r;const[n,...o]=t;if("number"==typeof n){const t=Array.isArray(e)?e.slice():[];return t[n]=s(t[n],o,r),t}return{...e,[n]:s(e&&e[n],o,r)}}function i(e,t,r,n){if(!t.length)return r;let o=e,s=null,i="";for(let u=0;u<t.length;u++){const c=t[u];if(!n.has(o)){let t;t="number"==typeof c?Array.isArray(o)?o.slice():[]:{...o},n.add(t),0===u?e=t:s[i]=t,o=t}u===t.length-1?o[c]=r:(s=o,i=c,o=o[c])}return e}function u(e){const t=n(e);return{value:t,key:JSON.stringify(t)}}const c=Symbol("validation-outcome");function a(e){const{initialValues:t,parsedValues:r,values:n,deleted:s}=e,u=new Set;let c=r??t;for(const[e,t]of n)c=i(c,JSON.parse(e),t,u);for(const e of s)c=o(c,JSON.parse(e));return c}function l(t,r,n,o){const{emitter:s,values:i,deleted:u}=t;i.set(r.key,n),function(e,{key:t}){if(!e.size)return;for(const r of e)(r===t||r.startsWith(`${t.slice(0,-1)},`)||t.startsWith(`${r.slice(0,-1)},`))&&e.delete(r)}(u,r),function(e,{key:t}){const r=g.get(e);if(!r?.size)return;const n=`${t.slice(0,-1)},`;for(const e of r.keys())e.startsWith(n)&&r.delete(e)}(t,r),p(t),e(s,"change",r)}function f({errors:e}){const t=[];for(const[r,n]of e){const e=JSON.parse(r).join(".");for(const{type:r,message:o}of n)t.push({path:e,type:r,message:o})}return t}function d(t,r,n){!function({emitter:t,errors:r},n,o){const s=function(e){if("string"==typeof e)return e?[{type:"custom",message:e}]:void 0;if(S(e))return[e];if(!e)return;const t=[];return e.forEach(e=>{"string"==typeof e&&e?t.push({type:"custom",message:e}):S(e)&&t.push(e)}),t.length?t:void 0}(o);s?r.set(n.key,s):r.delete(n.key);e(t,"errors",n)}(t,u(r),n)}const g=new WeakMap;function m(e,t,r){const n=g.get(e);return n?.has(t)?n.get(t):(o=e.initialValues,r.reduce((e,t)=>{if(null!=e)return e[t]},o));var o}const v=new WeakMap;function p(e){const t=v.get(e);t&&t.version++}function y(e){const t={};return function(e,t){for(const[r,n]of e.values){const o=JSON.parse(r);m(e,r,o)!==n&&t(o.join("."))}}(e,e=>{t[e]=!0}),t}function h(e){let t=v.get(e);if(t){if(t.version>0){const r=y(e);(function(e,t){const r=Object.keys(e);return r.length===Object.keys(t).length&&r.every(e=>!0===t[e])})(t.result,r)||(t.result=r),t.version=0}}else t={version:0,result:y(e)},v.set(e,t);return t.result}function w({touched:e}){return Array.from(e,e=>JSON.parse(e).join("."))}function b(t,r,n){const o=[];t.initialValues=r,t.parsedValues=void 0,function(t){const{emitter:r,errors:n}=t;n.clear(),e(r,"errors")}(t);const{emitter:s,touched:i,values:c,deleted:a,validating:f}=t;c.clear(),a.clear(),function(e){const t=g.get(e);t&&t.clear()}(t),i.clear(),f.clear(),t.isSubmitting=!1,t.submitCount=0,t.isSubmitSuccessful=void 0,p(t);for(const{key:e,value:r}of o)l(t,u(e),r);e(s,"change"),e(s,"touched"),e(s,"validating"),e(s,"submitting"),e(s,"submitCount"),e(s,"submitSuccessful"),e(s,"reset")}async function k(r,n){const o=()=>{return e=r.emitter,n="validating",o=()=>function(e){for(const t of e.validating)if(t!==N)return!1;return!0}(r),s=()=>!1,new Promise((r,i)=>{if(s())return void i();if(o())return void r();const u=t(e,n,()=>{if(s())return u(),void i();o()&&(u(),r())})});var e,n,o,s};return r.validators.forEach(e=>e()),await o(),r.validate&&await function(t){const r=t.validate;if(!r)return Promise.resolve();const n=t.validateDebounce??0;if(n<=0){const e=new AbortController;return Promise.resolve(r(a(t),{form:t,signal:e.signal})).then(e=>{O(t,e)})}const o=function(e){let t=J.get(e);t||(t={timer:null,controller:null,round:null,marked:!1,waiters:[]},J.set(e,t));return t}(t);null!==o.timer?clearTimeout(o.timer):(o.marked=!0,t.validating.add(N),e(t.emitter,"validating"));return o.timer=setTimeout(()=>{o.timer=null;const e=o.round={};(function(e,t,r){const n=e.validate;if(!n)return Promise.resolve();t.controller?.abort();const o=t.controller=new AbortController;let s;try{s=Promise.resolve(n(a(e),{form:e,signal:o.signal}))}catch(e){s=Promise.reject(e)}return s.then(n=>{t.round===r&&O(e,n)},e=>{if(t.round===r)throw e})})(t,o,e).then(()=>P(t,o,e,V),r=>P(t,o,e,r))},n),new Promise((e,t)=>{o.waiters.push({resolve:e,reject:t})})}(r),!function({errors:e}){return e.size>0}(r)}function S(e){return!!e&&"object"==typeof e&&"string"==typeof e.type&&"string"==typeof e.message}function A(e,t,r=[],o){Object.entries(t).forEach(([t,s])=>{const i=[...r,...n(t)];"string"==typeof s?s&&(d(e,i,s),j(e,i,o)):Array.isArray(s)||S(s)?(d(e,i,s),j(e,i,o)):s&&"object"==typeof s&&A(e,s,i,o)})}function j(e,t,r){if(!r)return;const n=u(t),o=e.errors.get(n.key);o&&r.set(n.key,o)}function O(t,r){const n=t.validateDeps?function(e){let t=E.get(e);t||(t=new Map,E.set(e,t));return t}(t):void 0;if(n&&(!function(t,r){for(const[n,o]of r){t.errors.get(n)===o&&(t.errors.delete(n),e(t.emitter,"errors",u(JSON.parse(n))))}}(t,n),n.clear()),r){if("object"==typeof r&&c in r){const o=r;return o.errors&&A(t,o.errors,[],n),void function(t,r){void 0!==r&&r!==t.parsedValues&&(t.parsedValues=r,e(t.emitter,"change"))}(t,o.values)}A(t,r,[],n)}}const E=new WeakMap;const N="__form_validate__";const V=Symbol("form-validate-settled"),J=new WeakMap;function P(t,r,n,o){if(r.round!==n)return;if(r.round=null,null!==r.timer)return;r.marked&&(r.marked=!1,t.validating.delete(N),e(t.emitter,"validating"));const s=r.waiters;r.waiters=[];for(const e of s)o===V?e.resolve():e.reject(o)}export{c as V,h as a,a as b,f as c,w as g,t as o,b as r,k as t};
|
|
2
|
+
//# sourceMappingURL=form-BQsb2CuG.mjs.map
|