attaform 0.24.4 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/fingerprint2.cjs +1 -1
- package/dist/chunks/fingerprint2.mjs +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +4 -4
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/runtime/plugins/attaform.cjs +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.CO0e7YVY.d.cts → attaform.55hFR_cl.d.ts} +3 -0
- package/dist/shared/{attaform.Ib7oSpxj.d.cts → attaform.B71rfNL5.d.mts} +1 -1
- package/dist/shared/{attaform.DTn1J0Eq.d.mts → attaform.BFfY7HRI.d.cts} +1 -1
- package/dist/shared/{attaform.CAVK56f8.cjs → attaform.BPl-ECRT.cjs} +49 -2
- package/dist/shared/attaform.BPl-ECRT.cjs.map +1 -0
- package/dist/shared/{attaform.CBMI57RP.cjs → attaform.BQflyVOL.cjs} +3 -3
- package/dist/shared/{attaform.CBMI57RP.cjs.map → attaform.BQflyVOL.cjs.map} +1 -1
- package/dist/shared/{attaform.DWKcw1ud.cjs → attaform.BRzKBj2g.cjs} +101 -4
- package/dist/shared/attaform.BRzKBj2g.cjs.map +1 -0
- package/dist/shared/{attaform.EeVCVnoH.d.ts → attaform.Be5otUVw.d.ts} +1 -1
- package/dist/shared/{attaform.iJ4y3sHU.mjs → attaform.BoYqnIPI.mjs} +223 -81
- package/dist/shared/attaform.BoYqnIPI.mjs.map +1 -0
- package/dist/shared/{attaform.B1N47eDM.d.ts → attaform.CEY_WLRJ.d.mts} +127 -56
- package/dist/shared/{attaform.CwqTCeTZ.mjs → attaform.CSXDW2tO.mjs} +4 -4
- package/dist/shared/{attaform.CwqTCeTZ.mjs.map → attaform.CSXDW2tO.mjs.map} +1 -1
- package/dist/shared/{attaform.lcTiMoma.mjs → attaform.CXVmZtFq.mjs} +3 -3
- package/dist/shared/{attaform.lcTiMoma.mjs.map → attaform.CXVmZtFq.mjs.map} +1 -1
- package/dist/shared/{attaform.CE-KJZ0j.cjs → attaform.Cs0UZ7q6.cjs} +4 -4
- package/dist/shared/{attaform.CE-KJZ0j.cjs.map → attaform.Cs0UZ7q6.cjs.map} +1 -1
- package/dist/shared/{attaform.AkX9wzfY.cjs → attaform.D51IwDtP.cjs} +2 -2
- package/dist/shared/{attaform.AkX9wzfY.cjs.map → attaform.D51IwDtP.cjs.map} +1 -1
- package/dist/shared/{attaform.QFrCtJBO.d.mts → attaform.DBNjHgNj.d.cts} +86 -17
- package/dist/shared/{attaform.QFrCtJBO.d.cts → attaform.DBNjHgNj.d.mts} +86 -17
- package/dist/shared/{attaform.QFrCtJBO.d.ts → attaform.DBNjHgNj.d.ts} +86 -17
- package/dist/shared/{attaform.DwsfkfSY.mjs → attaform.DGhIix5D.mjs} +48 -3
- package/dist/shared/attaform.DGhIix5D.mjs.map +1 -0
- package/dist/shared/{attaform.CO0e7YVY.d.mts → attaform.DJRz_bzM.d.cts} +3 -0
- package/dist/shared/{attaform.ChY7tIrn.mjs → attaform.DSOIz08n.mjs} +4 -4
- package/dist/shared/{attaform.ChY7tIrn.mjs.map → attaform.DSOIz08n.mjs.map} +1 -1
- package/dist/shared/{attaform.Buedl_UL.cjs → attaform.Du9RZp8m.cjs} +223 -81
- package/dist/shared/attaform.Du9RZp8m.cjs.map +1 -0
- package/dist/shared/{attaform.CO0e7YVY.d.ts → attaform.JPsaqjLl.d.mts} +3 -0
- package/dist/shared/{attaform.CqW4gF_Z.d.cts → attaform.MgaYKlPP.d.cts} +127 -56
- package/dist/shared/{attaform.CZpUm-2l.mjs → attaform.NqYEzRcM.mjs} +2 -2
- package/dist/shared/{attaform.CZpUm-2l.mjs.map → attaform.NqYEzRcM.mjs.map} +1 -1
- package/dist/shared/{attaform.WvcckZMD.mjs → attaform.Vp2-CWZB.mjs} +3 -2
- package/dist/shared/attaform.Vp2-CWZB.mjs.map +1 -0
- package/dist/shared/{attaform.CjdepGnw.cjs → attaform.ZXZ6dH72.cjs} +3 -1
- package/dist/shared/attaform.ZXZ6dH72.cjs.map +1 -0
- package/dist/shared/{attaform.f0l5ydy1.d.mts → attaform.ceYeVkjn.d.ts} +127 -56
- package/dist/shared/{attaform.QwLSdxuk.mjs → attaform.k9V0py0s.mjs} +101 -5
- package/dist/shared/attaform.k9V0py0s.mjs.map +1 -0
- package/dist/shared/{attaform.Bnm0FQaH.cjs → attaform.tZ0YKisf.cjs} +4 -4
- package/dist/shared/{attaform.Bnm0FQaH.cjs.map → attaform.tZ0YKisf.cjs.map} +1 -1
- package/dist/transforms.cjs +2 -1
- package/dist/transforms.cjs.map +1 -1
- package/dist/transforms.d.cts +13 -1
- package/dist/transforms.d.mts +13 -1
- package/dist/transforms.d.ts +13 -1
- package/dist/transforms.mjs +1 -1
- package/dist/vite.cjs +2 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +2 -1
- package/dist/vite.mjs.map +1 -1
- package/dist/zod-v3.cjs +2 -2
- package/dist/zod-v3.d.cts +3 -3
- package/dist/zod-v3.d.mts +3 -3
- package/dist/zod-v3.d.ts +3 -3
- package/dist/zod-v3.mjs +2 -2
- package/dist/zod-v4.cjs +2 -2
- package/dist/zod-v4.d.cts +6 -6
- package/dist/zod-v4.d.mts +6 -6
- package/dist/zod-v4.d.ts +6 -6
- package/dist/zod-v4.mjs +2 -2
- package/dist/zod.cjs +5 -5
- package/dist/zod.d.cts +5 -5
- package/dist/zod.d.mts +5 -5
- package/dist/zod.d.ts +5 -5
- package/dist/zod.mjs +5 -5
- package/package.json +1 -1
- package/dist/shared/attaform.Buedl_UL.cjs.map +0 -1
- package/dist/shared/attaform.CAVK56f8.cjs.map +0 -1
- package/dist/shared/attaform.CjdepGnw.cjs.map +0 -1
- package/dist/shared/attaform.DWKcw1ud.cjs.map +0 -1
- package/dist/shared/attaform.DwsfkfSY.mjs.map +0 -1
- package/dist/shared/attaform.QwLSdxuk.mjs.map +0 -1
- package/dist/shared/attaform.WvcckZMD.mjs.map +0 -1
- package/dist/shared/attaform.iJ4y3sHU.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const paths = require('./attaform.
|
|
3
|
+
const paths = require('./attaform.BPl-ECRT.cjs');
|
|
4
4
|
|
|
5
5
|
function renderAttaformState(app) {
|
|
6
6
|
const registry = paths.getRegistryFromApp(app);
|
|
@@ -36,4 +36,4 @@ const DEVTOOLS_WINDOW_KEY = "__attaform_devtools__";
|
|
|
36
36
|
exports.DEVTOOLS_WINDOW_KEY = DEVTOOLS_WINDOW_KEY;
|
|
37
37
|
exports.hydrateAttaformState = hydrateAttaformState;
|
|
38
38
|
exports.renderAttaformState = renderAttaformState;
|
|
39
|
-
//# sourceMappingURL=attaform.
|
|
39
|
+
//# sourceMappingURL=attaform.D51IwDtP.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attaform.
|
|
1
|
+
{"version":3,"file":"attaform.D51IwDtP.cjs","sources":["../../src/runtime/core/serialize.ts","../../src/runtime/core/devtools-shared.ts"],"sourcesContent":["import type { App } from 'vue'\nimport type { FormKey } from '../types/types-api'\nimport { pathKeyToDotted, type PathKey } from './paths'\nimport { getRegistryFromApp, type SerializedFormData } from './registry'\n\n/**\n * Serialised snapshot of every form in a Vue app, produced by\n * `renderAttaformState` and consumed by `hydrateAttaformState`.\n *\n * JSON-safe — pass to `JSON.stringify`, `devalue`, or any other\n * serialiser before embedding in your SSR payload.\n */\nexport type SerializedAttaformState = {\n /** Tuples of `[formKey, snapshot]` for every form in the app. */\n readonly forms: ReadonlyArray<readonly [FormKey, SerializedFormData]>\n}\n\n/**\n * Snapshot every form on a Vue app for SSR. Call from your server\n * entry after rendering the app:\n *\n * ```ts\n * import { renderToString } from '@vue/server-renderer'\n * import { renderAttaformState, escapeForInlineScript } from 'attaform'\n *\n * const html = await renderToString(app)\n * const state = renderAttaformState(app)\n * const payload = escapeForInlineScript(JSON.stringify(state))\n *\n * return `\n * ${html}\n * <script>window.__ATTAFORM_STATE__ = ${payload}</script>\n * `\n * ```\n *\n * Pair with `hydrateAttaformState` on the client to restore the\n * forms in their server-rendered state. Nuxt users don't need this —\n * `attaform/nuxt` wires SSR automatically.\n */\nexport function renderAttaformState(app: App): SerializedAttaformState {\n const registry = getRegistryFromApp(app)\n const forms: Array<readonly [FormKey, SerializedFormData]> = []\n for (const [key, state] of registry.forms) {\n // Skip the blank field when the set is empty so the\n // wire payload stays minimal for forms that don't use it. The\n // optional shape on the consuming side handles the absence\n // cleanly (defaults to \"no blank paths\"). PathKey → dotted at\n // the boundary so the wire shape matches the rest of the\n // public path notation.\n const transientList: string[] = []\n for (const pk of state.blankPaths) {\n const d = pathKeyToDotted(pk as PathKey)\n if (d !== null) transientList.push(d)\n }\n forms.push([\n key,\n {\n form: state.form.value,\n schemaErrors: Array.from(state.schemaErrors.entries()),\n userErrors: Array.from(state.userErrors.entries()),\n fields: Array.from(state.fields.entries()),\n ...(transientList.length > 0 ? { blankPaths: transientList } : {}),\n },\n ])\n }\n return { forms }\n}\n\n/**\n * Restore forms from a server-rendered snapshot on the client. Call\n * from your client entry before mounting:\n *\n * ```ts\n * import { createApp } from 'vue'\n * import { createAttaform, hydrateAttaformState } from 'attaform'\n *\n * const app = createApp(App).use(createAttaform())\n * hydrateAttaformState(app, window.__ATTAFORM_STATE__)\n * app.mount('#app')\n * ```\n *\n * The next `useForm({ key })` call for each serialised form picks up\n * the snapshot transparently — no further action is required.\n */\nexport function hydrateAttaformState(app: App, payload: SerializedAttaformState): void {\n const registry = getRegistryFromApp(app)\n for (const [key, data] of payload.forms) {\n registry.pendingHydration.set(key, data)\n }\n}\n","/**\n * Shared building blocks for Attaform's two devtools surfaces — the Vue\n * DevTools (Chrome-extension) inspector wired up in `./devtools.ts`, and\n * the Nuxt DevTools (overlay) panel wired up via `../../nuxt.ts` +\n * `../pages/_attaform_devtools.vue`.\n *\n * Houses the window-bridge contract both surfaces consume so a new\n * bridge field lands in one file. Both surfaces render RAW form values\n * by design — DevTools is a dev-only surface, and redaction across every\n * place a value surfaces is impractical security theater rather than a\n * real safeguard.\n */\nimport type { AttaformRegistry } from './registry'\n\n/**\n * Property key on `window` that the Nuxt-side dev plugin attaches the\n * bridge object to. The iframe-mounted overlay panel reads\n * `window.parent[DEVTOOLS_WINDOW_KEY]` to reach the host app's registry.\n *\n * Underscored + namespaced to make accidental collision with consumer\n * globals vanishingly unlikely. Stable across versions — bumping it\n * would silently disconnect older library builds from newer overlay\n * panels in the same browser tab during a library upgrade.\n */\nexport const DEVTOOLS_WINDOW_KEY = '__attaform_devtools__'\n\n/**\n * Shape of the object the host plugin attaches to `window` in dev mode.\n * The iframe overlay panel reads this to discover the live registry and\n * render its forms.\n *\n * Single-registry assumption: the latest `createAttaform()` install\n * wins. Multi-app pages (rare; typically only seen in micro-frontend\n * setups) will only see one app's forms in the panel. Documented but\n * not actively supported — the alternative (a Set of registries with\n * union-rendering) is a future call if a real consumer hits it.\n */\nexport interface AttaformDevtoolsBridge {\n registry: AttaformRegistry\n /**\n * The library version, surfaced in the panel's footer for support /\n * bug-report context. Read from `package.json` at host-plugin init.\n */\n version: string\n}\n\ndeclare global {\n interface Window {\n [DEVTOOLS_WINDOW_KEY]?: AttaformDevtoolsBridge\n }\n}\n"],"names":["getRegistryFromApp","pathKeyToDotted"],"mappings":";;;;AAuCO,SAAS,oBAAoB,GAAA,EAAmC;AACrE,EAAA,MAAM,QAAA,GAAWA,yBAAmB,GAAG,CAAA;AACvC,EAAA,MAAM,QAAuD,EAAC;AAC9D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,SAAS,KAAA,EAAO;AAOzC,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,EAAA,IAAM,MAAM,UAAA,EAAY;AACjC,MAAA,MAAM,CAAA,GAAIC,sBAAgB,EAAa,CAAA;AACvC,MAAA,IAAI,CAAA,KAAM,IAAA,EAAM,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,GAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,MAAM,IAAA,CAAK,KAAA;AAAA,QACjB,cAAc,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,SAAS,CAAA;AAAA,QACrD,YAAY,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA;AAAA,QACjD,QAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAAA,QACzC,GAAI,cAAc,MAAA,GAAS,CAAA,GAAI,EAAE,UAAA,EAAY,aAAA,KAAkB;AAAC;AAClE,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;AAkBO,SAAS,oBAAA,CAAqB,KAAU,OAAA,EAAwC;AACrF,EAAA,MAAM,QAAA,GAAWD,yBAAmB,GAAG,CAAA;AACvC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,CAAA,IAAK,QAAQ,KAAA,EAAO;AACvC,IAAA,QAAA,CAAS,gBAAA,CAAiB,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,EACzC;AACF;;ACjEO,MAAM,mBAAA,GAAsB;;;;;;"}
|
|
@@ -137,8 +137,8 @@ declare function canonicalizePath(input: string | Path): {
|
|
|
137
137
|
* `Path` to address the form value as a whole, and the home for
|
|
138
138
|
* form-level (global) errors: root `.refine()` messages, hydration
|
|
139
139
|
* failures, and `setErrors` entries with no path all live at `[]`. Aggregate
|
|
140
|
-
* reads (`errors()`, `meta.errors`) surface them alongside
|
|
141
|
-
* errors; `
|
|
140
|
+
* reads (`errors()`, `errors([])`, `meta.errors`) surface them alongside
|
|
141
|
+
* field errors; `meta.ownErrors` returns the root bucket alone.
|
|
142
142
|
*
|
|
143
143
|
* The empty SEGMENT tuple `[]` is structurally unconstructible as a
|
|
144
144
|
* field path, so it can never collide with a schema key, unlike the
|
|
@@ -1396,6 +1396,14 @@ type ReactiveValidationStatus<Form> = PendingValidationStatus | SettledValidatio
|
|
|
1396
1396
|
* manually via `form.focusFirstError()` or `form.scrollToFirstError()`
|
|
1397
1397
|
* from an `onError` callback.
|
|
1398
1398
|
*
|
|
1399
|
+
* Both focusing policies request `focusVisible: true`, so the browser
|
|
1400
|
+
* paints a focus ring even though the move is programmatic. Where a UA
|
|
1401
|
+
* doesn't yet support that hint, non-text controls (radio, checkbox,
|
|
1402
|
+
* custom widgets) may end up focused without a visible ring after a
|
|
1403
|
+
* pointer-driven submit; if you target those browsers, pair the policy
|
|
1404
|
+
* with your own indicator (e.g. a `:focus-within` ring on the option
|
|
1405
|
+
* wrapper).
|
|
1406
|
+
*
|
|
1399
1407
|
* If no errored field has a currently mounted, visible element, the
|
|
1400
1408
|
* policy silently no-ops.
|
|
1401
1409
|
*/
|
|
@@ -2066,14 +2074,15 @@ type OnError = (error: ValidationError[]) => void | Promise<void>;
|
|
|
2066
2074
|
type DisplayState = 'idle' | 'pending' | 'error' | 'success';
|
|
2067
2075
|
/**
|
|
2068
2076
|
* Keys on `FieldState` layered on FROM the display-state predicate
|
|
2069
|
-
* (plus `firstError`, computed alongside them).
|
|
2070
|
-
* predicate's arguments so a predicate cannot read
|
|
2071
|
-
* form a cycle — enforced at the type level AND at
|
|
2072
|
-
* objects passed in literally lack these keys, so an
|
|
2073
|
-
* or a vanilla-JS caller still can't reach them.
|
|
2074
|
-
* `FormMetaBase` (field-state-api.ts) omit the same
|
|
2077
|
+
* (plus `firstError` / `firstOwnError`, computed alongside them).
|
|
2078
|
+
* `Omit`'d from the predicate's arguments so a predicate cannot read
|
|
2079
|
+
* its own output and form a cycle — enforced at the type level AND at
|
|
2080
|
+
* runtime: the base objects passed in literally lack these keys, so an
|
|
2081
|
+
* `as` cast in TS or a vanilla-JS caller still can't reach them.
|
|
2082
|
+
* `FieldStateBase` / `FormMetaBase` (field-state-api.ts) omit the same
|
|
2083
|
+
* set in lockstep.
|
|
2075
2084
|
*/
|
|
2076
|
-
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError';
|
|
2085
|
+
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError' | 'firstOwnError';
|
|
2077
2086
|
/**
|
|
2078
2087
|
* One step of the display state machine: the verdict the field should
|
|
2079
2088
|
* render right now (`display`, projected to `displayState` and the
|
|
@@ -3106,7 +3115,40 @@ type FieldState<Value = unknown> = {
|
|
|
3106
3115
|
*/
|
|
3107
3116
|
readonly elements: readonly HTMLElement[];
|
|
3108
3117
|
readonly updatedAt: string | null;
|
|
3118
|
+
/**
|
|
3119
|
+
* Every `ValidationError` in this path's SUBTREE: the node's own
|
|
3120
|
+
* bucket plus every descendant's, sorted by schema-declaration order.
|
|
3121
|
+
* On a leaf (no descendants) this equals `ownErrors`. On a container
|
|
3122
|
+
* it rolls up the whole fieldset, so a parent's `errors` is non-empty
|
|
3123
|
+
* whenever any child is invalid.
|
|
3124
|
+
*
|
|
3125
|
+
* For the errors pinned at THIS path alone (a container's own
|
|
3126
|
+
* cross-field `.refine()`, or `setErrors` at this path), read
|
|
3127
|
+
* `ownErrors`.
|
|
3128
|
+
*/
|
|
3109
3129
|
readonly errors: readonly ValidationError[];
|
|
3130
|
+
/**
|
|
3131
|
+
* Every `ValidationError` at THIS exact path's own bucket, excluding
|
|
3132
|
+
* descendants: schema errors, blank-required errors, and `setErrors`
|
|
3133
|
+
* pinned here, in `schema`, `blank`, `user` order. The exact-path
|
|
3134
|
+
* counterpart to the subtree-scoped `errors`.
|
|
3135
|
+
*
|
|
3136
|
+
* On a leaf this is the same array as `errors` (a leaf has no
|
|
3137
|
+
* descendants). On a container it holds only the container's OWN
|
|
3138
|
+
* errors, a cross-field `.refine()` on the fieldset or a path-less
|
|
3139
|
+
* `setErrors` at this node, without dragging in any child error:
|
|
3140
|
+
*
|
|
3141
|
+
* ```vue
|
|
3142
|
+
* <p v-if="form.fields.address.firstOwnError">
|
|
3143
|
+
* {{ form.fields.address.firstOwnError.message }}
|
|
3144
|
+
* </p>
|
|
3145
|
+
* ```
|
|
3146
|
+
*
|
|
3147
|
+
* On `form.meta` this is the root `[]` bucket: form-level errors from
|
|
3148
|
+
* a root `.refine()` or a path-less `setErrors`. `form.meta.ownErrors`
|
|
3149
|
+
* (with `firstOwnError`) is the banner accessor for those.
|
|
3150
|
+
*/
|
|
3151
|
+
readonly ownErrors: readonly ValidationError[];
|
|
3110
3152
|
/**
|
|
3111
3153
|
* `true` while a per-field validation run is in flight at this path.
|
|
3112
3154
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
@@ -3227,9 +3269,28 @@ type FieldState<Value = unknown> = {
|
|
|
3227
3269
|
* decides when to render it.
|
|
3228
3270
|
*
|
|
3229
3271
|
* On container paths, the first error in the aggregated subtree
|
|
3230
|
-
* (descendants sorted by `pathOrdinal`).
|
|
3272
|
+
* (descendants sorted by `pathOrdinal`). For the container's OWN
|
|
3273
|
+
* first error only, read `firstOwnError`.
|
|
3231
3274
|
*/
|
|
3232
3275
|
readonly firstError: ValidationError | undefined;
|
|
3276
|
+
/**
|
|
3277
|
+
* The first `ValidationError` in `ownErrors` (this exact path's own
|
|
3278
|
+
* bucket), or `undefined` when that bucket is empty. Equivalent to
|
|
3279
|
+
* `ownErrors[0]`, the exact-path counterpart to `firstError`.
|
|
3280
|
+
*
|
|
3281
|
+
* On a leaf this equals `firstError`. On a container it is the
|
|
3282
|
+
* container's own cross-field error (a fieldset `.refine()`), never a
|
|
3283
|
+
* child's. `form.meta.firstOwnError` is the form-level banner: the
|
|
3284
|
+
* first root `[]` error from a root `.refine()` or a path-less
|
|
3285
|
+
* `setErrors`:
|
|
3286
|
+
*
|
|
3287
|
+
* ```vue
|
|
3288
|
+
* <p v-if="form.meta.firstOwnError" role="alert">
|
|
3289
|
+
* {{ form.meta.firstOwnError.message }}
|
|
3290
|
+
* </p>
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
readonly firstOwnError: ValidationError | undefined;
|
|
3233
3294
|
readonly path: ReadonlyArray<string | number>;
|
|
3234
3295
|
/**
|
|
3235
3296
|
* Stable, SSR-safe DOM id for this field, unique across every mount
|
|
@@ -3593,11 +3654,13 @@ type FormErrorsSurface<Form> = ErrorsProxyShape<Form> & {
|
|
|
3593
3654
|
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): readonly ValidationError[];
|
|
3594
3655
|
(segments: ReadonlyArray<string | number>): readonly ValidationError[];
|
|
3595
3656
|
/**
|
|
3596
|
-
* No-arg call returns the whole-form error aggregate
|
|
3597
|
-
* `form.meta.errors`: every field error plus
|
|
3598
|
-
*
|
|
3599
|
-
*
|
|
3600
|
-
*
|
|
3657
|
+
* No-arg call returns the whole-form error aggregate, the same as
|
|
3658
|
+
* `form.meta.errors` and `form.errors([])`: every field error plus
|
|
3659
|
+
* the root bucket. `form.errors(path)` is uniform at every depth,
|
|
3660
|
+
* including `[]`, so the root is no exception. For the root bucket
|
|
3661
|
+
* alone (a root `.refine()`, a path-less `setErrors`), read
|
|
3662
|
+
* `form.meta.ownErrors`. Always a readonly array; empty when the form
|
|
3663
|
+
* has no errors.
|
|
3601
3664
|
*/
|
|
3602
3665
|
(): readonly ValidationError[];
|
|
3603
3666
|
};
|
|
@@ -3705,8 +3768,8 @@ type FormMeta<F = unknown> = FieldState<F> & {
|
|
|
3705
3768
|
* `getDisplayState` predicates) but does NOT drive the library's
|
|
3706
3769
|
* default `getDisplayState` heuristic. The reveal-on-submit story
|
|
3707
3770
|
* runs entirely through `submissionAttempts`, which
|
|
3708
|
-
* `wizard.handleSubmit` bumps on
|
|
3709
|
-
*
|
|
3771
|
+
* `wizard.handleSubmit` bumps on every form (it always validates the
|
|
3772
|
+
* whole step list).
|
|
3710
3773
|
*
|
|
3711
3774
|
* Distinct from `submissionAttempts`, which counts `handleSubmit`
|
|
3712
3775
|
* passes only — wizard departures and form submissions are tracked
|
|
@@ -4423,6 +4486,12 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4423
4486
|
* Pass `{ preventScroll: true }` if you're scrolling separately
|
|
4424
4487
|
* (e.g. via `scrollToFirstError`) and don't want the browser to
|
|
4425
4488
|
* fight the explicit scroll.
|
|
4489
|
+
*
|
|
4490
|
+
* Requests `focusVisible: true` so the UA paints a focus ring even
|
|
4491
|
+
* though the move is programmatic. Honored where supported; on
|
|
4492
|
+
* browsers without it, non-text controls focused after a pointer
|
|
4493
|
+
* submit may show no ring, so you may still want an app-side
|
|
4494
|
+
* indicator.
|
|
4426
4495
|
*/
|
|
4427
4496
|
focusFirstError: (options?: {
|
|
4428
4497
|
preventScroll?: boolean;
|
|
@@ -137,8 +137,8 @@ declare function canonicalizePath(input: string | Path): {
|
|
|
137
137
|
* `Path` to address the form value as a whole, and the home for
|
|
138
138
|
* form-level (global) errors: root `.refine()` messages, hydration
|
|
139
139
|
* failures, and `setErrors` entries with no path all live at `[]`. Aggregate
|
|
140
|
-
* reads (`errors()`, `meta.errors`) surface them alongside
|
|
141
|
-
* errors; `
|
|
140
|
+
* reads (`errors()`, `errors([])`, `meta.errors`) surface them alongside
|
|
141
|
+
* field errors; `meta.ownErrors` returns the root bucket alone.
|
|
142
142
|
*
|
|
143
143
|
* The empty SEGMENT tuple `[]` is structurally unconstructible as a
|
|
144
144
|
* field path, so it can never collide with a schema key, unlike the
|
|
@@ -1396,6 +1396,14 @@ type ReactiveValidationStatus<Form> = PendingValidationStatus | SettledValidatio
|
|
|
1396
1396
|
* manually via `form.focusFirstError()` or `form.scrollToFirstError()`
|
|
1397
1397
|
* from an `onError` callback.
|
|
1398
1398
|
*
|
|
1399
|
+
* Both focusing policies request `focusVisible: true`, so the browser
|
|
1400
|
+
* paints a focus ring even though the move is programmatic. Where a UA
|
|
1401
|
+
* doesn't yet support that hint, non-text controls (radio, checkbox,
|
|
1402
|
+
* custom widgets) may end up focused without a visible ring after a
|
|
1403
|
+
* pointer-driven submit; if you target those browsers, pair the policy
|
|
1404
|
+
* with your own indicator (e.g. a `:focus-within` ring on the option
|
|
1405
|
+
* wrapper).
|
|
1406
|
+
*
|
|
1399
1407
|
* If no errored field has a currently mounted, visible element, the
|
|
1400
1408
|
* policy silently no-ops.
|
|
1401
1409
|
*/
|
|
@@ -2066,14 +2074,15 @@ type OnError = (error: ValidationError[]) => void | Promise<void>;
|
|
|
2066
2074
|
type DisplayState = 'idle' | 'pending' | 'error' | 'success';
|
|
2067
2075
|
/**
|
|
2068
2076
|
* Keys on `FieldState` layered on FROM the display-state predicate
|
|
2069
|
-
* (plus `firstError`, computed alongside them).
|
|
2070
|
-
* predicate's arguments so a predicate cannot read
|
|
2071
|
-
* form a cycle — enforced at the type level AND at
|
|
2072
|
-
* objects passed in literally lack these keys, so an
|
|
2073
|
-
* or a vanilla-JS caller still can't reach them.
|
|
2074
|
-
* `FormMetaBase` (field-state-api.ts) omit the same
|
|
2077
|
+
* (plus `firstError` / `firstOwnError`, computed alongside them).
|
|
2078
|
+
* `Omit`'d from the predicate's arguments so a predicate cannot read
|
|
2079
|
+
* its own output and form a cycle — enforced at the type level AND at
|
|
2080
|
+
* runtime: the base objects passed in literally lack these keys, so an
|
|
2081
|
+
* `as` cast in TS or a vanilla-JS caller still can't reach them.
|
|
2082
|
+
* `FieldStateBase` / `FormMetaBase` (field-state-api.ts) omit the same
|
|
2083
|
+
* set in lockstep.
|
|
2075
2084
|
*/
|
|
2076
|
-
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError';
|
|
2085
|
+
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError' | 'firstOwnError';
|
|
2077
2086
|
/**
|
|
2078
2087
|
* One step of the display state machine: the verdict the field should
|
|
2079
2088
|
* render right now (`display`, projected to `displayState` and the
|
|
@@ -3106,7 +3115,40 @@ type FieldState<Value = unknown> = {
|
|
|
3106
3115
|
*/
|
|
3107
3116
|
readonly elements: readonly HTMLElement[];
|
|
3108
3117
|
readonly updatedAt: string | null;
|
|
3118
|
+
/**
|
|
3119
|
+
* Every `ValidationError` in this path's SUBTREE: the node's own
|
|
3120
|
+
* bucket plus every descendant's, sorted by schema-declaration order.
|
|
3121
|
+
* On a leaf (no descendants) this equals `ownErrors`. On a container
|
|
3122
|
+
* it rolls up the whole fieldset, so a parent's `errors` is non-empty
|
|
3123
|
+
* whenever any child is invalid.
|
|
3124
|
+
*
|
|
3125
|
+
* For the errors pinned at THIS path alone (a container's own
|
|
3126
|
+
* cross-field `.refine()`, or `setErrors` at this path), read
|
|
3127
|
+
* `ownErrors`.
|
|
3128
|
+
*/
|
|
3109
3129
|
readonly errors: readonly ValidationError[];
|
|
3130
|
+
/**
|
|
3131
|
+
* Every `ValidationError` at THIS exact path's own bucket, excluding
|
|
3132
|
+
* descendants: schema errors, blank-required errors, and `setErrors`
|
|
3133
|
+
* pinned here, in `schema`, `blank`, `user` order. The exact-path
|
|
3134
|
+
* counterpart to the subtree-scoped `errors`.
|
|
3135
|
+
*
|
|
3136
|
+
* On a leaf this is the same array as `errors` (a leaf has no
|
|
3137
|
+
* descendants). On a container it holds only the container's OWN
|
|
3138
|
+
* errors, a cross-field `.refine()` on the fieldset or a path-less
|
|
3139
|
+
* `setErrors` at this node, without dragging in any child error:
|
|
3140
|
+
*
|
|
3141
|
+
* ```vue
|
|
3142
|
+
* <p v-if="form.fields.address.firstOwnError">
|
|
3143
|
+
* {{ form.fields.address.firstOwnError.message }}
|
|
3144
|
+
* </p>
|
|
3145
|
+
* ```
|
|
3146
|
+
*
|
|
3147
|
+
* On `form.meta` this is the root `[]` bucket: form-level errors from
|
|
3148
|
+
* a root `.refine()` or a path-less `setErrors`. `form.meta.ownErrors`
|
|
3149
|
+
* (with `firstOwnError`) is the banner accessor for those.
|
|
3150
|
+
*/
|
|
3151
|
+
readonly ownErrors: readonly ValidationError[];
|
|
3110
3152
|
/**
|
|
3111
3153
|
* `true` while a per-field validation run is in flight at this path.
|
|
3112
3154
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
@@ -3227,9 +3269,28 @@ type FieldState<Value = unknown> = {
|
|
|
3227
3269
|
* decides when to render it.
|
|
3228
3270
|
*
|
|
3229
3271
|
* On container paths, the first error in the aggregated subtree
|
|
3230
|
-
* (descendants sorted by `pathOrdinal`).
|
|
3272
|
+
* (descendants sorted by `pathOrdinal`). For the container's OWN
|
|
3273
|
+
* first error only, read `firstOwnError`.
|
|
3231
3274
|
*/
|
|
3232
3275
|
readonly firstError: ValidationError | undefined;
|
|
3276
|
+
/**
|
|
3277
|
+
* The first `ValidationError` in `ownErrors` (this exact path's own
|
|
3278
|
+
* bucket), or `undefined` when that bucket is empty. Equivalent to
|
|
3279
|
+
* `ownErrors[0]`, the exact-path counterpart to `firstError`.
|
|
3280
|
+
*
|
|
3281
|
+
* On a leaf this equals `firstError`. On a container it is the
|
|
3282
|
+
* container's own cross-field error (a fieldset `.refine()`), never a
|
|
3283
|
+
* child's. `form.meta.firstOwnError` is the form-level banner: the
|
|
3284
|
+
* first root `[]` error from a root `.refine()` or a path-less
|
|
3285
|
+
* `setErrors`:
|
|
3286
|
+
*
|
|
3287
|
+
* ```vue
|
|
3288
|
+
* <p v-if="form.meta.firstOwnError" role="alert">
|
|
3289
|
+
* {{ form.meta.firstOwnError.message }}
|
|
3290
|
+
* </p>
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
readonly firstOwnError: ValidationError | undefined;
|
|
3233
3294
|
readonly path: ReadonlyArray<string | number>;
|
|
3234
3295
|
/**
|
|
3235
3296
|
* Stable, SSR-safe DOM id for this field, unique across every mount
|
|
@@ -3593,11 +3654,13 @@ type FormErrorsSurface<Form> = ErrorsProxyShape<Form> & {
|
|
|
3593
3654
|
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): readonly ValidationError[];
|
|
3594
3655
|
(segments: ReadonlyArray<string | number>): readonly ValidationError[];
|
|
3595
3656
|
/**
|
|
3596
|
-
* No-arg call returns the whole-form error aggregate
|
|
3597
|
-
* `form.meta.errors`: every field error plus
|
|
3598
|
-
*
|
|
3599
|
-
*
|
|
3600
|
-
*
|
|
3657
|
+
* No-arg call returns the whole-form error aggregate, the same as
|
|
3658
|
+
* `form.meta.errors` and `form.errors([])`: every field error plus
|
|
3659
|
+
* the root bucket. `form.errors(path)` is uniform at every depth,
|
|
3660
|
+
* including `[]`, so the root is no exception. For the root bucket
|
|
3661
|
+
* alone (a root `.refine()`, a path-less `setErrors`), read
|
|
3662
|
+
* `form.meta.ownErrors`. Always a readonly array; empty when the form
|
|
3663
|
+
* has no errors.
|
|
3601
3664
|
*/
|
|
3602
3665
|
(): readonly ValidationError[];
|
|
3603
3666
|
};
|
|
@@ -3705,8 +3768,8 @@ type FormMeta<F = unknown> = FieldState<F> & {
|
|
|
3705
3768
|
* `getDisplayState` predicates) but does NOT drive the library's
|
|
3706
3769
|
* default `getDisplayState` heuristic. The reveal-on-submit story
|
|
3707
3770
|
* runs entirely through `submissionAttempts`, which
|
|
3708
|
-
* `wizard.handleSubmit` bumps on
|
|
3709
|
-
*
|
|
3771
|
+
* `wizard.handleSubmit` bumps on every form (it always validates the
|
|
3772
|
+
* whole step list).
|
|
3710
3773
|
*
|
|
3711
3774
|
* Distinct from `submissionAttempts`, which counts `handleSubmit`
|
|
3712
3775
|
* passes only — wizard departures and form submissions are tracked
|
|
@@ -4423,6 +4486,12 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4423
4486
|
* Pass `{ preventScroll: true }` if you're scrolling separately
|
|
4424
4487
|
* (e.g. via `scrollToFirstError`) and don't want the browser to
|
|
4425
4488
|
* fight the explicit scroll.
|
|
4489
|
+
*
|
|
4490
|
+
* Requests `focusVisible: true` so the UA paints a focus ring even
|
|
4491
|
+
* though the move is programmatic. Honored where supported; on
|
|
4492
|
+
* browsers without it, non-text controls focused after a pointer
|
|
4493
|
+
* submit may show no ring, so you may still want an app-side
|
|
4494
|
+
* indicator.
|
|
4426
4495
|
*/
|
|
4427
4496
|
focusFirstError: (options?: {
|
|
4428
4497
|
preventScroll?: boolean;
|
|
@@ -137,8 +137,8 @@ declare function canonicalizePath(input: string | Path): {
|
|
|
137
137
|
* `Path` to address the form value as a whole, and the home for
|
|
138
138
|
* form-level (global) errors: root `.refine()` messages, hydration
|
|
139
139
|
* failures, and `setErrors` entries with no path all live at `[]`. Aggregate
|
|
140
|
-
* reads (`errors()`, `meta.errors`) surface them alongside
|
|
141
|
-
* errors; `
|
|
140
|
+
* reads (`errors()`, `errors([])`, `meta.errors`) surface them alongside
|
|
141
|
+
* field errors; `meta.ownErrors` returns the root bucket alone.
|
|
142
142
|
*
|
|
143
143
|
* The empty SEGMENT tuple `[]` is structurally unconstructible as a
|
|
144
144
|
* field path, so it can never collide with a schema key, unlike the
|
|
@@ -1396,6 +1396,14 @@ type ReactiveValidationStatus<Form> = PendingValidationStatus | SettledValidatio
|
|
|
1396
1396
|
* manually via `form.focusFirstError()` or `form.scrollToFirstError()`
|
|
1397
1397
|
* from an `onError` callback.
|
|
1398
1398
|
*
|
|
1399
|
+
* Both focusing policies request `focusVisible: true`, so the browser
|
|
1400
|
+
* paints a focus ring even though the move is programmatic. Where a UA
|
|
1401
|
+
* doesn't yet support that hint, non-text controls (radio, checkbox,
|
|
1402
|
+
* custom widgets) may end up focused without a visible ring after a
|
|
1403
|
+
* pointer-driven submit; if you target those browsers, pair the policy
|
|
1404
|
+
* with your own indicator (e.g. a `:focus-within` ring on the option
|
|
1405
|
+
* wrapper).
|
|
1406
|
+
*
|
|
1399
1407
|
* If no errored field has a currently mounted, visible element, the
|
|
1400
1408
|
* policy silently no-ops.
|
|
1401
1409
|
*/
|
|
@@ -2066,14 +2074,15 @@ type OnError = (error: ValidationError[]) => void | Promise<void>;
|
|
|
2066
2074
|
type DisplayState = 'idle' | 'pending' | 'error' | 'success';
|
|
2067
2075
|
/**
|
|
2068
2076
|
* Keys on `FieldState` layered on FROM the display-state predicate
|
|
2069
|
-
* (plus `firstError`, computed alongside them).
|
|
2070
|
-
* predicate's arguments so a predicate cannot read
|
|
2071
|
-
* form a cycle — enforced at the type level AND at
|
|
2072
|
-
* objects passed in literally lack these keys, so an
|
|
2073
|
-
* or a vanilla-JS caller still can't reach them.
|
|
2074
|
-
* `FormMetaBase` (field-state-api.ts) omit the same
|
|
2077
|
+
* (plus `firstError` / `firstOwnError`, computed alongside them).
|
|
2078
|
+
* `Omit`'d from the predicate's arguments so a predicate cannot read
|
|
2079
|
+
* its own output and form a cycle — enforced at the type level AND at
|
|
2080
|
+
* runtime: the base objects passed in literally lack these keys, so an
|
|
2081
|
+
* `as` cast in TS or a vanilla-JS caller still can't reach them.
|
|
2082
|
+
* `FieldStateBase` / `FormMetaBase` (field-state-api.ts) omit the same
|
|
2083
|
+
* set in lockstep.
|
|
2075
2084
|
*/
|
|
2076
|
-
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError';
|
|
2085
|
+
type FieldStateDerivedKey = 'displayState' | 'showErrors' | 'showPending' | 'showSuccess' | 'showIdle' | 'firstError' | 'firstOwnError';
|
|
2077
2086
|
/**
|
|
2078
2087
|
* One step of the display state machine: the verdict the field should
|
|
2079
2088
|
* render right now (`display`, projected to `displayState` and the
|
|
@@ -3106,7 +3115,40 @@ type FieldState<Value = unknown> = {
|
|
|
3106
3115
|
*/
|
|
3107
3116
|
readonly elements: readonly HTMLElement[];
|
|
3108
3117
|
readonly updatedAt: string | null;
|
|
3118
|
+
/**
|
|
3119
|
+
* Every `ValidationError` in this path's SUBTREE: the node's own
|
|
3120
|
+
* bucket plus every descendant's, sorted by schema-declaration order.
|
|
3121
|
+
* On a leaf (no descendants) this equals `ownErrors`. On a container
|
|
3122
|
+
* it rolls up the whole fieldset, so a parent's `errors` is non-empty
|
|
3123
|
+
* whenever any child is invalid.
|
|
3124
|
+
*
|
|
3125
|
+
* For the errors pinned at THIS path alone (a container's own
|
|
3126
|
+
* cross-field `.refine()`, or `setErrors` at this path), read
|
|
3127
|
+
* `ownErrors`.
|
|
3128
|
+
*/
|
|
3109
3129
|
readonly errors: readonly ValidationError[];
|
|
3130
|
+
/**
|
|
3131
|
+
* Every `ValidationError` at THIS exact path's own bucket, excluding
|
|
3132
|
+
* descendants: schema errors, blank-required errors, and `setErrors`
|
|
3133
|
+
* pinned here, in `schema`, `blank`, `user` order. The exact-path
|
|
3134
|
+
* counterpart to the subtree-scoped `errors`.
|
|
3135
|
+
*
|
|
3136
|
+
* On a leaf this is the same array as `errors` (a leaf has no
|
|
3137
|
+
* descendants). On a container it holds only the container's OWN
|
|
3138
|
+
* errors, a cross-field `.refine()` on the fieldset or a path-less
|
|
3139
|
+
* `setErrors` at this node, without dragging in any child error:
|
|
3140
|
+
*
|
|
3141
|
+
* ```vue
|
|
3142
|
+
* <p v-if="form.fields.address.firstOwnError">
|
|
3143
|
+
* {{ form.fields.address.firstOwnError.message }}
|
|
3144
|
+
* </p>
|
|
3145
|
+
* ```
|
|
3146
|
+
*
|
|
3147
|
+
* On `form.meta` this is the root `[]` bucket: form-level errors from
|
|
3148
|
+
* a root `.refine()` or a path-less `setErrors`. `form.meta.ownErrors`
|
|
3149
|
+
* (with `firstOwnError`) is the banner accessor for those.
|
|
3150
|
+
*/
|
|
3151
|
+
readonly ownErrors: readonly ValidationError[];
|
|
3110
3152
|
/**
|
|
3111
3153
|
* `true` while a per-field validation run is in flight at this path.
|
|
3112
3154
|
* Reflects field-level debounced runs (`validate-on-change`) and
|
|
@@ -3227,9 +3269,28 @@ type FieldState<Value = unknown> = {
|
|
|
3227
3269
|
* decides when to render it.
|
|
3228
3270
|
*
|
|
3229
3271
|
* On container paths, the first error in the aggregated subtree
|
|
3230
|
-
* (descendants sorted by `pathOrdinal`).
|
|
3272
|
+
* (descendants sorted by `pathOrdinal`). For the container's OWN
|
|
3273
|
+
* first error only, read `firstOwnError`.
|
|
3231
3274
|
*/
|
|
3232
3275
|
readonly firstError: ValidationError | undefined;
|
|
3276
|
+
/**
|
|
3277
|
+
* The first `ValidationError` in `ownErrors` (this exact path's own
|
|
3278
|
+
* bucket), or `undefined` when that bucket is empty. Equivalent to
|
|
3279
|
+
* `ownErrors[0]`, the exact-path counterpart to `firstError`.
|
|
3280
|
+
*
|
|
3281
|
+
* On a leaf this equals `firstError`. On a container it is the
|
|
3282
|
+
* container's own cross-field error (a fieldset `.refine()`), never a
|
|
3283
|
+
* child's. `form.meta.firstOwnError` is the form-level banner: the
|
|
3284
|
+
* first root `[]` error from a root `.refine()` or a path-less
|
|
3285
|
+
* `setErrors`:
|
|
3286
|
+
*
|
|
3287
|
+
* ```vue
|
|
3288
|
+
* <p v-if="form.meta.firstOwnError" role="alert">
|
|
3289
|
+
* {{ form.meta.firstOwnError.message }}
|
|
3290
|
+
* </p>
|
|
3291
|
+
* ```
|
|
3292
|
+
*/
|
|
3293
|
+
readonly firstOwnError: ValidationError | undefined;
|
|
3233
3294
|
readonly path: ReadonlyArray<string | number>;
|
|
3234
3295
|
/**
|
|
3235
3296
|
* Stable, SSR-safe DOM id for this field, unique across every mount
|
|
@@ -3593,11 +3654,13 @@ type FormErrorsSurface<Form> = ErrorsProxyShape<Form> & {
|
|
|
3593
3654
|
<const S extends ReadonlyArray<string | number>>(segments: S & ([JoinSegments<S>] extends [FlatPath<Form>] ? unknown : never)): readonly ValidationError[];
|
|
3594
3655
|
(segments: ReadonlyArray<string | number>): readonly ValidationError[];
|
|
3595
3656
|
/**
|
|
3596
|
-
* No-arg call returns the whole-form error aggregate
|
|
3597
|
-
* `form.meta.errors`: every field error plus
|
|
3598
|
-
*
|
|
3599
|
-
*
|
|
3600
|
-
*
|
|
3657
|
+
* No-arg call returns the whole-form error aggregate, the same as
|
|
3658
|
+
* `form.meta.errors` and `form.errors([])`: every field error plus
|
|
3659
|
+
* the root bucket. `form.errors(path)` is uniform at every depth,
|
|
3660
|
+
* including `[]`, so the root is no exception. For the root bucket
|
|
3661
|
+
* alone (a root `.refine()`, a path-less `setErrors`), read
|
|
3662
|
+
* `form.meta.ownErrors`. Always a readonly array; empty when the form
|
|
3663
|
+
* has no errors.
|
|
3601
3664
|
*/
|
|
3602
3665
|
(): readonly ValidationError[];
|
|
3603
3666
|
};
|
|
@@ -3705,8 +3768,8 @@ type FormMeta<F = unknown> = FieldState<F> & {
|
|
|
3705
3768
|
* `getDisplayState` predicates) but does NOT drive the library's
|
|
3706
3769
|
* default `getDisplayState` heuristic. The reveal-on-submit story
|
|
3707
3770
|
* runs entirely through `submissionAttempts`, which
|
|
3708
|
-
* `wizard.handleSubmit` bumps on
|
|
3709
|
-
*
|
|
3771
|
+
* `wizard.handleSubmit` bumps on every form (it always validates the
|
|
3772
|
+
* whole step list).
|
|
3710
3773
|
*
|
|
3711
3774
|
* Distinct from `submissionAttempts`, which counts `handleSubmit`
|
|
3712
3775
|
* passes only — wizard departures and form submissions are tracked
|
|
@@ -4423,6 +4486,12 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
|
|
|
4423
4486
|
* Pass `{ preventScroll: true }` if you're scrolling separately
|
|
4424
4487
|
* (e.g. via `scrollToFirstError`) and don't want the browser to
|
|
4425
4488
|
* fight the explicit scroll.
|
|
4489
|
+
*
|
|
4490
|
+
* Requests `focusVisible: true` so the UA paints a focus ring even
|
|
4491
|
+
* though the move is programmatic. Honored where supported; on
|
|
4492
|
+
* browsers without it, non-text controls focused after a pointer
|
|
4493
|
+
* submit may show no ring, so you may still want an app-side
|
|
4494
|
+
* indicator.
|
|
4426
4495
|
*/
|
|
4427
4496
|
focusFirstError: (options?: {
|
|
4428
4497
|
preventScroll?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { shallowReactive, getCurrentInstance, inject, effectScope, watch, warn, nextTick } from 'vue';
|
|
2
|
-
import { i as isRegisterValue, a as isTransforming, S as SSR_COMPONENT_HOST_MODIFIER, R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER } from './attaform.
|
|
2
|
+
import { i as isRegisterValue, a as isTransforming, S as SSR_COMPONENT_HOST_MODIFIER, R as REGISTER_OWNER_MARKER, V as V_REGISTER_COMPILED_MODIFIER, b as V_REGISTER_MARKER } from './attaform.Vp2-CWZB.mjs';
|
|
3
3
|
|
|
4
4
|
const __DEV__ = (typeof process !== "undefined" ? process.env.NODE_ENV : "production") !== "production";
|
|
5
5
|
|
|
@@ -25,6 +25,28 @@ function toError(value) {
|
|
|
25
25
|
const message = typeof value === "string" && value.length > 0 ? value : `Submit callback threw a non-Error value (${typeof value})`;
|
|
26
26
|
return new Error(message, { cause: value });
|
|
27
27
|
}
|
|
28
|
+
function normalizeErrorInput(item, scope, formKey, defaultCode) {
|
|
29
|
+
if (item instanceof Error) {
|
|
30
|
+
return {
|
|
31
|
+
message: item.message.length > 0 ? item.message : "Unknown error",
|
|
32
|
+
path: scope !== void 0 ? [...scope] : [],
|
|
33
|
+
formKey,
|
|
34
|
+
code: defaultCode
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const entry = {
|
|
38
|
+
message: typeof item.message === "string" && item.message.length > 0 ? item.message : "Unknown error",
|
|
39
|
+
path: scope !== void 0 ? [...scope] : Array.isArray(item.path) ? [...item.path] : [],
|
|
40
|
+
formKey,
|
|
41
|
+
code: typeof item.code === "string" && item.code.length > 0 ? item.code : defaultCode
|
|
42
|
+
};
|
|
43
|
+
if (item.data !== void 0) entry.data = item.data;
|
|
44
|
+
return entry;
|
|
45
|
+
}
|
|
46
|
+
function normalizeErrorInputs(input, scope, formKey, defaultCode) {
|
|
47
|
+
const items = Array.isArray(input) ? input : [input];
|
|
48
|
+
return items.map((item) => normalizeErrorInput(item, scope, formKey, defaultCode));
|
|
49
|
+
}
|
|
28
50
|
class RegistryNotInstalledError extends AttaformError {
|
|
29
51
|
constructor() {
|
|
30
52
|
super(
|
|
@@ -1200,6 +1222,7 @@ function getCheckboxValue(el, checked) {
|
|
|
1200
1222
|
return key in el ? el[key] : checked;
|
|
1201
1223
|
}
|
|
1202
1224
|
const warnedUnsupportedElements = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
1225
|
+
const warnedRedundantBindings = __DEV__ ? /* @__PURE__ */ new Set() : null;
|
|
1203
1226
|
const componentHostLatch = /* @__PURE__ */ new WeakMap();
|
|
1204
1227
|
const hostFocusListeners = /* @__PURE__ */ new WeakMap();
|
|
1205
1228
|
const hostHealObservers = /* @__PURE__ */ new WeakMap();
|
|
@@ -1286,6 +1309,7 @@ const vRegisterDynamic = {
|
|
|
1286
1309
|
created(el, binding, vnode) {
|
|
1287
1310
|
callModelHook(el, binding, vnode, null, "created");
|
|
1288
1311
|
if (isRegisterValue(binding.value)) setupAria(el, binding.value, vnode);
|
|
1312
|
+
if (__DEV__) warnRedundantStateBinding(el, binding, vnode);
|
|
1289
1313
|
},
|
|
1290
1314
|
mounted(el, binding, vnode) {
|
|
1291
1315
|
callModelHook(el, binding, vnode, null, "mounted");
|
|
@@ -1383,6 +1407,27 @@ function resolveDynamicModel(tagName, type) {
|
|
|
1383
1407
|
if (type === "radio") return vRegisterRadio;
|
|
1384
1408
|
return vRegisterText;
|
|
1385
1409
|
}
|
|
1410
|
+
function warnRedundantStateBinding(el, binding, vnode) {
|
|
1411
|
+
if (warnedRedundantBindings === null) return;
|
|
1412
|
+
if (!INTERACTIVE_TAG_NAMES.has(el.tagName)) return;
|
|
1413
|
+
if (binding.modifiers[V_REGISTER_COMPILED_MODIFIER] === true) return;
|
|
1414
|
+
const props = vnode.props;
|
|
1415
|
+
if (props == null) return;
|
|
1416
|
+
const variant = resolveDynamicModel(el.tagName, props["type"]);
|
|
1417
|
+
if (variant === vRegisterFile) return;
|
|
1418
|
+
const hasVModel = "onUpdate:modelValue" in props;
|
|
1419
|
+
const stateAttr = variant === vRegisterCheckbox || variant === vRegisterRadio ? "checked" : "value";
|
|
1420
|
+
const hasStateAttr = stateAttr in props;
|
|
1421
|
+
if (!hasVModel && !hasStateAttr) return;
|
|
1422
|
+
const tag = el.tagName.toLowerCase();
|
|
1423
|
+
const redundant = hasVModel ? "v-model" : `:${stateAttr}`;
|
|
1424
|
+
const signature = `${tag}:${String(props["type"] ?? "")}:${redundant}`;
|
|
1425
|
+
if (warnedRedundantBindings.has(signature)) return;
|
|
1426
|
+
warnedRedundantBindings.add(signature);
|
|
1427
|
+
warn(
|
|
1428
|
+
`[attaform] \`${redundant}\` is redundant beside v-register on <${tag}>. v-register already drives this field's value, so keep v-register alone and drop \`${redundant}\`. (An identity \`:value\` on a radio or <option> is expected and stays silent.)`
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1386
1431
|
function ssrCheckboxProps(rv, props) {
|
|
1387
1432
|
const model = rv.innerRef.value;
|
|
1388
1433
|
const optionValue = props?.["value"];
|
|
@@ -1569,5 +1614,5 @@ function pathsEqual(a, b) {
|
|
|
1569
1614
|
return true;
|
|
1570
1615
|
}
|
|
1571
1616
|
|
|
1572
|
-
export { AttaformError as A, InvalidPathError as I, OutsideSetupError as O, ROOT_PATH as R, SubmitErrorHandlerError as S, __DEV__ as _, InvalidUseFormConfigError as a, ROOT_PATH_KEY as b, RegistryNotInstalledError as c, ReservedFormKeyError as d, assignKey as e, canonicalizePath as f, createAttaform as g, createRegistry as h, getRegistryFromApp as i, isPathPrefix as j, kAttaformRegistry as k, kAttaformWizardActiveStepResolver as l, pathKeyToDotted as m, pathsEqual as n, keyForSegments as o, parseDottedPath as p,
|
|
1573
|
-
//# sourceMappingURL=attaform.
|
|
1617
|
+
export { AttaformError as A, kFormInstanceId as B, kAttaformAncestorWizard as C, InvalidPathError as I, OutsideSetupError as O, ROOT_PATH as R, SubmitErrorHandlerError as S, __DEV__ as _, InvalidUseFormConfigError as a, ROOT_PATH_KEY as b, RegistryNotInstalledError as c, ReservedFormKeyError as d, assignKey as e, canonicalizePath as f, createAttaform as g, createRegistry as h, getRegistryFromApp as i, isPathPrefix as j, kAttaformRegistry as k, kAttaformWizardActiveStepResolver as l, pathKeyToDotted as m, pathsEqual as n, keyForSegments as o, parseDottedPath as p, normalizeErrorInput as q, INTERACTIVE_TAG_NAMES as r, segmentsForPathKey as s, toError as t, useRegistry as u, vRegister as v, normalizeErrorInputs as w, coerceToPathKey as x, ensureAttaformInstalled as y, kFormContext as z };
|
|
1618
|
+
//# sourceMappingURL=attaform.DGhIix5D.mjs.map
|