[{"data":1,"prerenderedAt":2442},["ShallowReactive",2],{"content-\u002Fdocs\u002Fapi\u002Fcore":3},{"id":4,"title":5,"body":6,"description":18,"extension":2436,"meta":2437,"navigation":634,"path":2438,"seo":2439,"stem":2440,"__hash__":2441},"docs\u002Fdocs\u002Fapi\u002Fcore.md","attaform",{"type":7,"value":8,"toc":2415},"minimark",[9,15,19,118,125,128,165,168,263,269,287,293,302,309,343,348,354,364,370,381,387,393,399,424,466,472,482,485,562,585,799,804,817,962,968,986,993,1004,1191,1203,1206,1235,1267,1280,1287,1293,1441,1469,1483,1489,1497,1503,1523,1531,1552,1561,1567,1578,1584,1606,1612,1646,1649,1711,1821,1843,1851,1855,1868,1950,1957,2030,2035,2049,2054,2084,2200,2203,2240,2263,2280,2286,2312,2316,2411],[10,11,12],"h1",{"id":5},[13,14,5],"code",{},[16,17,18],"p",{},"The framework-agnostic core. Use this if you're bringing your own\nschema library or wiring SSR by hand.",[20,21,26],"pre",{"className":22,"code":23,"language":24,"meta":25,"style":25},"language-ts shiki shiki-themes github-light github-dark","import {\n  createAttaform,\n  useForm, \u002F\u002F re-export of useAbstractForm\n  injectForm,\n  useRegistry,\n  renderAttaformState,\n  hydrateAttaformState,\n  escapeForInlineScript,\n  vRegister,\n  canonicalizePath,\n  parseApiErrors,\n} from 'attaform'\n","ts","",[13,27,28,41,47,57,63,69,75,81,87,93,99,105],{"__ignoreMap":25},[29,30,33,37],"span",{"class":31,"line":32},"line",1,[29,34,36],{"class":35},"szBVR","import",[29,38,40],{"class":39},"sVt8B"," {\n",[29,42,44],{"class":31,"line":43},2,[29,45,46],{"class":39},"  createAttaform,\n",[29,48,50,53],{"class":31,"line":49},3,[29,51,52],{"class":39},"  useForm, ",[29,54,56],{"class":55},"sJ8bj","\u002F\u002F re-export of useAbstractForm\n",[29,58,60],{"class":31,"line":59},4,[29,61,62],{"class":39},"  injectForm,\n",[29,64,66],{"class":31,"line":65},5,[29,67,68],{"class":39},"  useRegistry,\n",[29,70,72],{"class":31,"line":71},6,[29,73,74],{"class":39},"  renderAttaformState,\n",[29,76,78],{"class":31,"line":77},7,[29,79,80],{"class":39},"  hydrateAttaformState,\n",[29,82,84],{"class":31,"line":83},8,[29,85,86],{"class":39},"  escapeForInlineScript,\n",[29,88,90],{"class":31,"line":89},9,[29,91,92],{"class":39},"  vRegister,\n",[29,94,96],{"class":31,"line":95},10,[29,97,98],{"class":39},"  canonicalizePath,\n",[29,100,102],{"class":31,"line":101},11,[29,103,104],{"class":39},"  parseApiErrors,\n",[29,106,108,111,114],{"class":31,"line":107},12,[29,109,110],{"class":39},"} ",[29,112,113],{"class":35},"from",[29,115,117],{"class":116},"sZZnC"," 'attaform'\n",[119,120,122],"h2",{"id":121},"createattaformoptions",[13,123,124],{},"createAttaform(options?)",[16,126,127],{},"The Vue plugin. Install once per app.",[20,129,131],{"className":22,"code":130,"language":24,"meta":25,"style":25},"createApp(App).use(createAttaform()).mount('#app')\n",[13,132,133],{"__ignoreMap":25},[29,134,135,139,142,145,148,151,154,157,159,162],{"class":31,"line":32},[29,136,138],{"class":137},"sScJk","createApp",[29,140,141],{"class":39},"(App).",[29,143,144],{"class":137},"use",[29,146,147],{"class":39},"(",[29,149,150],{"class":137},"createAttaform",[29,152,153],{"class":39},"()).",[29,155,156],{"class":137},"mount",[29,158,147],{"class":39},[29,160,161],{"class":116},"'#app'",[29,163,164],{"class":39},")\n",[16,166,167],{},"Options:",[169,170,171,187],"table",{},[172,173,174],"thead",{},[175,176,177,181,184],"tr",{},[178,179,180],"th",{},"Field",[178,182,183],{},"Type",[178,185,186],{},"Description",[188,189,190,218,241],"tbody",{},[175,191,192,198,203],{},[193,194,195],"td",{},[13,196,197],{},"override",[193,199,200],{},[13,201,202],{},"boolean",[193,204,205,206,209,210,213,214,217],{},"Force ",[13,207,208],{},"isSSR"," to ",[13,211,212],{},"true"," \u002F ",[13,215,216],{},"false",". Auto-detected otherwise.",[175,219,220,225,229],{},[193,221,222],{},[13,223,224],{},"devtools",[193,226,227],{},[13,228,202],{},[193,230,231,232,234,235,240],{},"Enable the Vue DevTools plugin. Default ",[13,233,212],{},". See ",[236,237,239],"a",{"href":238},"\u002Fdocs\u002Frecipes\u002Fdevtools","recipe",".",[175,242,243,248,253],{},[193,244,245],{},[13,246,247],{},"defaults",[193,249,250],{},[13,251,252],{},"AttaformDefaults",[193,254,255,256,259,260,240],{},"App-level option defaults applied to every ",[13,257,258],{},"useForm"," call. See ",[236,261,239],{"href":262},"\u002Fdocs\u002Frecipes\u002Fapp-defaults",[119,264,266],{"id":265},"useformform-schema-key",[13,267,268],{},"useForm\u003CForm>({ schema, key, ... })",[16,270,271,272,275,276,280,281,240],{},"Schema-agnostic. Takes any ",[13,273,274],{},"AbstractSchema\u003CForm, Form>"," — wrap a\nValibot schema, ArkType schema, or a hand-rolled validator with\n",[236,277,279],{"href":278},"\u002Fdocs\u002Frecipes\u002Fcustom-adapter","a custom adapter",". The Zod subpaths\nare pre-made wrappers over this. For options, see\n",[236,282,284],{"href":283},"\u002Fdocs\u002Fapi\u002Fzod#useformschemaoptions",[13,285,286],{},"attaform\u002Fzod",[119,288,290],{"id":289},"injectformformkey",[13,291,292],{},"injectForm\u003CForm>(key?)",[16,294,295,296,298,299,240],{},"Reach the nearest ancestor's form (no key) or reach any form by its\nkey. Type-identical return to ",[13,297,258],{},". See\n",[236,300,239],{"href":301},"\u002Fdocs\u002Frecipes\u002Fform-context",[16,303,304,308],{},[305,306,307],"strong",{},"Resolution rules"," (no-key form):",[310,311,312,316,330,337],"ul",{},[313,314,315],"li",{},"Closest ambient ancestor wins.",[313,317,318,319,322,323,326,327,240],{},"Only anonymous ",[13,320,321],{},"useForm()"," (no ",[13,324,325],{},"key",") fills the ambient slot;\nkeyed forms are reachable only via ",[13,328,329],{},"injectForm(key)",[313,331,332,333,336],{},"No ambient ancestor → returns ",[13,334,335],{},"null"," (dev-mode warn).",[313,338,339,340,240],{},"Inherits the resolved ancestor's ",[13,341,342],{},"formInstanceId",[16,344,345,347],{},[305,346,307],{}," (keyed form): registry lookup by string key,\nindependent of component-tree position.",[119,349,351],{"id":350},"useregistry",[13,352,353],{},"useRegistry()",[16,355,356,357,360,361,240],{},"Returns the current app's ",[13,358,359],{},"AttaformRegistry",". Must be called inside\na component's ",[13,362,363],{},"setup()",[119,365,367],{"id":366},"renderattaformstateapp-serializedattaformstate",[13,368,369],{},"renderAttaformState(app) → SerializedAttaformState",[16,371,372,373,376,377,380],{},"Server-side: serialize every form in the app to a plain object safe\nfor ",[13,374,375],{},"JSON.stringify",". Pair with ",[13,378,379],{},"hydrateAttaformState"," on the\nclient.",[119,382,384],{"id":383},"hydrateattaformstateapp-payload",[13,385,386],{},"hydrateAttaformState(app, payload)",[16,388,389,390,240],{},"Client-side: rehydrate forms from the serialized payload. Call\nbefore ",[13,391,392],{},"app.mount(...)",[119,394,396],{"id":395},"escapeforinlinescriptjson-string",[13,397,398],{},"escapeForInlineScript(json) → string",[16,400,401,402,405,406,409,410,409,413,416,417,420,421,240],{},"Takes a JSON string and escapes the characters that would let a\nform value break out of an inline ",[13,403,404],{},"\u003Cscript>"," tag: ",[13,407,408],{},"\u003C",", ",[13,411,412],{},">",[13,414,415],{},"&",",\nU+2028, U+2029. Pair with ",[13,418,419],{},"renderAttaformState"," when hand-rolling\nSSR; Nuxt handles it for you via ",[13,422,423],{},"devalue",[20,425,427],{"className":22,"code":426,"language":24,"meta":25,"style":25},"const payload = escapeForInlineScript(JSON.stringify(renderAttaformState(app)))\n\u002F\u002F `\u003Cscript>window.__STATE__ = ${payload}\u003C\u002Fscript>` is safe to inline.\n",[13,428,429,461],{"__ignoreMap":25},[29,430,431,434,438,441,444,446,449,451,454,456,458],{"class":31,"line":32},[29,432,433],{"class":35},"const",[29,435,437],{"class":436},"sj4cs"," payload",[29,439,440],{"class":35}," =",[29,442,443],{"class":137}," escapeForInlineScript",[29,445,147],{"class":39},[29,447,448],{"class":436},"JSON",[29,450,240],{"class":39},[29,452,453],{"class":137},"stringify",[29,455,147],{"class":39},[29,457,419],{"class":137},[29,459,460],{"class":39},"(app)))\n",[29,462,463],{"class":31,"line":43},[29,464,465],{"class":55},"\u002F\u002F `\u003Cscript>window.__STATE__ = ${payload}\u003C\u002Fscript>` is safe to inline.\n",[119,467,469],{"id":468},"vregister",[13,470,471],{},"vRegister",[16,473,474,475,478,479,481],{},"The ",[13,476,477],{},"v-register"," directive. Registered automatically by\n",[13,480,150],{},"; exported for consumers installing directives\nmanually.",[16,483,484],{},"Bind to a native input, select, textarea, checkbox, or radio:",[20,486,490],{"className":487,"code":488,"language":489,"meta":25,"style":25},"language-vue shiki shiki-themes github-light github-dark","\u003Cinput v-register=\"form.register('email')\" \u002F>\n\u003Cselect v-register=\"form.register('country')\">...\u003C\u002Fselect>\n","vue",[13,491,492,528],{"__ignoreMap":25},[29,493,494,496,500,503,506,509,512,515,517,520,523,525],{"class":31,"line":32},[29,495,408],{"class":39},[29,497,499],{"class":498},"s9eBZ","input",[29,501,502],{"class":137}," v-register",[29,504,505],{"class":39},"=",[29,507,508],{"class":116},"\"",[29,510,511],{"class":39},"form.",[29,513,514],{"class":137},"register",[29,516,147],{"class":39},[29,518,519],{"class":116},"'email'",[29,521,522],{"class":39},")",[29,524,508],{"class":116},[29,526,527],{"class":39}," \u002F>\n",[29,529,530,532,535,537,539,541,543,545,547,550,552,554,557,559],{"class":31,"line":43},[29,531,408],{"class":39},[29,533,534],{"class":498},"select",[29,536,502],{"class":137},[29,538,505],{"class":39},[29,540,508],{"class":116},[29,542,511],{"class":39},[29,544,514],{"class":137},[29,546,147],{"class":39},[29,548,549],{"class":116},"'country'",[29,551,522],{"class":39},[29,553,508],{"class":116},[29,555,556],{"class":39},">...\u003C\u002F",[29,558,534],{"class":498},[29,560,561],{"class":39},">\n",[16,563,564,565,568,569,572,573,575,576,580,581,584],{},"Or to a custom component whose root is ",[305,566,567],{},"not"," a native input —\n",[13,570,571],{},"useRegister()"," in the child reads the parent's binding so you can\nre-bind ",[13,574,477],{}," onto an inner native element. When the\nwrapper's root ",[577,578,579],"em",{},"is"," the input itself, Vue's attribute fallthrough\nhandles it and ",[13,582,583],{},"useRegister"," is unnecessary.",[20,586,588],{"className":487,"code":587,"language":489,"meta":25,"style":25},"\u003C!-- Parent -->\n\u003CMyField label=\"Email\" v-register=\"form.register('email')\" \u002F>\n\n\u003C!-- MyField.vue (root is \u003Clabel>, not \u003Cinput>) -->\n\u003Cscript setup lang=\"ts\">\n  import { useRegister } from 'attaform'\n  defineProps\u003C{ label: string }>()\n  const register = useRegister()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Clabel class=\"field\">\n    \u003Cspan>{{ label }}\u003C\u002Fspan>\n    \u003Cinput v-register=\"register\" \u002F>\n  \u003C\u002Flabel>\n\u003C\u002Ftemplate>\n",[13,589,590,595,630,636,641,661,673,694,710,719,723,732,749,764,780,790],{"__ignoreMap":25},[29,591,592],{"class":31,"line":32},[29,593,594],{"class":55},"\u003C!-- Parent -->\n",[29,596,597,599,602,605,607,610,612,614,616,618,620,622,624,626,628],{"class":31,"line":43},[29,598,408],{"class":39},[29,600,601],{"class":498},"MyField",[29,603,604],{"class":137}," label",[29,606,505],{"class":39},[29,608,609],{"class":116},"\"Email\"",[29,611,502],{"class":137},[29,613,505],{"class":39},[29,615,508],{"class":116},[29,617,511],{"class":39},[29,619,514],{"class":137},[29,621,147],{"class":39},[29,623,519],{"class":116},[29,625,522],{"class":39},[29,627,508],{"class":116},[29,629,527],{"class":39},[29,631,632],{"class":31,"line":49},[29,633,635],{"emptyLinePlaceholder":634},true,"\n",[29,637,638],{"class":31,"line":59},[29,639,640],{"class":55},"\u003C!-- MyField.vue (root is \u003Clabel>, not \u003Cinput>) -->\n",[29,642,643,645,648,651,654,656,659],{"class":31,"line":65},[29,644,408],{"class":39},[29,646,647],{"class":498},"script",[29,649,650],{"class":137}," setup",[29,652,653],{"class":137}," lang",[29,655,505],{"class":39},[29,657,658],{"class":116},"\"ts\"",[29,660,561],{"class":39},[29,662,663,666,669,671],{"class":31,"line":71},[29,664,665],{"class":35},"  import",[29,667,668],{"class":39}," { useRegister } ",[29,670,113],{"class":35},[29,672,117],{"class":116},[29,674,675,678,681,685,688,691],{"class":31,"line":77},[29,676,677],{"class":137},"  defineProps",[29,679,680],{"class":39},"\u003C{ ",[29,682,684],{"class":683},"s4XuR","label",[29,686,687],{"class":35},":",[29,689,690],{"class":436}," string",[29,692,693],{"class":39}," }>()\n",[29,695,696,699,702,704,707],{"class":31,"line":83},[29,697,698],{"class":35},"  const",[29,700,701],{"class":436}," register",[29,703,440],{"class":35},[29,705,706],{"class":137}," useRegister",[29,708,709],{"class":39},"()\n",[29,711,712,715,717],{"class":31,"line":89},[29,713,714],{"class":39},"\u003C\u002F",[29,716,647],{"class":498},[29,718,561],{"class":39},[29,720,721],{"class":31,"line":95},[29,722,635],{"emptyLinePlaceholder":634},[29,724,725,727,730],{"class":31,"line":101},[29,726,408],{"class":39},[29,728,729],{"class":498},"template",[29,731,561],{"class":39},[29,733,734,737,739,742,744,747],{"class":31,"line":107},[29,735,736],{"class":39},"  \u003C",[29,738,684],{"class":498},[29,740,741],{"class":137}," class",[29,743,505],{"class":39},[29,745,746],{"class":116},"\"field\"",[29,748,561],{"class":39},[29,750,752,755,757,760,762],{"class":31,"line":751},13,[29,753,754],{"class":39},"    \u003C",[29,756,29],{"class":498},[29,758,759],{"class":39},">{{ label }}\u003C\u002F",[29,761,29],{"class":498},[29,763,561],{"class":39},[29,765,767,769,771,773,775,778],{"class":31,"line":766},14,[29,768,754],{"class":39},[29,770,499],{"class":498},[29,772,502],{"class":137},[29,774,505],{"class":39},[29,776,777],{"class":116},"\"register\"",[29,779,527],{"class":39},[29,781,783,786,788],{"class":31,"line":782},15,[29,784,785],{"class":39},"  \u003C\u002F",[29,787,684],{"class":498},[29,789,561],{"class":39},[29,791,793,795,797],{"class":31,"line":792},16,[29,794,714],{"class":39},[29,796,729],{"class":498},[29,798,561],{"class":39},[800,801,803],"h3",{"id":802},"modifiers","Modifiers",[16,805,806,808,809,812,813,816],{},[13,807,477],{}," mirrors Vue's ",[13,810,811],{},"v-model"," modifier semantics, scoped per\nelement type. Modifier names are typed — a typo (",[13,814,815],{},"v-register.lazi",")\nis a TypeScript error, not a silent runtime no-op.",[169,818,819,832],{},[172,820,821],{},[175,822,823,826,829],{},[178,824,825],{},"Element",[178,827,828],{},"Modifier",[178,830,831],{},"What it does",[188,833,834,862,890,918,944],{},[175,835,836,847,852],{},[193,837,838,409,841,409,844],{},[13,839,840],{},"\u003Cinput type=\"text\">",[13,842,843],{},"\u003Cinput type=\"number\">",[13,845,846],{},"\u003Ctextarea>",[193,848,849],{},[13,850,851],{},".lazy",[193,853,854,855,858,859,861],{},"Write on ",[13,856,857],{},"change"," (blur) instead of ",[13,860,499],{},". Disables IME composition handlers — composition events don't gate writes.",[175,863,864,872,877],{},[193,865,866,409,868,409,870],{},[13,867,840],{},[13,869,843],{},[13,871,846],{},[193,873,874],{},[13,875,876],{},".trim",[193,878,879,880,883,884,886,887,889],{},"Strip leading\u002Ftrailing whitespace ",[305,881,882],{},"on blur",". While the user is typing, the model holds the raw input (whitespace included); on ",[13,885,857],{}," the value is trimmed once and written to both model and DOM. Combine with ",[13,888,851],{}," to skip the mid-typing writes entirely.",[175,891,892,900,905],{},[193,893,894,409,896,409,898],{},[13,895,840],{},[13,897,843],{},[13,899,846],{},[193,901,902],{},[13,903,904],{},".number",[193,906,907,908,911,912,914,915,917],{},"Cast via ",[13,909,910],{},"parseFloat"," before writing; values that can't be parsed pass through unchanged. Auto-applied for ",[13,913,843],{}," — explicit ",[13,916,904],{}," is redundant.",[175,919,920,925,929],{},[193,921,922],{},[13,923,924],{},"\u003Cselect>",[193,926,927],{},[13,928,904],{},[193,930,931,932,935,936,938,939,941,942,240],{},"Cast each selected option's ",[13,933,934],{},"value"," via ",[13,937,910],{}," before writing. Mirrors Vue's ",[13,940,811],{}," on ",[13,943,924],{},[175,945,946,954,959],{},[193,947,948,409,951],{},[13,949,950],{},"\u003Cinput type=\"checkbox\">",[13,952,953],{},"\u003Cinput type=\"radio\">",[193,955,956],{},[577,957,958],{},"(none)",[193,960,961],{},"No modifiers — Vue's v-model doesn't define any here either.",[16,963,964,965,240],{},"Combine freely on text\u002Ftextarea: ",[13,966,967],{},"\u003Cinput v-register.lazy.number=\"form.register('age')\" \u002F>",[16,969,970,971,973,974,977,978,981,982,985],{},"When the slim-primitive gate rejects a write produced by a modifier\ncast (e.g. ",[13,972,904],{}," × ",[13,975,976],{},"'abc'"," against a ",[13,979,980],{},"z.number()"," slot — the\nnon-parseable string passes through ",[13,983,984],{},"looseToNumber"," unchanged), the\ndirective's listener completes silently and the DOM keeps the user's\ninput. The form state stays at its previous value. Field-level\nvalidation will surface a refinement error on the next render.",[800,987,989,990],{"id":988},"custom-assigners-updateregistervalue","Custom assigners — ",[13,991,992],{},"@update:registerValue",[16,994,995,996,999,1000,1003],{},"Replaces the directive's default \"DOM event → extract value →\n",[13,997,998],{},"rv.setValueWithInternalPath(value)","\" bridge. The handler receives\nthe post-extraction value plus the ",[13,1001,1002],{},"RegisterValue"," and decides what\n(if anything) reaches form state.",[20,1005,1007],{"className":487,"code":1006,"language":489,"meta":25,"style":25},"\u003Cscript setup lang=\"ts\">\n  import type { RegisterValue } from 'attaform'\n\n  const form = useForm({ schema, defaultValues: { username: '' } })\n\n  function uppercaseAssigner(value: unknown, rv: RegisterValue): void {\n    rv.setValueWithInternalPath(String(value ?? '').toUpperCase())\n  }\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cinput v-register=\"form.register('username')\" @update:registerValue=\"uppercaseAssigner\" \u002F>\n\u003C\u002Ftemplate>\n",[13,1008,1009,1025,1039,1043,1064,1068,1104,1135,1140,1148,1152,1160,1183],{"__ignoreMap":25},[29,1010,1011,1013,1015,1017,1019,1021,1023],{"class":31,"line":32},[29,1012,408],{"class":39},[29,1014,647],{"class":498},[29,1016,650],{"class":137},[29,1018,653],{"class":137},[29,1020,505],{"class":39},[29,1022,658],{"class":116},[29,1024,561],{"class":39},[29,1026,1027,1029,1032,1035,1037],{"class":31,"line":43},[29,1028,665],{"class":35},[29,1030,1031],{"class":35}," type",[29,1033,1034],{"class":39}," { RegisterValue } ",[29,1036,113],{"class":35},[29,1038,117],{"class":116},[29,1040,1041],{"class":31,"line":49},[29,1042,635],{"emptyLinePlaceholder":634},[29,1044,1045,1047,1050,1052,1055,1058,1061],{"class":31,"line":59},[29,1046,698],{"class":35},[29,1048,1049],{"class":436}," form",[29,1051,440],{"class":35},[29,1053,1054],{"class":137}," useForm",[29,1056,1057],{"class":39},"({ schema, defaultValues: { username: ",[29,1059,1060],{"class":116},"''",[29,1062,1063],{"class":39}," } })\n",[29,1065,1066],{"class":31,"line":65},[29,1067,635],{"emptyLinePlaceholder":634},[29,1069,1070,1073,1076,1078,1080,1082,1085,1087,1090,1092,1095,1097,1099,1102],{"class":31,"line":71},[29,1071,1072],{"class":35},"  function",[29,1074,1075],{"class":137}," uppercaseAssigner",[29,1077,147],{"class":39},[29,1079,934],{"class":683},[29,1081,687],{"class":35},[29,1083,1084],{"class":436}," unknown",[29,1086,409],{"class":39},[29,1088,1089],{"class":683},"rv",[29,1091,687],{"class":35},[29,1093,1094],{"class":137}," RegisterValue",[29,1096,522],{"class":39},[29,1098,687],{"class":35},[29,1100,1101],{"class":436}," void",[29,1103,40],{"class":39},[29,1105,1106,1109,1112,1114,1117,1120,1123,1126,1129,1132],{"class":31,"line":77},[29,1107,1108],{"class":39},"    rv.",[29,1110,1111],{"class":137},"setValueWithInternalPath",[29,1113,147],{"class":39},[29,1115,1116],{"class":137},"String",[29,1118,1119],{"class":39},"(value ",[29,1121,1122],{"class":35},"??",[29,1124,1125],{"class":116}," ''",[29,1127,1128],{"class":39},").",[29,1130,1131],{"class":137},"toUpperCase",[29,1133,1134],{"class":39},"())\n",[29,1136,1137],{"class":31,"line":83},[29,1138,1139],{"class":39},"  }\n",[29,1141,1142,1144,1146],{"class":31,"line":89},[29,1143,714],{"class":39},[29,1145,647],{"class":498},[29,1147,561],{"class":39},[29,1149,1150],{"class":31,"line":95},[29,1151,635],{"emptyLinePlaceholder":634},[29,1153,1154,1156,1158],{"class":31,"line":101},[29,1155,408],{"class":39},[29,1157,729],{"class":498},[29,1159,561],{"class":39},[29,1161,1162,1164,1166,1168,1170,1173,1176,1178,1181],{"class":31,"line":107},[29,1163,736],{"class":39},[29,1165,499],{"class":498},[29,1167,502],{"class":137},[29,1169,505],{"class":39},[29,1171,1172],{"class":116},"\"form.register('username')\"",[29,1174,1175],{"class":137}," @update:registerValue",[29,1177,505],{"class":39},[29,1179,1180],{"class":116},"\"uppercaseAssigner\"",[29,1182,527],{"class":39},[29,1184,1185,1187,1189],{"class":31,"line":751},[29,1186,714],{"class":39},[29,1188,729],{"class":498},[29,1190,561],{"class":39},[16,1192,1193,1194,1196,1197,1199,1200,1202],{},"Modifier extraction runs first — ",[13,1195,904],{}," gives you a number,\n",[13,1198,876],{}," the trimmed string, ",[13,1201,950],{}," the boolean.",[16,1204,1205],{},"Four patterns:",[310,1207,1208,1217,1223,1229],{},[313,1209,1210,1213,1214,240],{},[305,1211,1212],{},"Transform"," — call ",[13,1215,1216],{},"rv.setValueWithInternalPath(normalised)",[313,1218,1219,1222],{},[305,1220,1221],{},"Reject"," — skip the call; the keystroke drops entirely (distinct\nfrom validation errors, which accept then flag).",[313,1224,1225,1228],{},[305,1226,1227],{},"Side-effect + default"," — log \u002F analytics, then call through.",[313,1230,1231,1234],{},[305,1232,1233],{},"Redirect"," — write to a different field or external store.",[16,1236,1237,1238,1241,1242,1244,1245,213,1248,1251,1252,409,1255,409,1257,1259,1260,1262,1263,1266],{},"Handler signature:\n",[13,1239,1240],{},"(value: unknown, registerValue: RegisterValue) => boolean | undefined",".\nReturn ",[13,1243,216],{}," to flag a rejected write; ",[13,1246,1247],{},"undefined",[13,1249,1250],{},"void"," is\nsuccess. Use only on ",[13,1253,1254],{},"\u003Cinput>",[13,1256,924],{},[13,1258,846],{}," roots — for\nnon-form roots see ",[13,1261,571],{}," or ",[13,1264,1265],{},"assignKey"," (Web Components).",[16,1268,1269,1270,1272,1273,1275,1276,1279],{},"The handler can be a top-level function outside ",[13,1271,363],{}," since\n",[13,1274,1089],{}," is supplied by the directive. Multiple listeners on the same\nelement receive ",[13,1277,1278],{},"(value, rv)"," in registration order.",[800,1281,1283,1284],{"id":1282},"transforms-registerpath-transforms","Transforms — ",[13,1285,1286],{},"register(path, { transforms: [...] })",[16,1288,1289,1290,1292],{},"A pipeline of pure functions for normalizing user input. Composed\nleft-to-right; runs inside the directive's assigner across every\n",[13,1291,477],{}," element variant.",[20,1294,1296],{"className":22,"code":1295,"language":24,"meta":25,"style":25},"import type { RegisterTransform } from 'attaform'\n\nconst trim: RegisterTransform = (v) => (typeof v === 'string' ? v.trim() : v)\nconst lowercase: RegisterTransform = (v) => (typeof v === 'string' ? v.toLowerCase() : v)\n\nconst rv = form.register('email', { transforms: [trim, lowercase] })\n",[13,1297,1298,1311,1315,1372,1416,1420],{"__ignoreMap":25},[29,1299,1300,1302,1304,1307,1309],{"class":31,"line":32},[29,1301,36],{"class":35},[29,1303,1031],{"class":35},[29,1305,1306],{"class":39}," { RegisterTransform } ",[29,1308,113],{"class":35},[29,1310,117],{"class":116},[29,1312,1313],{"class":31,"line":43},[29,1314,635],{"emptyLinePlaceholder":634},[29,1316,1317,1319,1322,1324,1327,1329,1332,1335,1338,1341,1343,1346,1349,1352,1355,1358,1361,1364,1367,1369],{"class":31,"line":49},[29,1318,433],{"class":35},[29,1320,1321],{"class":137}," trim",[29,1323,687],{"class":35},[29,1325,1326],{"class":137}," RegisterTransform",[29,1328,440],{"class":35},[29,1330,1331],{"class":39}," (",[29,1333,1334],{"class":683},"v",[29,1336,1337],{"class":39},") ",[29,1339,1340],{"class":35},"=>",[29,1342,1331],{"class":39},[29,1344,1345],{"class":35},"typeof",[29,1347,1348],{"class":39}," v ",[29,1350,1351],{"class":35},"===",[29,1353,1354],{"class":116}," 'string'",[29,1356,1357],{"class":35}," ?",[29,1359,1360],{"class":39}," v.",[29,1362,1363],{"class":137},"trim",[29,1365,1366],{"class":39},"() ",[29,1368,687],{"class":35},[29,1370,1371],{"class":39}," v)\n",[29,1373,1374,1376,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1399,1401,1403,1405,1407,1410,1412,1414],{"class":31,"line":59},[29,1375,433],{"class":35},[29,1377,1378],{"class":137}," lowercase",[29,1380,687],{"class":35},[29,1382,1326],{"class":137},[29,1384,440],{"class":35},[29,1386,1331],{"class":39},[29,1388,1334],{"class":683},[29,1390,1337],{"class":39},[29,1392,1340],{"class":35},[29,1394,1331],{"class":39},[29,1396,1345],{"class":35},[29,1398,1348],{"class":39},[29,1400,1351],{"class":35},[29,1402,1354],{"class":116},[29,1404,1357],{"class":35},[29,1406,1360],{"class":39},[29,1408,1409],{"class":137},"toLowerCase",[29,1411,1366],{"class":39},[29,1413,687],{"class":35},[29,1415,1371],{"class":39},[29,1417,1418],{"class":31,"line":65},[29,1419,635],{"emptyLinePlaceholder":634},[29,1421,1422,1424,1427,1429,1432,1434,1436,1438],{"class":31,"line":71},[29,1423,433],{"class":35},[29,1425,1426],{"class":436}," rv",[29,1428,440],{"class":35},[29,1430,1431],{"class":39}," form.",[29,1433,514],{"class":137},[29,1435,147],{"class":39},[29,1437,519],{"class":116},[29,1439,1440],{"class":39},", { transforms: [trim, lowercase] })\n",[20,1442,1444],{"className":487,"code":1443,"language":489,"meta":25,"style":25},"\u003Cinput v-register=\"rv\" \u002F>\n\u003C!-- type \"  Foo@BAR.com  \", form receives \"foo@bar.com\" -->\n",[13,1445,1446,1464],{"__ignoreMap":25},[29,1447,1448,1450,1452,1454,1456,1458,1460,1462],{"class":31,"line":32},[29,1449,408],{"class":39},[29,1451,499],{"class":498},[29,1453,502],{"class":137},[29,1455,505],{"class":39},[29,1457,508],{"class":116},[29,1459,1089],{"class":39},[29,1461,508],{"class":116},[29,1463,527],{"class":39},[29,1465,1466],{"class":31,"line":43},[29,1467,1468],{"class":55},"\u003C!-- type \"  Foo@BAR.com  \", form receives \"foo@bar.com\" -->\n",[16,1470,1471,1474,1475,1478,1479,1482],{},[13,1472,1473],{},"RegisterTransform"," is ",[13,1476,1477],{},"(value: unknown) => unknown"," — generic-erased\nso a personal library of transforms plugs into any ",[13,1480,1481],{},"register()"," slot.\nWrite defensive bodies that no-op on type mismatch.",[16,1484,1485,1488],{},[305,1486,1487],{},"Pipeline ordering",": transforms run after modifier extraction,\nbefore the assigner writes to form state.",[20,1490,1495],{"className":1491,"code":1493,"language":1494},[1492],"language-text","DOM event → modifier cast → transforms[0] → … → transforms[n] → assigner\n","text",[13,1496,1493],{"__ignoreMap":25},[16,1498,1499,1500,240],{},"Combine freely: ",[13,1501,1502],{},"\u003Cinput v-register.lazy.number=\"register('age', { transforms: [clamp(0, 99)] })\">",[16,1504,1505,1508,1509,409,1512,1515,1516,1519,1520,240],{},[305,1506,1507],{},"Scope."," Transforms apply to user-input via the directive only —\nNOT to ",[13,1510,1511],{},"setValue",[13,1513,1514],{},"reset",", hydration, SSR replay, or ",[13,1517,1518],{},"markBlank()",".\nFor programmatic writes, compose transforms at the call site:\n",[13,1521,1522],{},"form.setValue('email', lowercase(trim(rawValue)))",[16,1524,1525,1530],{},[305,1526,1527,1528,240],{},"With ",[13,1529,992],{}," The override receives the\npost-transform value as its first arg. If you want the raw\nextracted value, don't register transforms.",[16,1532,1533,1536,1537,1539,1540,1543,1544,1547,1548,1551],{},[305,1534,1535],{},"Failure mode."," Must be sync. On throw OR Promise return: the\npipeline aborts, form state is unchanged, the assigner returns\n",[13,1538,216],{},", the DOM reverts via the ",[13,1541,1542],{},":value"," binding, and a\n",[13,1545,1546],{},"console.error"," is logged. Dev mode includes the path, transform\nindex, transform ",[13,1549,1550],{},".name",", and remediation hint; prod logs a fixed\nstring only. A throw on one keystroke doesn't poison subsequent\nkeystrokes or other fields.",[16,1553,1554,1560],{},[305,1555,1556,1557,1559],{},"Transforms cover normalization. ",[13,1558,992],{}," covers\ncontrol"," (rejection-with-side-effect, redirection, custom DOM\nmutation).",[119,1562,1564],{"id":1563},"canonicalizepathinput-segments-key",[13,1565,1566],{},"canonicalizePath(input) → { segments, key }",[16,1568,1569,1570,1573,1574,1577],{},"Normalise a dotted-string or array path into a structured ",[13,1571,1572],{},"Path","\nplus a stable ",[13,1575,1576],{},"PathKey",". Use when building custom adapters.",[119,1579,1581],{"id":1580},"parseapierrorspayload-options-parseapierrorsresult",[13,1582,1583],{},"parseApiErrors(payload, options) → ParseApiErrorsResult",[16,1585,1586,1587,409,1590,1593,1594,1597,1598,1601,1602,1605],{},"Pure transformation: takes a server response in the common shapes\n(",[13,1588,1589],{},"{ error: { details } }",[13,1591,1592],{},"{ details }",", or a raw ",[13,1595,1596],{},"{ path: entry }","\nrecord) and returns ",[13,1599,1600],{},"{ ok, errors, rejected? }",". Pair with\n",[13,1603,1604],{},"form.setFieldErrors(result.errors)"," to apply.",[16,1607,1608,1611],{},[305,1609,1610],{},"Wire format."," Two entry shapes:",[310,1613,1614,1630],{},[313,1615,1616,1619,1620,1623,1624,1626,1627,240],{},[305,1617,1618],{},"Structured"," — ",[13,1621,1622],{},"{ message: string, code: string }",". ",[13,1625,13],{},"\nforwards onto the produced ",[13,1628,1629],{},"ValidationError",[313,1631,1632,1635,1636,1623,1639,1642,1643,240],{},[305,1633,1634],{},"Bare string"," — synthesized into\n",[13,1637,1638],{},"{ message, code: defaultCode }",[13,1640,1641],{},"defaultCode"," defaults to\n",[13,1644,1645],{},"'api:unknown'",[16,1647,1648],{},"A field's value may be a single entry, an array, or a mix.",[20,1650,1654],{"className":1651,"code":1652,"language":1653,"meta":25,"style":25},"language-jsonc shiki shiki-themes github-light github-dark","{\n  \"error\": {\n    \"details\": {\n      \"email\": { \"message\": \"taken\", \"code\": \"api:duplicate-email\" },\n      \"password\": [{ \"message\": \"too short\", \"code\": \"api:min-length\" }, \"must include a number\"],\n      \"username\": [\"Username is reserved.\"],\n      \"items.0.name\": { \"message\": \"blank\", \"code\": \"api:blank\" },\n      \"\": { \"message\": \"form-level failure\", \"code\": \"api:form\" },\n    },\n  },\n}\n","jsonc",[13,1655,1656,1661,1666,1671,1676,1681,1686,1691,1696,1701,1706],{"__ignoreMap":25},[29,1657,1658],{"class":31,"line":32},[29,1659,1660],{},"{\n",[29,1662,1663],{"class":31,"line":43},[29,1664,1665],{},"  \"error\": {\n",[29,1667,1668],{"class":31,"line":49},[29,1669,1670],{},"    \"details\": {\n",[29,1672,1673],{"class":31,"line":59},[29,1674,1675],{},"      \"email\": { \"message\": \"taken\", \"code\": \"api:duplicate-email\" },\n",[29,1677,1678],{"class":31,"line":65},[29,1679,1680],{},"      \"password\": [{ \"message\": \"too short\", \"code\": \"api:min-length\" }, \"must include a number\"],\n",[29,1682,1683],{"class":31,"line":71},[29,1684,1685],{},"      \"username\": [\"Username is reserved.\"],\n",[29,1687,1688],{"class":31,"line":77},[29,1689,1690],{},"      \"items.0.name\": { \"message\": \"blank\", \"code\": \"api:blank\" },\n",[29,1692,1693],{"class":31,"line":83},[29,1694,1695],{},"      \"\": { \"message\": \"form-level failure\", \"code\": \"api:form\" },\n",[29,1697,1698],{"class":31,"line":89},[29,1699,1700],{},"    },\n",[29,1702,1703],{"class":31,"line":95},[29,1704,1705],{},"  },\n",[29,1707,1708],{"class":31,"line":101},[29,1709,1710],{},"}\n",[20,1712,1714],{"className":22,"code":1713,"language":24,"meta":25,"style":25},"const result = parseApiErrors(response, {\n  formKey: form.key,\n  \u002F\u002F Stamp every bare-string entry with a custom code (default 'api:unknown'):\n  defaultCode: 'api:server-validation',\n  \u002F\u002F Optional caps for untrusted gateway-passthrough payloads:\n  maxEntries: 200, \u002F\u002F default 1000\n  maxPathDepth: 8, \u002F\u002F default 32\n})\nif (result.ok) form.setFieldErrors(result.errors)\nelse console.warn('Bad payload:', result.rejected)\n",[13,1715,1716,1731,1736,1741,1752,1757,1770,1783,1788,1802],{"__ignoreMap":25},[29,1717,1718,1720,1723,1725,1728],{"class":31,"line":32},[29,1719,433],{"class":35},[29,1721,1722],{"class":436}," result",[29,1724,440],{"class":35},[29,1726,1727],{"class":137}," parseApiErrors",[29,1729,1730],{"class":39},"(response, {\n",[29,1732,1733],{"class":31,"line":43},[29,1734,1735],{"class":39},"  formKey: form.key,\n",[29,1737,1738],{"class":31,"line":49},[29,1739,1740],{"class":55},"  \u002F\u002F Stamp every bare-string entry with a custom code (default 'api:unknown'):\n",[29,1742,1743,1746,1749],{"class":31,"line":59},[29,1744,1745],{"class":39},"  defaultCode: ",[29,1747,1748],{"class":116},"'api:server-validation'",[29,1750,1751],{"class":39},",\n",[29,1753,1754],{"class":31,"line":65},[29,1755,1756],{"class":55},"  \u002F\u002F Optional caps for untrusted gateway-passthrough payloads:\n",[29,1758,1759,1762,1765,1767],{"class":31,"line":71},[29,1760,1761],{"class":39},"  maxEntries: ",[29,1763,1764],{"class":436},"200",[29,1766,409],{"class":39},[29,1768,1769],{"class":55},"\u002F\u002F default 1000\n",[29,1771,1772,1775,1778,1780],{"class":31,"line":77},[29,1773,1774],{"class":39},"  maxPathDepth: ",[29,1776,1777],{"class":436},"8",[29,1779,409],{"class":39},[29,1781,1782],{"class":55},"\u002F\u002F default 32\n",[29,1784,1785],{"class":31,"line":83},[29,1786,1787],{"class":39},"})\n",[29,1789,1790,1793,1796,1799],{"class":31,"line":89},[29,1791,1792],{"class":35},"if",[29,1794,1795],{"class":39}," (result.ok) form.",[29,1797,1798],{"class":137},"setFieldErrors",[29,1800,1801],{"class":39},"(result.errors)\n",[29,1803,1804,1807,1810,1813,1815,1818],{"class":31,"line":95},[29,1805,1806],{"class":35},"else",[29,1808,1809],{"class":39}," console.",[29,1811,1812],{"class":137},"warn",[29,1814,147],{"class":39},[29,1816,1817],{"class":116},"'Bad payload:'",[29,1819,1820],{"class":39},", result.rejected)\n",[16,1822,1823,1824,1827,1828,1830,1831,1834,1835,1838,1839,1842],{},"Half-structured entries (",[13,1825,1826],{},"{ message }"," with no ",[13,1829,13],{},", or ",[13,1832,1833],{},"{ code }","\nwith no ",[13,1836,1837],{},"message",") are still rejected — those signal a server bug\n(the wire shape was ",[577,1840,1841],{},"trying"," to be structured) and shouldn't be\nsilently coerced.",[16,1844,1845,1846,1850],{},"See ",[236,1847,1849],{"href":1848},"\u002Fdocs\u002Frecipes\u002Fserver-errors","server-errors recipe"," for the full\npattern.",[119,1852,1854],{"id":1853},"error-codes","Error codes",[16,1856,1857,1858,1860,1861,1864,1865,687],{},"Every ",[13,1859,1629],{}," carries a required ",[13,1862,1863],{},"code: string"," for stable\nmachine identification. Convention is ",[13,1866,1867],{},"\u003Cscope>:\u003Ckebab-case>",[169,1869,1870,1883],{},[172,1871,1872],{},[175,1873,1874,1877,1880],{},[178,1875,1876],{},"Scope",[178,1878,1879],{},"Owner",[178,1881,1882],{},"Examples",[188,1884,1885,1906,1931],{},[175,1886,1887,1892,1895],{},[193,1888,1889],{},[13,1890,1891],{},"atta:",[193,1893,1894],{},"Library core",[193,1896,1897,409,1900,409,1903],{},[13,1898,1899],{},"atta:no-value-supplied",[13,1901,1902],{},"atta:adapter-threw",[13,1904,1905],{},"atta:path-not-found",[175,1907,1908,1913,1916],{},[193,1909,1910],{},[13,1911,1912],{},"zod:",[193,1914,1915],{},"Zod adapter",[193,1917,1918,409,1921,409,1924,1927,1928,522],{},[13,1919,1920],{},"zod:too_small",[13,1922,1923],{},"zod:invalid_format",[13,1925,1926],{},"zod:custom"," (forwarded from ",[13,1929,1930],{},"issue.code",[175,1932,1933,1936,1939],{},[193,1934,1935],{},"consumer",[193,1937,1938],{},"Your app \u002F backend",[193,1940,1941,409,1944,409,1947],{},[13,1942,1943],{},"api:duplicate-email",[13,1945,1946],{},"auth:expired-token",[13,1948,1949],{},"myapp:account-locked",[16,1951,1952,1953,1956],{},"The library exports ",[13,1954,1955],{},"AttaformErrorCode"," for branching on internal codes:",[20,1958,1960],{"className":22,"code":1959,"language":24,"meta":25,"style":25},"import { AttaformErrorCode } from 'attaform'\n\u002F\u002F or 'attaform\u002Fzod' \u002F 'attaform\u002Fzod-v3'\n\nif (error.code === AttaformErrorCode.NoValueSupplied) {\n  \u002F\u002F user opened the form and hasn't filled this field yet\n}\nif (error.code.startsWith('zod:')) {\n  \u002F\u002F schema-level validation failure\n}\n",[13,1961,1962,1973,1978,1982,1994,1999,2003,2021,2026],{"__ignoreMap":25},[29,1963,1964,1966,1969,1971],{"class":31,"line":32},[29,1965,36],{"class":35},[29,1967,1968],{"class":39}," { AttaformErrorCode } ",[29,1970,113],{"class":35},[29,1972,117],{"class":116},[29,1974,1975],{"class":31,"line":43},[29,1976,1977],{"class":55},"\u002F\u002F or 'attaform\u002Fzod' \u002F 'attaform\u002Fzod-v3'\n",[29,1979,1980],{"class":31,"line":49},[29,1981,635],{"emptyLinePlaceholder":634},[29,1983,1984,1986,1989,1991],{"class":31,"line":59},[29,1985,1792],{"class":35},[29,1987,1988],{"class":39}," (error.code ",[29,1990,1351],{"class":35},[29,1992,1993],{"class":39}," AttaformErrorCode.NoValueSupplied) {\n",[29,1995,1996],{"class":31,"line":65},[29,1997,1998],{"class":55},"  \u002F\u002F user opened the form and hasn't filled this field yet\n",[29,2000,2001],{"class":31,"line":71},[29,2002,1710],{"class":39},[29,2004,2005,2007,2010,2013,2015,2018],{"class":31,"line":77},[29,2006,1792],{"class":35},[29,2008,2009],{"class":39}," (error.code.",[29,2011,2012],{"class":137},"startsWith",[29,2014,147],{"class":39},[29,2016,2017],{"class":116},"'zod:'",[29,2019,2020],{"class":39},")) {\n",[29,2022,2023],{"class":31,"line":83},[29,2024,2025],{"class":55},"  \u002F\u002F schema-level validation failure\n",[29,2027,2028],{"class":31,"line":89},[29,2029,1710],{"class":39},[16,2031,2032,2034],{},[13,2033,1912],{}," codes are computed inline (no enum) since Zod's code list\nevolves. String-match the prefix to handle \"any zod error\" generically,\nor check exact codes for fine-grained branching.",[16,2036,2037,2038,2041,2042,2044,2045,2048],{},"The library never invents consumer-side codes — they originate in your\nbackend payload (via ",[13,2039,2040],{},"parseApiErrors",") or in ",[13,2043,1798],{}," \u002F\n",[13,2046,2047],{},"addFieldErrors"," calls you make directly. Pick a prefix and stay\nconsistent across your app.",[119,2050,2052],{"id":2051},"unset",[13,2053,2051],{},[16,2055,2056,2057,2060,2061,2064,2065,409,2067,2064,2069,409,2072,2074,2075,409,2078,2064,2081,1128],{},"A brand-typed sentinel symbol used to mark a primitive leaf as\n",[305,2058,2059],{},"displayed-empty"," while storage holds the schema's slim default\n(",[13,2062,2063],{},"0"," for ",[13,2066,980],{},[13,2068,1060],{},[13,2070,2071],{},"z.string()",[13,2073,216],{}," for\n",[13,2076,2077],{},"z.boolean()",[13,2079,2080],{},"0n",[13,2082,2083],{},"z.bigint()",[20,2085,2087],{"className":22,"code":2086,"language":24,"meta":25,"style":25},"import { unset, useForm } from 'attaform\u002Fzod'\nimport { z } from 'zod'\n\nconst form = useForm({\n  schema: z.object({ income: z.number() }),\n  defaultValues: { income: unset }, \u002F\u002F input renders blank, storage = 0\n})\n\n\u002F\u002F Programmatic clear — same semantic as the user backspacing the field.\nform.setValue('income', unset)\n\n\u002F\u002F Restore-with-blanks via reset.\nform.reset({ income: unset })\n",[13,2088,2089,2101,2113,2117,2130,2147,2155,2159,2163,2168,2182,2186,2191],{"__ignoreMap":25},[29,2090,2091,2093,2096,2098],{"class":31,"line":32},[29,2092,36],{"class":35},[29,2094,2095],{"class":39}," { unset, useForm } ",[29,2097,113],{"class":35},[29,2099,2100],{"class":116}," 'attaform\u002Fzod'\n",[29,2102,2103,2105,2108,2110],{"class":31,"line":43},[29,2104,36],{"class":35},[29,2106,2107],{"class":39}," { z } ",[29,2109,113],{"class":35},[29,2111,2112],{"class":116}," 'zod'\n",[29,2114,2115],{"class":31,"line":49},[29,2116,635],{"emptyLinePlaceholder":634},[29,2118,2119,2121,2123,2125,2127],{"class":31,"line":59},[29,2120,433],{"class":35},[29,2122,1049],{"class":436},[29,2124,440],{"class":35},[29,2126,1054],{"class":137},[29,2128,2129],{"class":39},"({\n",[29,2131,2132,2135,2138,2141,2144],{"class":31,"line":65},[29,2133,2134],{"class":39},"  schema: z.",[29,2136,2137],{"class":137},"object",[29,2139,2140],{"class":39},"({ income: z.",[29,2142,2143],{"class":137},"number",[29,2145,2146],{"class":39},"() }),\n",[29,2148,2149,2152],{"class":31,"line":71},[29,2150,2151],{"class":39},"  defaultValues: { income: unset }, ",[29,2153,2154],{"class":55},"\u002F\u002F input renders blank, storage = 0\n",[29,2156,2157],{"class":31,"line":77},[29,2158,1787],{"class":39},[29,2160,2161],{"class":31,"line":83},[29,2162,635],{"emptyLinePlaceholder":634},[29,2164,2165],{"class":31,"line":89},[29,2166,2167],{"class":55},"\u002F\u002F Programmatic clear — same semantic as the user backspacing the field.\n",[29,2169,2170,2172,2174,2176,2179],{"class":31,"line":95},[29,2171,511],{"class":39},[29,2173,1511],{"class":137},[29,2175,147],{"class":39},[29,2177,2178],{"class":116},"'income'",[29,2180,2181],{"class":39},", unset)\n",[29,2183,2184],{"class":31,"line":101},[29,2185,635],{"emptyLinePlaceholder":634},[29,2187,2188],{"class":31,"line":107},[29,2189,2190],{"class":55},"\u002F\u002F Restore-with-blanks via reset.\n",[29,2192,2193,2195,2197],{"class":31,"line":751},[29,2194,511],{"class":39},[29,2196,1514],{"class":137},[29,2198,2199],{"class":39},"({ income: unset })\n",[16,2201,2202],{},"Three places accept the sentinel:",[310,2204,2205,2220,2232],{},[313,2206,2207,2212,2213,2215,2216,2219],{},[305,2208,2209],{},[13,2210,2211],{},"defaultValues"," — every primitive leaf can be ",[13,2214,2051],{},". The\nlibrary walks the payload at construction and adds the leaf's path\nto the form's ",[13,2217,2218],{},"blankPaths"," set.",[313,2221,2222,2227,2228,2231],{},[305,2223,2224],{},[13,2225,2226],{},"setValue(path, unset)"," — translated at the API boundary;\nstorage gets the slim default with ",[13,2229,2230],{},"blank: true"," meta.",[313,2233,2234,2239],{},[305,2235,2236],{},[13,2237,2238],{},"reset({ … })"," — same translation; the post-reset state\nbecomes the new dirty=false baseline.",[16,2241,2242,2245,2246,2248,2249,2252,2253,2255,2256,2259,2260,2262],{},[305,2243,2244],{},"Auto-mark on construction."," Every primitive leaf the consumer\ndidn't supply in ",[13,2247,2211],{}," is auto-marked ",[13,2250,2251],{},"blank",". To opt a\nleaf out, supply a non-",[13,2254,2051],{}," value (",[13,2257,2258],{},"defaultValues: { email: '' }",").\nAuto-mark recurses through nested objects, NOT arrays. Hydration\n(persisted draft, SSR payload) overrides — the hydrated ",[13,2261,2218],{},"\nlist is authoritative.",[16,2264,2265,2268,2269,2272,2273,2044,2276,2279],{},[305,2266,2267],{},"Submit \u002F validate honor the sentinel."," A blank path bound to a\nrequired schema raises ",[13,2270,2271],{},"\"No value supplied\""," during ",[13,2274,2275],{},"handleSubmit",[13,2277,2278],{},"validate*",". Optional \u002F nullable \u002F has-default schemas accept the\nempty case.",[16,2281,2282,2283,2285],{},"The directive's input listener auto-marks numeric inputs on empty\nDOM; strings and booleans require explicit ",[13,2284,2051],{}," (DOM state alone\ndoesn't carry \"user-cleared\" intent).",[16,2287,2288,2291,2292,2295,2296,2299,2300,2303,2304,2307,2308,2311],{},[305,2289,2290],{},"Introspection."," ",[13,2293,2294],{},"form.fields.\u003Cpath>.blank"," per-path;\n",[13,2297,2298],{},"form.blankPaths.value"," (frozen ",[13,2301,2302],{},"ReadonlySet\u003CPathKey>",") for bulk.\n",[13,2305,2306],{},"isUnset(value)"," is the runtime guard; ",[13,2309,2310],{},"Unset"," the type-level\nbrand.",[119,2313,2315],{"id":2314},"other-exports","Other exports",[310,2317,2318,2327,2346,2355,2369,2378,2387],{},[313,2319,2320,2323,2324],{},[13,2321,2322],{},"parseDottedPath(s)"," — string → ",[13,2325,2326],{},"Segment[]",[313,2328,2329,1619,2331,2334,2335,2337,2338,2342,2343,2345],{},[13,2330,1265],{},[13,2332,2333],{},"unique symbol"," used to install a custom assigner on a v-register-bound element. For most cases prefer the ",[13,2336,992],{}," listener (see ",[236,2339,2341],{"href":2340},"#custom-assigners--updateregistervalue","Custom assigners","); reach for ",[13,2344,1265],{}," only when you need pre-mount installation (typically Web Components).",[313,2347,2348,2351,2352,2354],{},[13,2349,2350],{},"isRegisterValue(x)"," — type guard for the object ",[13,2353,514],{}," returns",[313,2356,2357,1619,2359,2361,2362,2364,2365,240],{},[13,2358,1473],{},[13,2360,1477],{}," — type alias for entries in ",[13,2363,1286],{},". Generic-erased so a personal library of transforms works across any path type; see ",[236,2366,2368],{"href":2367},"#transforms--registerpath--transforms-","Transforms",[313,2370,2371,213,2374,2377],{},[13,2372,2373],{},"ROOT_PATH",[13,2375,2376],{},"ROOT_PATH_KEY"," — the empty path and its key",[313,2379,2380,1619,2383,2386],{},[13,2381,2382],{},"PARSE_API_ERRORS_DEFAULTS",[13,2384,2385],{},"{ maxEntries: 1000, maxPathDepth: 32, maxTotalSegments: 10000 }"," constant",[313,2388,2389,213,2392,213,2395,213,2398,213,2401,213,2404,213,2407,2410],{},[13,2390,2391],{},"AnonPersistError",[13,2393,2394],{},"InvalidPathError",[13,2396,2397],{},"OutsideSetupError",[13,2399,2400],{},"RegistryNotInstalledError",[13,2402,2403],{},"ReservedFormKeyError",[13,2405,2406],{},"SensitivePersistFieldError",[13,2408,2409],{},"SubmitErrorHandlerError"," — error classes",[2412,2413,2414],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":25,"searchDepth":43,"depth":43,"links":2416},[2417,2418,2419,2420,2421,2422,2423,2424,2431,2432,2433,2434,2435],{"id":121,"depth":43,"text":124},{"id":265,"depth":43,"text":268},{"id":289,"depth":43,"text":292},{"id":350,"depth":43,"text":353},{"id":366,"depth":43,"text":369},{"id":383,"depth":43,"text":386},{"id":395,"depth":43,"text":398},{"id":468,"depth":43,"text":471,"children":2425},[2426,2427,2429],{"id":802,"depth":49,"text":803},{"id":988,"depth":49,"text":2428},"Custom assigners — @update:registerValue",{"id":1282,"depth":49,"text":2430},"Transforms — register(path, { transforms: [...] })",{"id":1563,"depth":43,"text":1566},{"id":1580,"depth":43,"text":1583},{"id":1853,"depth":43,"text":1854},{"id":2051,"depth":43,"text":2051},{"id":2314,"depth":43,"text":2315},"md",{},"\u002Fdocs\u002Fapi\u002Fcore",{"title":5,"description":18},"docs\u002Fapi\u002Fcore","S6aKACTllWPDBzHChjBu-Z3PMKAOS0eq1n7KkBOvYII",1777934135883]