[{"data":1,"prerenderedAt":1072},["ShallowReactive",2],{"content-\u002Fdocs\u002Frecipes\u002Fapp-defaults":3},{"id":4,"title":5,"body":6,"description":1065,"extension":1066,"meta":1067,"navigation":107,"path":1068,"seo":1069,"stem":1070,"__hash__":1071},"docs\u002Fdocs\u002Frecipes\u002Fapp-defaults.md","App-level defaults",{"type":7,"value":8,"toc":1053},"minimark",[9,13,43,48,53,204,208,285,289,292,300,303,307,310,423,453,457,463,605,613,638,644,657,660,812,825,868,882,886,892,1042,1049],[10,11,5],"h1",{"id":12},"app-level-defaults",[14,15,16,17,21,22,25,26,25,29,21,32,25,35,38,39,42],"p",{},"Attaform ships sensible library defaults (",[18,19,20],"code",{},"validateOn: 'change'",",\n",[18,23,24],{},"debounceMs: 0",", ",[18,27,28],{},"strict: true",[18,30,31],{},"coerce: true",[18,33,34],{},"rememberVariants: true",[18,36,37],{},"onInvalidSubmit: 'none'",") that fit most\napps out of the box. Set app-wide overrides once via the plugin\ninstead of repeating them at every ",[18,40,41],{},"useForm"," call.",[44,45,47],"h2",{"id":46},"setup","Setup",[49,50,52],"h3",{"id":51},"bare-vue-3","Bare Vue 3",[54,55,60],"pre",{"className":56,"code":57,"language":58,"meta":59,"style":59},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F main.ts\nimport { createApp } from 'vue'\nimport { createAttaform } from 'attaform'\n\ncreateApp(App)\n  .use(\n    createAttaform({\n      defaults: {\n        debounceMs: 100,\n        onInvalidSubmit: 'focus-first-error',\n      },\n    })\n  )\n  .mount('#app')\n","ts","",[18,61,62,71,89,102,109,119,131,140,146,158,169,175,181,187],{"__ignoreMap":59},[63,64,67],"span",{"class":65,"line":66},"line",1,[63,68,70],{"class":69},"sJ8bj","\u002F\u002F main.ts\n",[63,72,74,78,82,85],{"class":65,"line":73},2,[63,75,77],{"class":76},"szBVR","import",[63,79,81],{"class":80},"sVt8B"," { createApp } ",[63,83,84],{"class":76},"from",[63,86,88],{"class":87},"sZZnC"," 'vue'\n",[63,90,92,94,97,99],{"class":65,"line":91},3,[63,93,77],{"class":76},[63,95,96],{"class":80}," { createAttaform } ",[63,98,84],{"class":76},[63,100,101],{"class":87}," 'attaform'\n",[63,103,105],{"class":65,"line":104},4,[63,106,108],{"emptyLinePlaceholder":107},true,"\n",[63,110,112,116],{"class":65,"line":111},5,[63,113,115],{"class":114},"sScJk","createApp",[63,117,118],{"class":80},"(App)\n",[63,120,122,125,128],{"class":65,"line":121},6,[63,123,124],{"class":80},"  .",[63,126,127],{"class":114},"use",[63,129,130],{"class":80},"(\n",[63,132,134,137],{"class":65,"line":133},7,[63,135,136],{"class":114},"    createAttaform",[63,138,139],{"class":80},"({\n",[63,141,143],{"class":65,"line":142},8,[63,144,145],{"class":80},"      defaults: {\n",[63,147,149,152,156],{"class":65,"line":148},9,[63,150,151],{"class":80},"        debounceMs: ",[63,153,155],{"class":154},"sj4cs","100",[63,157,21],{"class":80},[63,159,161,164,167],{"class":65,"line":160},10,[63,162,163],{"class":80},"        onInvalidSubmit: ",[63,165,166],{"class":87},"'focus-first-error'",[63,168,21],{"class":80},[63,170,172],{"class":65,"line":171},11,[63,173,174],{"class":80},"      },\n",[63,176,178],{"class":65,"line":177},12,[63,179,180],{"class":80},"    })\n",[63,182,184],{"class":65,"line":183},13,[63,185,186],{"class":80},"  )\n",[63,188,190,192,195,198,201],{"class":65,"line":189},14,[63,191,124],{"class":80},[63,193,194],{"class":114},"mount",[63,196,197],{"class":80},"(",[63,199,200],{"class":87},"'#app'",[63,202,203],{"class":80},")\n",[49,205,207],{"id":206},"nuxt-3-4","Nuxt 3 \u002F 4",[54,209,211],{"className":56,"code":210,"language":58,"meta":59,"style":59},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: ['attaform\u002Fnuxt'],\n  attaform: {\n    defaults: {\n      debounceMs: 100,\n      onInvalidSubmit: 'focus-first-error',\n    },\n  },\n})\n",[18,212,213,218,231,242,247,252,261,270,275,280],{"__ignoreMap":59},[63,214,215],{"class":65,"line":66},[63,216,217],{"class":69},"\u002F\u002F nuxt.config.ts\n",[63,219,220,223,226,229],{"class":65,"line":73},[63,221,222],{"class":76},"export",[63,224,225],{"class":76}," default",[63,227,228],{"class":114}," defineNuxtConfig",[63,230,139],{"class":80},[63,232,233,236,239],{"class":65,"line":91},[63,234,235],{"class":80},"  modules: [",[63,237,238],{"class":87},"'attaform\u002Fnuxt'",[63,240,241],{"class":80},"],\n",[63,243,244],{"class":65,"line":104},[63,245,246],{"class":80},"  attaform: {\n",[63,248,249],{"class":65,"line":111},[63,250,251],{"class":80},"    defaults: {\n",[63,253,254,257,259],{"class":65,"line":121},[63,255,256],{"class":80},"      debounceMs: ",[63,258,155],{"class":154},[63,260,21],{"class":80},[63,262,263,266,268],{"class":65,"line":133},[63,264,265],{"class":80},"      onInvalidSubmit: ",[63,267,166],{"class":87},[63,269,21],{"class":80},[63,271,272],{"class":65,"line":142},[63,273,274],{"class":80},"    },\n",[63,276,277],{"class":65,"line":148},[63,278,279],{"class":80},"  },\n",[63,281,282],{"class":65,"line":160},[63,283,284],{"class":80},"})\n",[44,286,288],{"id":287},"resolution-order","Resolution order",[14,290,291],{},"For each option, the resolved value is the first defined among:",[54,293,298],{"className":294,"code":296,"language":297},[295],"language-text","useForm({ … })  >  createAttaform({ defaults })  >  library default\n","text",[18,299,296],{"__ignoreMap":59},[14,301,302],{},"So a per-form value always wins, an app-level default fills in when\nomitted, and the library's built-in default is the final fallback.",[44,304,306],{"id":305},"merge-semantics","Merge semantics",[14,308,309],{},"Every option resolves independently — set anything once at the app\nlevel, override anything per-form without losing the rest:",[54,311,313],{"className":56,"code":312,"language":58,"meta":59,"style":59},"\u002F\u002F Plugin side\ncreateAttaform({\n  defaults: { validateOn: 'change', debounceMs: 100 },\n})\n\n\u002F\u002F useForm calls\nuseForm({ schema })\n\u002F\u002F → validateOn: 'change', debounceMs: 100 (app-level both)\n\nuseForm({ schema, validateOn: 'blur' })\n\u002F\u002F → validateOn: 'blur', debounceMs: ignored\n\u002F\u002F   (validateOn: 'blur' rejects debounceMs by type, the inherited\n\u002F\u002F   100 is silently dropped)\n\nuseForm({ schema, debounceMs: 25 })\n\u002F\u002F → validateOn: 'change' (app-level), debounceMs: 25 (per-form wins)\n",[18,314,315,320,327,343,347,351,356,363,368,372,385,390,395,400,404,417],{"__ignoreMap":59},[63,316,317],{"class":65,"line":66},[63,318,319],{"class":69},"\u002F\u002F Plugin side\n",[63,321,322,325],{"class":65,"line":73},[63,323,324],{"class":114},"createAttaform",[63,326,139],{"class":80},[63,328,329,332,335,338,340],{"class":65,"line":91},[63,330,331],{"class":80},"  defaults: { validateOn: ",[63,333,334],{"class":87},"'change'",[63,336,337],{"class":80},", debounceMs: ",[63,339,155],{"class":154},[63,341,342],{"class":80}," },\n",[63,344,345],{"class":65,"line":104},[63,346,284],{"class":80},[63,348,349],{"class":65,"line":111},[63,350,108],{"emptyLinePlaceholder":107},[63,352,353],{"class":65,"line":121},[63,354,355],{"class":69},"\u002F\u002F useForm calls\n",[63,357,358,360],{"class":65,"line":133},[63,359,41],{"class":114},[63,361,362],{"class":80},"({ schema })\n",[63,364,365],{"class":65,"line":142},[63,366,367],{"class":69},"\u002F\u002F → validateOn: 'change', debounceMs: 100 (app-level both)\n",[63,369,370],{"class":65,"line":148},[63,371,108],{"emptyLinePlaceholder":107},[63,373,374,376,379,382],{"class":65,"line":160},[63,375,41],{"class":114},[63,377,378],{"class":80},"({ schema, validateOn: ",[63,380,381],{"class":87},"'blur'",[63,383,384],{"class":80}," })\n",[63,386,387],{"class":65,"line":171},[63,388,389],{"class":69},"\u002F\u002F → validateOn: 'blur', debounceMs: ignored\n",[63,391,392],{"class":65,"line":177},[63,393,394],{"class":69},"\u002F\u002F   (validateOn: 'blur' rejects debounceMs by type, the inherited\n",[63,396,397],{"class":65,"line":183},[63,398,399],{"class":69},"\u002F\u002F   100 is silently dropped)\n",[63,401,402],{"class":65,"line":189},[63,403,108],{"emptyLinePlaceholder":107},[63,405,407,409,412,415],{"class":65,"line":406},15,[63,408,41],{"class":114},[63,410,411],{"class":80},"({ schema, debounceMs: ",[63,413,414],{"class":154},"25",[63,416,384],{"class":80},[63,418,420],{"class":65,"line":419},16,[63,421,422],{"class":69},"\u002F\u002F → validateOn: 'change' (app-level), debounceMs: 25 (per-form wins)\n",[14,424,425,428,429,432,433,436,437,439,440,442,443,445,446,448,449,452],{},[18,426,427],{},"validateOn"," and ",[18,430,431],{},"debounceMs"," are flat top-level fields — there's no\nnested merge object anymore. The TS-level ",[18,434,435],{},"ValidateOnConfig","\ndiscriminated union enforces that ",[18,438,431],{}," is only valid when\n",[18,441,427],{}," is ",[18,444,334],{}," (or omitted); pairing it with ",[18,447,381],{}," \u002F\n",[18,450,451],{},"'submit'"," is a compile-time error.",[44,454,456],{"id":455},"whats-supported","What's supported",[14,458,459,462],{},[18,460,461],{},"AttaformDefaults"," covers the form-shaping options:",[54,464,466],{"className":56,"code":465,"language":58,"meta":59,"style":59},"type AttaformDefaults = {\n  strict?: boolean\n  validateOn?: 'change' | 'blur' | 'submit'\n  debounceMs?: number\n  onInvalidSubmit?: 'none' | 'focus-first-error' | 'scroll-to-first-error' | 'both'\n  history?: true | { max?: number }\n  rememberVariants?: boolean\n  coerce?: boolean | CoercionRegistry\n}\n",[18,467,468,482,494,515,525,550,576,585,600],{"__ignoreMap":59},[63,469,470,473,476,479],{"class":65,"line":66},[63,471,472],{"class":76},"type",[63,474,475],{"class":114}," AttaformDefaults",[63,477,478],{"class":76}," =",[63,480,481],{"class":80}," {\n",[63,483,484,488,491],{"class":65,"line":73},[63,485,487],{"class":486},"s4XuR","  strict",[63,489,490],{"class":76},"?:",[63,492,493],{"class":154}," boolean\n",[63,495,496,499,501,504,507,510,512],{"class":65,"line":91},[63,497,498],{"class":486},"  validateOn",[63,500,490],{"class":76},[63,502,503],{"class":87}," 'change'",[63,505,506],{"class":76}," |",[63,508,509],{"class":87}," 'blur'",[63,511,506],{"class":76},[63,513,514],{"class":87}," 'submit'\n",[63,516,517,520,522],{"class":65,"line":104},[63,518,519],{"class":486},"  debounceMs",[63,521,490],{"class":76},[63,523,524],{"class":154}," number\n",[63,526,527,530,532,535,537,540,542,545,547],{"class":65,"line":111},[63,528,529],{"class":486},"  onInvalidSubmit",[63,531,490],{"class":76},[63,533,534],{"class":87}," 'none'",[63,536,506],{"class":76},[63,538,539],{"class":87}," 'focus-first-error'",[63,541,506],{"class":76},[63,543,544],{"class":87}," 'scroll-to-first-error'",[63,546,506],{"class":76},[63,548,549],{"class":87}," 'both'\n",[63,551,552,555,557,560,562,565,568,570,573],{"class":65,"line":121},[63,553,554],{"class":486},"  history",[63,556,490],{"class":76},[63,558,559],{"class":154}," true",[63,561,506],{"class":76},[63,563,564],{"class":80}," { ",[63,566,567],{"class":486},"max",[63,569,490],{"class":76},[63,571,572],{"class":154}," number",[63,574,575],{"class":80}," }\n",[63,577,578,581,583],{"class":65,"line":133},[63,579,580],{"class":486},"  rememberVariants",[63,582,490],{"class":76},[63,584,493],{"class":154},[63,586,587,590,592,595,597],{"class":65,"line":142},[63,588,589],{"class":486},"  coerce",[63,591,490],{"class":76},[63,593,594],{"class":154}," boolean",[63,596,506],{"class":76},[63,598,599],{"class":114}," CoercionRegistry\n",[63,601,602],{"class":65,"line":148},[63,603,604],{"class":80},"}\n",[14,606,607,608,612],{},"What's ",[609,610,611],"strong",{},"not"," supported (and why):",[614,615,616,629],"ul",{},[617,618,619,25,622,25,625,628],"li",{},[18,620,621],{},"schema",[18,623,624],{},"key",[18,626,627],{},"defaultValues"," — per-form by definition. A\ncross-form schema doesn't make sense; per-form keys are identity.",[617,630,631,634,635,637],{},[18,632,633],{},"persist"," — opt-in per form already; cross-form storage defaults\nare ambiguous (key-prefix collisions, adapter selection). Set\n",[18,636,633],{}," per-form for now; this may land as a follow-up if a real\nuse case appears.",[44,639,641,642],{"id":640},"per-form-defaultvalues","Per-form ",[18,643,627],{},[14,645,646,647,428,650,652,653,656],{},"App-level defaults shape options like ",[18,648,649],{},"strict",[18,651,427],{},".\nPer-form initial values live on each ",[18,654,655],{},"useForm({ defaultValues })","\ncall.",[14,658,659],{},"Three patterns:",[54,661,663],{"className":56,"code":662,"language":58,"meta":59,"style":59},"import { unset } from 'attaform\u002Fzod'\n\n\u002F\u002F 1. Plain values — explicit defaults flow into storage and the form\n\u002F\u002F    is not blank for those leaves.\nuseForm({ schema, defaultValues: { email: 'me@example.com', count: 10 } })\n\n\u002F\u002F 2. Omit defaultValues entirely — every NUMERIC primitive leaf\n\u002F\u002F    (number, bigint) is auto-marked blank at construction. Storage\n\u002F\u002F    holds the schema's slim defaults; the form displays empty;\n\u002F\u002F    `form.errors.\u003Cpath>` reactively carries 'No value supplied' for\n\u002F\u002F    required schemas. Strings and booleans are NOT auto-marked\n\u002F\u002F    because their slim defaults match what the DOM shows natively\n\u002F\u002F    — the schema is the authority on whether `''` \u002F `false` is\n\u002F\u002F    acceptable. See `docs\u002Fblank.md` for the full rationale.\nuseForm({ schema })\n\n\u002F\u002F 3. Mark specific leaves as `unset` — those leaves are blank\n\u002F\u002F    explicitly, regardless of type. Numeric siblings without an\n\u002F\u002F    explicit value still auto-mark; string \u002F boolean siblings\n\u002F\u002F    without an explicit value are NOT auto-marked.\nuseForm({ schema, defaultValues: { email: unset, count: 10 } })\n\u002F\u002F                                  ^^^^^^^^^^^^^ blank (explicit unset)\n\u002F\u002F                                                  ^^^^^^^^^ explicit value\n",[18,664,665,677,681,686,691,710,714,719,724,729,734,739,744,749,754,760,764,770,776,782,788,800,806],{"__ignoreMap":59},[63,666,667,669,672,674],{"class":65,"line":66},[63,668,77],{"class":76},[63,670,671],{"class":80}," { unset } ",[63,673,84],{"class":76},[63,675,676],{"class":87}," 'attaform\u002Fzod'\n",[63,678,679],{"class":65,"line":73},[63,680,108],{"emptyLinePlaceholder":107},[63,682,683],{"class":65,"line":91},[63,684,685],{"class":69},"\u002F\u002F 1. Plain values — explicit defaults flow into storage and the form\n",[63,687,688],{"class":65,"line":104},[63,689,690],{"class":69},"\u002F\u002F    is not blank for those leaves.\n",[63,692,693,695,698,701,704,707],{"class":65,"line":111},[63,694,41],{"class":114},[63,696,697],{"class":80},"({ schema, defaultValues: { email: ",[63,699,700],{"class":87},"'me@example.com'",[63,702,703],{"class":80},", count: ",[63,705,706],{"class":154},"10",[63,708,709],{"class":80}," } })\n",[63,711,712],{"class":65,"line":121},[63,713,108],{"emptyLinePlaceholder":107},[63,715,716],{"class":65,"line":133},[63,717,718],{"class":69},"\u002F\u002F 2. Omit defaultValues entirely — every NUMERIC primitive leaf\n",[63,720,721],{"class":65,"line":142},[63,722,723],{"class":69},"\u002F\u002F    (number, bigint) is auto-marked blank at construction. Storage\n",[63,725,726],{"class":65,"line":148},[63,727,728],{"class":69},"\u002F\u002F    holds the schema's slim defaults; the form displays empty;\n",[63,730,731],{"class":65,"line":160},[63,732,733],{"class":69},"\u002F\u002F    `form.errors.\u003Cpath>` reactively carries 'No value supplied' for\n",[63,735,736],{"class":65,"line":171},[63,737,738],{"class":69},"\u002F\u002F    required schemas. Strings and booleans are NOT auto-marked\n",[63,740,741],{"class":65,"line":177},[63,742,743],{"class":69},"\u002F\u002F    because their slim defaults match what the DOM shows natively\n",[63,745,746],{"class":65,"line":183},[63,747,748],{"class":69},"\u002F\u002F    — the schema is the authority on whether `''` \u002F `false` is\n",[63,750,751],{"class":65,"line":189},[63,752,753],{"class":69},"\u002F\u002F    acceptable. See `docs\u002Fblank.md` for the full rationale.\n",[63,755,756,758],{"class":65,"line":406},[63,757,41],{"class":114},[63,759,362],{"class":80},[63,761,762],{"class":65,"line":419},[63,763,108],{"emptyLinePlaceholder":107},[63,765,767],{"class":65,"line":766},17,[63,768,769],{"class":69},"\u002F\u002F 3. Mark specific leaves as `unset` — those leaves are blank\n",[63,771,773],{"class":65,"line":772},18,[63,774,775],{"class":69},"\u002F\u002F    explicitly, regardless of type. Numeric siblings without an\n",[63,777,779],{"class":65,"line":778},19,[63,780,781],{"class":69},"\u002F\u002F    explicit value still auto-mark; string \u002F boolean siblings\n",[63,783,785],{"class":65,"line":784},20,[63,786,787],{"class":69},"\u002F\u002F    without an explicit value are NOT auto-marked.\n",[63,789,791,793,796,798],{"class":65,"line":790},21,[63,792,41],{"class":114},[63,794,795],{"class":80},"({ schema, defaultValues: { email: unset, count: ",[63,797,706],{"class":154},[63,799,709],{"class":80},[63,801,803],{"class":65,"line":802},22,[63,804,805],{"class":69},"\u002F\u002F                                  ^^^^^^^^^^^^^ blank (explicit unset)\n",[63,807,809],{"class":65,"line":808},23,[63,810,811],{"class":69},"\u002F\u002F                                                  ^^^^^^^^^ explicit value\n",[14,813,814,817,818,428,821,824],{},[18,815,816],{},"unset"," works in ",[18,819,820],{},"setValue('email', unset)",[18,822,823],{},"reset({ email: unset })","\nidentically — same semantic everywhere.",[14,826,827,828,830,831,834,835,428,838,841,842,845,846,849,850,853,854,857,858,857,861,857,864,867],{},"Auto-mark and explicit ",[18,829,816],{}," converge on the same state: the path\nlives in the form's ",[18,832,833],{},"blankPaths"," set, surfaced via\n",[18,836,837],{},"form.fields.\u003Cpath>.blank",[18,839,840],{},"form.blankPaths.value"," for bulk\nintrospection. The merged ",[18,843,844],{},"form.errors.\u003Cpath>"," reactively carries\n",[18,847,848],{},"'No value supplied'"," (",[18,851,852],{},"code: 'atta:no-value-supplied'",") for required\nschemas; ",[18,855,856],{},".optional()"," \u002F ",[18,859,860],{},".nullable()",[18,862,863],{},".default(N)",[18,865,866],{},".catch(N)","\nschemas accept the empty case.",[14,869,870,871,873,874,877,878,881],{},"To opt a numeric leaf OUT of auto-mark, supply a non-",[18,872,816],{}," value\n(",[18,875,876],{},"defaultValues: { count: 0 }"," is the explicit \"0 is intentional\"\nsignal). For strings and booleans you don't need an opt-out — they're\nnot auto-marked in the first place. See ",[18,879,880],{},"docs\u002Fblank.md"," for why the\nasymmetry is principled (storage \u002F display divergence is real for\nnumerics and absent for strings \u002F booleans).",[44,883,885],{"id":884},"alternative-userland-wrapper","Alternative: userland wrapper",[14,887,888,889,891],{},"If you need defaults but don't want to touch the plugin (third-party\ncomponent library, opting in only for some forms), wrap ",[18,890,41],{}," in\nyour project:",[54,893,895],{"className":56,"code":894,"language":58,"meta":59,"style":59},"\u002F\u002F composables\u002FuseAppForm.ts\nimport { useForm as attaformUseForm } from 'attaform\u002Fzod'\nimport type { z } from 'zod'\n\nexport function useAppForm\u003CS extends z.ZodObject>(opts: Parameters\u003Ctypeof attaformUseForm\u003CS>>[0]) {\n  return attaformUseForm({\n    validateOn: 'change',\n    debounceMs: 100,\n    ...opts,\n  })\n}\n",[18,896,897,902,919,934,938,997,1007,1016,1025,1033,1038],{"__ignoreMap":59},[63,898,899],{"class":65,"line":66},[63,900,901],{"class":69},"\u002F\u002F composables\u002FuseAppForm.ts\n",[63,903,904,906,909,912,915,917],{"class":65,"line":73},[63,905,77],{"class":76},[63,907,908],{"class":80}," { useForm ",[63,910,911],{"class":76},"as",[63,913,914],{"class":80}," attaformUseForm } ",[63,916,84],{"class":76},[63,918,676],{"class":87},[63,920,921,923,926,929,931],{"class":65,"line":91},[63,922,77],{"class":76},[63,924,925],{"class":76}," type",[63,927,928],{"class":80}," { z } ",[63,930,84],{"class":76},[63,932,933],{"class":87}," 'zod'\n",[63,935,936],{"class":65,"line":104},[63,937,108],{"emptyLinePlaceholder":107},[63,939,940,942,945,948,951,954,957,960,963,966,969,972,975,978,980,983,986,988,991,994],{"class":65,"line":111},[63,941,222],{"class":76},[63,943,944],{"class":76}," function",[63,946,947],{"class":114}," useAppForm",[63,949,950],{"class":80},"\u003C",[63,952,953],{"class":114},"S",[63,955,956],{"class":76}," extends",[63,958,959],{"class":114}," z",[63,961,962],{"class":80},".",[63,964,965],{"class":114},"ZodObject",[63,967,968],{"class":80},">(",[63,970,971],{"class":486},"opts",[63,973,974],{"class":76},":",[63,976,977],{"class":114}," Parameters",[63,979,950],{"class":80},[63,981,982],{"class":76},"typeof",[63,984,985],{"class":80}," attaformUseForm\u003C",[63,987,953],{"class":114},[63,989,990],{"class":80},">>[",[63,992,993],{"class":154},"0",[63,995,996],{"class":80},"]) {\n",[63,998,999,1002,1005],{"class":65,"line":121},[63,1000,1001],{"class":76},"  return",[63,1003,1004],{"class":114}," attaformUseForm",[63,1006,139],{"class":80},[63,1008,1009,1012,1014],{"class":65,"line":133},[63,1010,1011],{"class":80},"    validateOn: ",[63,1013,334],{"class":87},[63,1015,21],{"class":80},[63,1017,1018,1021,1023],{"class":65,"line":142},[63,1019,1020],{"class":80},"    debounceMs: ",[63,1022,155],{"class":154},[63,1024,21],{"class":80},[63,1026,1027,1030],{"class":65,"line":148},[63,1028,1029],{"class":76},"    ...",[63,1031,1032],{"class":80},"opts,\n",[63,1034,1035],{"class":65,"line":160},[63,1036,1037],{"class":80},"  })\n",[63,1039,1040],{"class":65,"line":171},[63,1041,604],{"class":80},[14,1043,1044,1045,1048],{},"This is fully equivalent for the consumer — every ",[18,1046,1047],{},"useAppForm"," call\ngets your defaults; per-form options still win via the spread. The\nplugin-level approach is more idiomatic for first-party apps; the\nwrapper is right when you can't (or shouldn't) influence the plugin\nconfig from your call site.",[1050,1051,1052],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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 .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .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 .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":59,"searchDepth":73,"depth":73,"links":1054},[1055,1059,1060,1061,1062,1064],{"id":46,"depth":73,"text":47,"children":1056},[1057,1058],{"id":51,"depth":91,"text":52},{"id":206,"depth":91,"text":207},{"id":287,"depth":73,"text":288},{"id":305,"depth":73,"text":306},{"id":455,"depth":73,"text":456},{"id":640,"depth":73,"text":1063},"Per-form defaultValues",{"id":884,"depth":73,"text":885},"Attaform ships sensible library defaults (validateOn: 'change',\ndebounceMs: 0, strict: true, coerce: true,\nrememberVariants: true, onInvalidSubmit: 'none') that fit most\napps out of the box. Set app-wide overrides once via the plugin\ninstead of repeating them at every useForm call.","md",{},"\u002Fdocs\u002Frecipes\u002Fapp-defaults",{"title":5,"description":1065},"docs\u002Frecipes\u002Fapp-defaults","OioB18t4x5u_WYwsx3XY-UQRfpnKUd1zzBvVPcOz36I",1777934136164]