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.
Files changed (92) hide show
  1. package/dist/chunks/devtools.cjs +1 -1
  2. package/dist/chunks/devtools.mjs +1 -1
  3. package/dist/chunks/fingerprint2.cjs +1 -1
  4. package/dist/chunks/fingerprint2.mjs +1 -1
  5. package/dist/index.cjs +4 -4
  6. package/dist/index.d.cts +5 -5
  7. package/dist/index.d.mts +5 -5
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.mjs +4 -4
  10. package/dist/nuxt.d.cts +1 -1
  11. package/dist/nuxt.d.mts +1 -1
  12. package/dist/nuxt.d.ts +1 -1
  13. package/dist/runtime/plugins/attaform.cjs +2 -2
  14. package/dist/runtime/plugins/attaform.mjs +2 -2
  15. package/dist/shared/{attaform.CO0e7YVY.d.cts → attaform.55hFR_cl.d.ts} +3 -0
  16. package/dist/shared/{attaform.Ib7oSpxj.d.cts → attaform.B71rfNL5.d.mts} +1 -1
  17. package/dist/shared/{attaform.DTn1J0Eq.d.mts → attaform.BFfY7HRI.d.cts} +1 -1
  18. package/dist/shared/{attaform.CAVK56f8.cjs → attaform.BPl-ECRT.cjs} +49 -2
  19. package/dist/shared/attaform.BPl-ECRT.cjs.map +1 -0
  20. package/dist/shared/{attaform.CBMI57RP.cjs → attaform.BQflyVOL.cjs} +3 -3
  21. package/dist/shared/{attaform.CBMI57RP.cjs.map → attaform.BQflyVOL.cjs.map} +1 -1
  22. package/dist/shared/{attaform.DWKcw1ud.cjs → attaform.BRzKBj2g.cjs} +101 -4
  23. package/dist/shared/attaform.BRzKBj2g.cjs.map +1 -0
  24. package/dist/shared/{attaform.EeVCVnoH.d.ts → attaform.Be5otUVw.d.ts} +1 -1
  25. package/dist/shared/{attaform.iJ4y3sHU.mjs → attaform.BoYqnIPI.mjs} +223 -81
  26. package/dist/shared/attaform.BoYqnIPI.mjs.map +1 -0
  27. package/dist/shared/{attaform.B1N47eDM.d.ts → attaform.CEY_WLRJ.d.mts} +127 -56
  28. package/dist/shared/{attaform.CwqTCeTZ.mjs → attaform.CSXDW2tO.mjs} +4 -4
  29. package/dist/shared/{attaform.CwqTCeTZ.mjs.map → attaform.CSXDW2tO.mjs.map} +1 -1
  30. package/dist/shared/{attaform.lcTiMoma.mjs → attaform.CXVmZtFq.mjs} +3 -3
  31. package/dist/shared/{attaform.lcTiMoma.mjs.map → attaform.CXVmZtFq.mjs.map} +1 -1
  32. package/dist/shared/{attaform.CE-KJZ0j.cjs → attaform.Cs0UZ7q6.cjs} +4 -4
  33. package/dist/shared/{attaform.CE-KJZ0j.cjs.map → attaform.Cs0UZ7q6.cjs.map} +1 -1
  34. package/dist/shared/{attaform.AkX9wzfY.cjs → attaform.D51IwDtP.cjs} +2 -2
  35. package/dist/shared/{attaform.AkX9wzfY.cjs.map → attaform.D51IwDtP.cjs.map} +1 -1
  36. package/dist/shared/{attaform.QFrCtJBO.d.mts → attaform.DBNjHgNj.d.cts} +86 -17
  37. package/dist/shared/{attaform.QFrCtJBO.d.cts → attaform.DBNjHgNj.d.mts} +86 -17
  38. package/dist/shared/{attaform.QFrCtJBO.d.ts → attaform.DBNjHgNj.d.ts} +86 -17
  39. package/dist/shared/{attaform.DwsfkfSY.mjs → attaform.DGhIix5D.mjs} +48 -3
  40. package/dist/shared/attaform.DGhIix5D.mjs.map +1 -0
  41. package/dist/shared/{attaform.CO0e7YVY.d.mts → attaform.DJRz_bzM.d.cts} +3 -0
  42. package/dist/shared/{attaform.ChY7tIrn.mjs → attaform.DSOIz08n.mjs} +4 -4
  43. package/dist/shared/{attaform.ChY7tIrn.mjs.map → attaform.DSOIz08n.mjs.map} +1 -1
  44. package/dist/shared/{attaform.Buedl_UL.cjs → attaform.Du9RZp8m.cjs} +223 -81
  45. package/dist/shared/attaform.Du9RZp8m.cjs.map +1 -0
  46. package/dist/shared/{attaform.CO0e7YVY.d.ts → attaform.JPsaqjLl.d.mts} +3 -0
  47. package/dist/shared/{attaform.CqW4gF_Z.d.cts → attaform.MgaYKlPP.d.cts} +127 -56
  48. package/dist/shared/{attaform.CZpUm-2l.mjs → attaform.NqYEzRcM.mjs} +2 -2
  49. package/dist/shared/{attaform.CZpUm-2l.mjs.map → attaform.NqYEzRcM.mjs.map} +1 -1
  50. package/dist/shared/{attaform.WvcckZMD.mjs → attaform.Vp2-CWZB.mjs} +3 -2
  51. package/dist/shared/attaform.Vp2-CWZB.mjs.map +1 -0
  52. package/dist/shared/{attaform.CjdepGnw.cjs → attaform.ZXZ6dH72.cjs} +3 -1
  53. package/dist/shared/attaform.ZXZ6dH72.cjs.map +1 -0
  54. package/dist/shared/{attaform.f0l5ydy1.d.mts → attaform.ceYeVkjn.d.ts} +127 -56
  55. package/dist/shared/{attaform.QwLSdxuk.mjs → attaform.k9V0py0s.mjs} +101 -5
  56. package/dist/shared/attaform.k9V0py0s.mjs.map +1 -0
  57. package/dist/shared/{attaform.Bnm0FQaH.cjs → attaform.tZ0YKisf.cjs} +4 -4
  58. package/dist/shared/{attaform.Bnm0FQaH.cjs.map → attaform.tZ0YKisf.cjs.map} +1 -1
  59. package/dist/transforms.cjs +2 -1
  60. package/dist/transforms.cjs.map +1 -1
  61. package/dist/transforms.d.cts +13 -1
  62. package/dist/transforms.d.mts +13 -1
  63. package/dist/transforms.d.ts +13 -1
  64. package/dist/transforms.mjs +1 -1
  65. package/dist/vite.cjs +2 -1
  66. package/dist/vite.cjs.map +1 -1
  67. package/dist/vite.mjs +2 -1
  68. package/dist/vite.mjs.map +1 -1
  69. package/dist/zod-v3.cjs +2 -2
  70. package/dist/zod-v3.d.cts +3 -3
  71. package/dist/zod-v3.d.mts +3 -3
  72. package/dist/zod-v3.d.ts +3 -3
  73. package/dist/zod-v3.mjs +2 -2
  74. package/dist/zod-v4.cjs +2 -2
  75. package/dist/zod-v4.d.cts +6 -6
  76. package/dist/zod-v4.d.mts +6 -6
  77. package/dist/zod-v4.d.ts +6 -6
  78. package/dist/zod-v4.mjs +2 -2
  79. package/dist/zod.cjs +5 -5
  80. package/dist/zod.d.cts +5 -5
  81. package/dist/zod.d.mts +5 -5
  82. package/dist/zod.d.ts +5 -5
  83. package/dist/zod.mjs +5 -5
  84. package/package.json +1 -1
  85. package/dist/shared/attaform.Buedl_UL.cjs.map +0 -1
  86. package/dist/shared/attaform.CAVK56f8.cjs.map +0 -1
  87. package/dist/shared/attaform.CjdepGnw.cjs.map +0 -1
  88. package/dist/shared/attaform.DWKcw1ud.cjs.map +0 -1
  89. package/dist/shared/attaform.DwsfkfSY.mjs.map +0 -1
  90. package/dist/shared/attaform.QwLSdxuk.mjs.map +0 -1
  91. package/dist/shared/attaform.WvcckZMD.mjs.map +0 -1
  92. package/dist/shared/attaform.iJ4y3sHU.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const paths = require('./attaform.CAVK56f8.cjs');
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.AkX9wzfY.cjs.map
39
+ //# sourceMappingURL=attaform.D51IwDtP.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"attaform.AkX9wzfY.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;;;;;;"}
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 field
141
- * errors; `errors([])` returns the global bucket alone.
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). `Omit`'d from the
2070
- * predicate's arguments so a predicate cannot read its own output and
2071
- * form a cycle — enforced at the type level AND at runtime: the base
2072
- * objects passed in literally lack these keys, so an `as` cast in TS
2073
- * or a vanilla-JS caller still can't reach them. `FieldStateBase` /
2074
- * `FormMetaBase` (field-state-api.ts) omit the same set in lockstep.
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 same as
3597
- * `form.meta.errors`: every field error plus the global bucket.
3598
- * Distinct from `form.errors([])`, which returns ONLY the global
3599
- * (root) bucket. Always a readonly array; empty when the form has no
3600
- * errors.
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 the active form at intermediate
3709
- * steps and on every form at the final step.
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 field
141
- * errors; `errors([])` returns the global bucket alone.
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). `Omit`'d from the
2070
- * predicate's arguments so a predicate cannot read its own output and
2071
- * form a cycle — enforced at the type level AND at runtime: the base
2072
- * objects passed in literally lack these keys, so an `as` cast in TS
2073
- * or a vanilla-JS caller still can't reach them. `FieldStateBase` /
2074
- * `FormMetaBase` (field-state-api.ts) omit the same set in lockstep.
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 same as
3597
- * `form.meta.errors`: every field error plus the global bucket.
3598
- * Distinct from `form.errors([])`, which returns ONLY the global
3599
- * (root) bucket. Always a readonly array; empty when the form has no
3600
- * errors.
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 the active form at intermediate
3709
- * steps and on every form at the final step.
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 field
141
- * errors; `errors([])` returns the global bucket alone.
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). `Omit`'d from the
2070
- * predicate's arguments so a predicate cannot read its own output and
2071
- * form a cycle — enforced at the type level AND at runtime: the base
2072
- * objects passed in literally lack these keys, so an `as` cast in TS
2073
- * or a vanilla-JS caller still can't reach them. `FieldStateBase` /
2074
- * `FormMetaBase` (field-state-api.ts) omit the same set in lockstep.
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 same as
3597
- * `form.meta.errors`: every field error plus the global bucket.
3598
- * Distinct from `form.errors([])`, which returns ONLY the global
3599
- * (root) bucket. Always a readonly array; empty when the form has no
3600
- * errors.
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 the active form at intermediate
3709
- * steps and on every form at the final step.
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.WvcckZMD.mjs';
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, INTERACTIVE_TAG_NAMES as q, coerceToPathKey as r, segmentsForPathKey as s, toError as t, useRegistry as u, vRegister as v, ensureAttaformInstalled as w, kFormContext as x, kFormInstanceId as y, kAttaformAncestorWizard as z };
1573
- //# sourceMappingURL=attaform.DwsfkfSY.mjs.map
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