[{"data":1,"prerenderedAt":1317},["ShallowReactive",2],{"content-\u002Fdocs\u002Fmultistep\u002Fhandle-submit":3},{"id":4,"title":5,"body":6,"description":1297,"extension":1298,"meta":1299,"metaRows":1300,"navigation":108,"path":1312,"seo":1313,"source":1314,"stem":1315,"__hash__":1316},"docs\u002Fdocs\u002Fmultistep\u002Fhandle-submit.md","handleSubmit",{"type":7,"value":8,"toc":1285},"minimark",[9,16,34,37,42,48,351,374,378,387,537,581,739,743,746,805,812,818,824,998,1027,1033,1048,1084,1090,1097,1109,1163,1180,1184,1226,1230,1281],[10,11,13],"h1",{"id":12},"handlesubmit",[14,15,5],"code",{},[17,18,19],"blockquote",{},[20,21,22,25,26,29,30,33],"p",{},[14,23,24],{},"wizard.handleSubmit(onSubmit, onError?)"," returns one event handler that fits every Next-and-Finish button in the wizard. Intermediate calls validate the active form and advance on success; the final call validates every form in parallel, calls ",[14,27,28],{},"onSubmit"," once, and stays on the terminal step. ",[14,31,32],{},"isFinal"," on the context is the only difference the consumer needs to switch on.",[35,36],"docs-meta-table",{},[38,39,41],"h2",{"id":40},"the-same-handler-binds-to-every-button","The same handler binds to every button",[20,43,44,47],{},[14,45,46],{},"wizard.handleSubmit"," returns an event handler. Bind it once and reuse it for every Next button, every Finish button, and any submit-via-keyboard path:",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup lang=\"ts\">\n  import { useForm, useWizard } from 'attaform\u002Fzod'\n\n  const wizard = useWizard({ steps: [shipping, payment, review] })\n\n  const onSubmit = wizard.handleSubmit(async (ctx) => {\n    if (!ctx.isFinal) return\n    await api.checkout({\n      shipping: ctx.get(shipping),\n      payment: ctx.get(payment),\n    })\n  })\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"onSubmit\">\n    \u003C!-- step body -->\n    \u003Cbutton :disabled=\"wizard.submitting\" type=\"submit\">\n      {{ wizard.isFinalStep ? 'Finish' : 'Next' }}\n    \u003C\u002Fbutton>\n  \u003C\u002Fform>\n\u003C\u002Ftemplate>\n","vue","",[14,56,57,87,103,110,129,134,171,188,203,215,226,232,238,248,253,263,282,289,316,322,332,342],{"__ignoreMap":54},[58,59,62,66,70,74,77,80,84],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"sVt8B","\u003C",[58,67,69],{"class":68},"s9eBZ","script",[58,71,73],{"class":72},"sScJk"," setup",[58,75,76],{"class":72}," lang",[58,78,79],{"class":64},"=",[58,81,83],{"class":82},"sZZnC","\"ts\"",[58,85,86],{"class":64},">\n",[58,88,90,94,97,100],{"class":60,"line":89},2,[58,91,93],{"class":92},"szBVR","  import",[58,95,96],{"class":64}," { useForm, useWizard } ",[58,98,99],{"class":92},"from",[58,101,102],{"class":82}," 'attaform\u002Fzod'\n",[58,104,106],{"class":60,"line":105},3,[58,107,109],{"emptyLinePlaceholder":108},true,"\n",[58,111,113,116,120,123,126],{"class":60,"line":112},4,[58,114,115],{"class":92},"  const",[58,117,119],{"class":118},"sj4cs"," wizard",[58,121,122],{"class":92}," =",[58,124,125],{"class":72}," useWizard",[58,127,128],{"class":64},"({ steps: [shipping, payment, review] })\n",[58,130,132],{"class":60,"line":131},5,[58,133,109],{"emptyLinePlaceholder":108},[58,135,137,139,142,144,147,149,152,155,158,162,165,168],{"class":60,"line":136},6,[58,138,115],{"class":92},[58,140,141],{"class":118}," onSubmit",[58,143,122],{"class":92},[58,145,146],{"class":64}," wizard.",[58,148,5],{"class":72},[58,150,151],{"class":64},"(",[58,153,154],{"class":92},"async",[58,156,157],{"class":64}," (",[58,159,161],{"class":160},"s4XuR","ctx",[58,163,164],{"class":64},") ",[58,166,167],{"class":92},"=>",[58,169,170],{"class":64}," {\n",[58,172,174,177,179,182,185],{"class":60,"line":173},7,[58,175,176],{"class":92},"    if",[58,178,157],{"class":64},[58,180,181],{"class":92},"!",[58,183,184],{"class":64},"ctx.isFinal) ",[58,186,187],{"class":92},"return\n",[58,189,191,194,197,200],{"class":60,"line":190},8,[58,192,193],{"class":92},"    await",[58,195,196],{"class":64}," api.",[58,198,199],{"class":72},"checkout",[58,201,202],{"class":64},"({\n",[58,204,206,209,212],{"class":60,"line":205},9,[58,207,208],{"class":64},"      shipping: ctx.",[58,210,211],{"class":72},"get",[58,213,214],{"class":64},"(shipping),\n",[58,216,218,221,223],{"class":60,"line":217},10,[58,219,220],{"class":64},"      payment: ctx.",[58,222,211],{"class":72},[58,224,225],{"class":64},"(payment),\n",[58,227,229],{"class":60,"line":228},11,[58,230,231],{"class":64},"    })\n",[58,233,235],{"class":60,"line":234},12,[58,236,237],{"class":64},"  })\n",[58,239,241,244,246],{"class":60,"line":240},13,[58,242,243],{"class":64},"\u003C\u002F",[58,245,69],{"class":68},[58,247,86],{"class":64},[58,249,251],{"class":60,"line":250},14,[58,252,109],{"emptyLinePlaceholder":108},[58,254,256,258,261],{"class":60,"line":255},15,[58,257,65],{"class":64},[58,259,260],{"class":68},"template",[58,262,86],{"class":64},[58,264,266,269,272,275,277,280],{"class":60,"line":265},16,[58,267,268],{"class":64},"  \u003C",[58,270,271],{"class":68},"form",[58,273,274],{"class":72}," @submit.prevent",[58,276,79],{"class":64},[58,278,279],{"class":82},"\"onSubmit\"",[58,281,86],{"class":64},[58,283,285],{"class":60,"line":284},17,[58,286,288],{"class":287},"sJ8bj","    \u003C!-- step body -->\n",[58,290,292,295,298,301,303,306,309,311,314],{"class":60,"line":291},18,[58,293,294],{"class":64},"    \u003C",[58,296,297],{"class":68},"button",[58,299,300],{"class":72}," :disabled",[58,302,79],{"class":64},[58,304,305],{"class":82},"\"wizard.submitting\"",[58,307,308],{"class":72}," type",[58,310,79],{"class":64},[58,312,313],{"class":82},"\"submit\"",[58,315,86],{"class":64},[58,317,319],{"class":60,"line":318},19,[58,320,321],{"class":64},"      {{ wizard.isFinalStep ? 'Finish' : 'Next' }}\n",[58,323,325,328,330],{"class":60,"line":324},20,[58,326,327],{"class":64},"    \u003C\u002F",[58,329,297],{"class":68},[58,331,86],{"class":64},[58,333,335,338,340],{"class":60,"line":334},21,[58,336,337],{"class":64},"  \u003C\u002F",[58,339,271],{"class":68},[58,341,86],{"class":64},[58,343,345,347,349],{"class":60,"line":344},22,[58,346,243],{"class":64},[58,348,260],{"class":68},[58,350,86],{"class":64},[20,352,353,354,357,358,361,362,365,366,369,370,373],{},"The handler accepts an optional ",[14,355,356],{},"Event"," argument and calls ",[14,359,360],{},"preventDefault()"," when one is passed, so ",[14,363,364],{},"@submit"," and ",[14,367,368],{},"@click"," both work. Bare imperative calls (",[14,371,372],{},"onSubmit()"," with no event) are also fine; the handler just skips the prevent step.",[38,375,377],{"id":376},"the-submit-context","The submit context",[20,379,380,381,383,384,386],{},"The ",[14,382,28],{}," callback receives one ",[14,385,161],{}," argument:",[49,388,392],{"className":389,"code":390,"language":391,"meta":54,"style":54},"language-ts shiki shiki-themes github-light github-dark","type WizardSubmitContext = {\n  readonly values: Readonly\u003CRecord\u003CFormKey, unknown>>\n  readonly get: \u003CF extends AnyForm>(form: F) => F extends { readonly values: infer V } ? V : unknown\n  readonly currentKey: FormKey\n  readonly isFinal: boolean\n}\n","ts",[14,393,394,406,439,508,520,532],{"__ignoreMap":54},[58,395,396,399,402,404],{"class":60,"line":61},[58,397,398],{"class":92},"type",[58,400,401],{"class":72}," WizardSubmitContext",[58,403,122],{"class":92},[58,405,170],{"class":64},[58,407,408,411,414,417,420,422,425,427,430,433,436],{"class":60,"line":89},[58,409,410],{"class":92},"  readonly",[58,412,413],{"class":160}," values",[58,415,416],{"class":92},":",[58,418,419],{"class":72}," Readonly",[58,421,65],{"class":64},[58,423,424],{"class":72},"Record",[58,426,65],{"class":64},[58,428,429],{"class":72},"FormKey",[58,431,432],{"class":64},", ",[58,434,435],{"class":118},"unknown",[58,437,438],{"class":64},">>\n",[58,440,441,443,446,448,451,454,457,460,463,465,467,470,472,474,476,478,481,484,486,488,491,494,497,500,502,505],{"class":60,"line":105},[58,442,410],{"class":92},[58,444,445],{"class":72}," get",[58,447,416],{"class":92},[58,449,450],{"class":64}," \u003C",[58,452,453],{"class":72},"F",[58,455,456],{"class":92}," extends",[58,458,459],{"class":72}," AnyForm",[58,461,462],{"class":64},">(",[58,464,271],{"class":160},[58,466,416],{"class":92},[58,468,469],{"class":72}," F",[58,471,164],{"class":64},[58,473,167],{"class":92},[58,475,469],{"class":72},[58,477,456],{"class":92},[58,479,480],{"class":64}," { ",[58,482,483],{"class":92},"readonly",[58,485,413],{"class":160},[58,487,416],{"class":92},[58,489,490],{"class":92}," infer",[58,492,493],{"class":72}," V",[58,495,496],{"class":64}," } ",[58,498,499],{"class":92},"?",[58,501,493],{"class":72},[58,503,504],{"class":92}," :",[58,506,507],{"class":118}," unknown\n",[58,509,510,512,515,517],{"class":60,"line":112},[58,511,410],{"class":92},[58,513,514],{"class":160}," currentKey",[58,516,416],{"class":92},[58,518,519],{"class":72}," FormKey\n",[58,521,522,524,527,529],{"class":60,"line":131},[58,523,410],{"class":92},[58,525,526],{"class":160}," isFinal",[58,528,416],{"class":92},[58,530,531],{"class":118}," boolean\n",[58,533,534],{"class":60,"line":136},[58,535,536],{"class":64},"}\n",[538,539,540,551,557,563],"ul",{},[541,542,543,546,547,550],"li",{},[14,544,545],{},"ctx.values"," is the namespaced parsed payload, keyed by step key. Mirrors ",[14,548,549],{},"wizard.allValues"," for forms that validated successfully on this call. Affordance steps contribute an empty record.",[541,552,553,556],{},[14,554,555],{},"ctx.get(formRef)"," is the typed accessor: pass a form ref, get back the parsed output narrowed to that form's schema. The handy shape when you've already closed over the form refs at construction.",[541,558,559,562],{},[14,560,561],{},"ctx.currentKey"," is the key of the step that fired this submission.",[541,564,565,568,569,572,573,576,577,580],{},[14,566,567],{},"ctx.isFinal"," is ",[14,570,571],{},"true"," when ",[14,574,575],{},"currentKey"," is the last position in ",[14,578,579],{},"wizard.steps",". Use it to fork between \"advance to the next step\" (nothing to do here) and \"actually call the API.\"",[49,582,584],{"className":389,"code":583,"language":391,"meta":54,"style":54},"const onSubmit = wizard.handleSubmit(async (ctx) => {\n  if (!ctx.isFinal) {\n    \u002F\u002F Intermediate steps: validation passed. Track a step-complete event;\n    \u002F\u002F the wizard advances once this callback returns without setting errors.\n    analytics.track('wizard_step_complete', { step: ctx.currentKey })\n    return\n  }\n  \u002F\u002F Final step: validate-everything passed, run the actual mutation.\n  const order = await api.checkout({\n    shipping: ctx.get(shipping),\n    payment: ctx.get(payment),\n  })\n  router.push(`\u002Forders\u002F${order.id}`)\n})\n",[14,585,586,613,625,630,635,651,656,661,666,684,693,702,706,734],{"__ignoreMap":54},[58,587,588,591,593,595,597,599,601,603,605,607,609,611],{"class":60,"line":61},[58,589,590],{"class":92},"const",[58,592,141],{"class":118},[58,594,122],{"class":92},[58,596,146],{"class":64},[58,598,5],{"class":72},[58,600,151],{"class":64},[58,602,154],{"class":92},[58,604,157],{"class":64},[58,606,161],{"class":160},[58,608,164],{"class":64},[58,610,167],{"class":92},[58,612,170],{"class":64},[58,614,615,618,620,622],{"class":60,"line":89},[58,616,617],{"class":92},"  if",[58,619,157],{"class":64},[58,621,181],{"class":92},[58,623,624],{"class":64},"ctx.isFinal) {\n",[58,626,627],{"class":60,"line":105},[58,628,629],{"class":287},"    \u002F\u002F Intermediate steps: validation passed. Track a step-complete event;\n",[58,631,632],{"class":60,"line":112},[58,633,634],{"class":287},"    \u002F\u002F the wizard advances once this callback returns without setting errors.\n",[58,636,637,640,643,645,648],{"class":60,"line":131},[58,638,639],{"class":64},"    analytics.",[58,641,642],{"class":72},"track",[58,644,151],{"class":64},[58,646,647],{"class":82},"'wizard_step_complete'",[58,649,650],{"class":64},", { step: ctx.currentKey })\n",[58,652,653],{"class":60,"line":136},[58,654,655],{"class":92},"    return\n",[58,657,658],{"class":60,"line":173},[58,659,660],{"class":64},"  }\n",[58,662,663],{"class":60,"line":190},[58,664,665],{"class":287},"  \u002F\u002F Final step: validate-everything passed, run the actual mutation.\n",[58,667,668,670,673,675,678,680,682],{"class":60,"line":205},[58,669,115],{"class":92},[58,671,672],{"class":118}," order",[58,674,122],{"class":92},[58,676,677],{"class":92}," await",[58,679,196],{"class":64},[58,681,199],{"class":72},[58,683,202],{"class":64},[58,685,686,689,691],{"class":60,"line":217},[58,687,688],{"class":64},"    shipping: ctx.",[58,690,211],{"class":72},[58,692,214],{"class":64},[58,694,695,698,700],{"class":60,"line":228},[58,696,697],{"class":64},"    payment: ctx.",[58,699,211],{"class":72},[58,701,225],{"class":64},[58,703,704],{"class":60,"line":234},[58,705,237],{"class":64},[58,707,708,711,714,716,719,722,725,728,731],{"class":60,"line":240},[58,709,710],{"class":64},"  router.",[58,712,713],{"class":72},"push",[58,715,151],{"class":64},[58,717,718],{"class":82},"`\u002Forders\u002F${",[58,720,721],{"class":64},"order",[58,723,724],{"class":82},".",[58,726,727],{"class":64},"id",[58,729,730],{"class":82},"}`",[58,732,733],{"class":64},")\n",[58,735,736],{"class":60,"line":250},[58,737,738],{"class":64},"})\n",[38,740,742],{"id":741},"intermediate-vs-final","Intermediate vs final",[20,744,745],{},"The two calls do different work:",[538,747,748,769],{},[541,749,750,157,754,757,758,760,761,764,765,768],{},[751,752,753],"strong",{},"Intermediate call",[14,755,756],{},"ctx.isFinal === false","). Validates the active form only. On a clean pass, ",[14,759,28],{}," runs from the current step and the wizard then advances to the next compiled step. The advance is gated on the result: if validation fails, or if the callback hands a server rejection to ",[14,762,763],{},"setErrors"," and returns, the wizard stays put and ",[14,766,767],{},"onError"," fires.",[541,770,771,157,774,777,778,780,781,784,785,787,788,791,792,795,796,798,799,802,803,768],{},[751,772,773],{},"Final call",[14,775,776],{},"ctx.isFinal === true","). Validates every form in parallel. On success, ",[14,779,28],{}," runs once and ",[14,782,783],{},"wizard.done"," flips to ",[14,786,571],{}," (monotonic, only ",[14,789,790],{},"reset()"," flips it back). ",[14,793,794],{},"done"," flips only when the callback also leaves no errors set, so a ",[14,797,763],{},"-and-return server rejection keeps it ",[14,800,801],{},"false",". On a validation failure, the wizard stays on the terminal step and ",[14,804,767],{},[20,806,807,808,811],{},"The two paths share one handler and one context shape, so the consumer never has to choose between \"fire the mutation now\" and \"fire it later\" until the ",[14,809,810],{},"if (!ctx.isFinal) return"," guard at the top of the callback.",[38,813,815,816],{"id":814},"error-aggregation-with-onerror","Error aggregation with ",[14,817,767],{},[20,819,820,821,823],{},"The optional ",[14,822,767],{}," callback receives every error the submission produced, flat:",[49,825,827],{"className":389,"code":826,"language":391,"meta":54,"style":54},"const onSubmit = wizard.handleSubmit(\n  async (ctx) => {\n    if (!ctx.isFinal) return\n    await api.checkout(ctx.values)\n  },\n  (errors) => {\n    toast.error(`${errors.length} issue(s) before you can finish.`, {\n      description: errors.map((e) => `${e.formKey}: ${e.message}`).join('\\n'),\n    })\n  }\n)\n",[14,828,829,844,859,871,882,887,901,927,986,990,994],{"__ignoreMap":54},[58,830,831,833,835,837,839,841],{"class":60,"line":61},[58,832,590],{"class":92},[58,834,141],{"class":118},[58,836,122],{"class":92},[58,838,146],{"class":64},[58,840,5],{"class":72},[58,842,843],{"class":64},"(\n",[58,845,846,849,851,853,855,857],{"class":60,"line":89},[58,847,848],{"class":92},"  async",[58,850,157],{"class":64},[58,852,161],{"class":160},[58,854,164],{"class":64},[58,856,167],{"class":92},[58,858,170],{"class":64},[58,860,861,863,865,867,869],{"class":60,"line":105},[58,862,176],{"class":92},[58,864,157],{"class":64},[58,866,181],{"class":92},[58,868,184],{"class":64},[58,870,187],{"class":92},[58,872,873,875,877,879],{"class":60,"line":112},[58,874,193],{"class":92},[58,876,196],{"class":64},[58,878,199],{"class":72},[58,880,881],{"class":64},"(ctx.values)\n",[58,883,884],{"class":60,"line":131},[58,885,886],{"class":64},"  },\n",[58,888,889,892,895,897,899],{"class":60,"line":136},[58,890,891],{"class":64},"  (",[58,893,894],{"class":160},"errors",[58,896,164],{"class":64},[58,898,167],{"class":92},[58,900,170],{"class":64},[58,902,903,906,909,911,914,916,918,921,924],{"class":60,"line":173},[58,904,905],{"class":64},"    toast.",[58,907,908],{"class":72},"error",[58,910,151],{"class":64},[58,912,913],{"class":82},"`${",[58,915,894],{"class":64},[58,917,724],{"class":82},[58,919,920],{"class":118},"length",[58,922,923],{"class":82},"} issue(s) before you can finish.`",[58,925,926],{"class":64},", {\n",[58,928,929,932,935,938,941,943,945,948,950,952,955,958,960,962,965,967,970,973,975,978,981,983],{"class":60,"line":190},[58,930,931],{"class":64},"      description: errors.",[58,933,934],{"class":72},"map",[58,936,937],{"class":64},"((",[58,939,940],{"class":160},"e",[58,942,164],{"class":64},[58,944,167],{"class":92},[58,946,947],{"class":82}," `${",[58,949,940],{"class":64},[58,951,724],{"class":82},[58,953,954],{"class":64},"formKey",[58,956,957],{"class":82},"}: ${",[58,959,940],{"class":64},[58,961,724],{"class":82},[58,963,964],{"class":64},"message",[58,966,730],{"class":82},[58,968,969],{"class":64},").",[58,971,972],{"class":72},"join",[58,974,151],{"class":64},[58,976,977],{"class":82},"'",[58,979,980],{"class":118},"\\n",[58,982,977],{"class":82},[58,984,985],{"class":64},"),\n",[58,987,988],{"class":60,"line":205},[58,989,231],{"class":64},[58,991,992],{"class":60,"line":217},[58,993,660],{"class":64},[58,995,996],{"class":60,"line":228},[58,997,733],{"class":64},[20,999,1000,1001,432,1003,432,1006,1008,1009,1011,1012,1014,1015,1018,1019,1026],{},"Each error carries ",[14,1002,954],{},[14,1004,1005],{},"path",[14,1007,964],{},", and an optional ",[14,1010,14],{},". The list combines validation errors from every form processed on this call, any errors the callback set with ",[14,1013,763],{},", and any activation failures (e.g., a form whose async ",[14,1016,1017],{},"defaultValues"," rejected). For wizard-wide error summaries that persist between submissions, drive them off ",[1020,1021,1023],"a",{"href":1022},"\u002Fdocs\u002Fmultistep\u002Faggregates#allerrors-for-wizard-wide-summaries",[14,1024,1025],{},"wizard.allErrors"," instead.",[38,1028,1030],{"id":1029},"focusfirsterror",[14,1031,1032],{},"focusFirstError",[20,1034,1035,1036,1039,1040,1043,1044,1047],{},"When a submission produces errors, the wizard jumps to the first failing form and invokes its ",[14,1037,1038],{},"applyInvalidSubmitPolicy()"," (focus \u002F scroll per the form's own ",[14,1041,1042],{},"onInvalidSubmit"," configuration). The behavior is on by default; opt out by passing ",[14,1045,1046],{},"focusFirstError: false"," on the wizard:",[49,1049,1051],{"className":389,"code":1050,"language":391,"meta":54,"style":54},"const wizard = useWizard({\n  steps: [shipping, payment, review],\n  focusFirstError: false,\n})\n",[14,1052,1053,1065,1070,1080],{"__ignoreMap":54},[58,1054,1055,1057,1059,1061,1063],{"class":60,"line":61},[58,1056,590],{"class":92},[58,1058,119],{"class":118},[58,1060,122],{"class":92},[58,1062,125],{"class":72},[58,1064,202],{"class":64},[58,1066,1067],{"class":60,"line":89},[58,1068,1069],{"class":64},"  steps: [shipping, payment, review],\n",[58,1071,1072,1075,1077],{"class":60,"line":105},[58,1073,1074],{"class":64},"  focusFirstError: ",[58,1076,801],{"class":118},[58,1078,1079],{"class":64},",\n",[58,1081,1082],{"class":60,"line":112},[58,1083,738],{"class":64},[20,1085,1086,1087,1089],{},"With the focus jump disabled, the wizard stays on the terminal step and leaves navigation to the consumer's ",[14,1088,767],{}," callback. Useful when you've built a custom error-summary panel that owns the click-to-jump behavior.",[38,1091,1093,1096],{"id":1092},"wizardsubmitting-for-re-entrance",[14,1094,1095],{},"wizard.submitting"," for re-entrance",[20,1098,1099,1101,1102,1104,1105,1108],{},[14,1100,46],{}," guards against re-entrant calls: while a prior submission is still in flight (the ",[14,1103,28],{}," promise hasn't settled), subsequent calls dev-warn and resolve no-op. The ",[14,1106,1107],{},"submitting"," flag is the gate:",[49,1110,1112],{"className":51,"code":1111,"language":53,"meta":54,"style":54},"\u003Ctemplate>\n  \u003Cbutton :disabled=\"wizard.submitting\" type=\"submit\">\n    {{ wizard.submitting ? 'Submitting…' : 'Finish' }}\n  \u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n",[14,1113,1114,1122,1142,1147,1155],{"__ignoreMap":54},[58,1115,1116,1118,1120],{"class":60,"line":61},[58,1117,65],{"class":64},[58,1119,260],{"class":68},[58,1121,86],{"class":64},[58,1123,1124,1126,1128,1130,1132,1134,1136,1138,1140],{"class":60,"line":89},[58,1125,268],{"class":64},[58,1127,297],{"class":68},[58,1129,300],{"class":72},[58,1131,79],{"class":64},[58,1133,305],{"class":82},[58,1135,308],{"class":72},[58,1137,79],{"class":64},[58,1139,313],{"class":82},[58,1141,86],{"class":64},[58,1143,1144],{"class":60,"line":105},[58,1145,1146],{"class":64},"    {{ wizard.submitting ? 'Submitting…' : 'Finish' }}\n",[58,1148,1149,1151,1153],{"class":60,"line":112},[58,1150,337],{"class":64},[58,1152,297],{"class":68},[58,1154,86],{"class":64},[58,1156,1157,1159,1161],{"class":60,"line":131},[58,1158,243],{"class":64},[58,1160,260],{"class":68},[58,1162,86],{"class":64},[20,1164,1165,1166,432,1169,1172,1173,1176,1177,1179],{},"Disabling the button is belt-and-braces; the wizard refuses re-entry on its own. The flag also gates navigation: ",[14,1167,1168],{},"wizard.next()",[14,1170,1171],{},"wizard.back()",", and ",[14,1174,1175],{},"wizard.goTo()"," all refuse while ",[14,1178,1107],{}," is true so an in-flight submit can't be torn out from underneath itself.",[38,1181,1183],{"id":1182},"degenerate-inputs","Degenerate inputs",[538,1185,1186,1200,1206],{},[541,1187,1188,1191,1192,1194,1195,365,1197,1199],{},[751,1189,1190],{},"Empty steps list."," ",[14,1193,5],{}," dev-warns and resolves no-op. ",[14,1196,28],{},[14,1198,767],{}," are never invoked.",[541,1201,1202,1205],{},[751,1203,1204],{},"Re-entrant submission."," The second call dev-warns and resolves no-op; the first call continues to settle.",[541,1207,1208,1214,1215,1217,1218,1221,1222,1225],{},[751,1209,1210,1211,1213],{},"No ",[14,1212,356],{}," argument."," Imperative calls (",[14,1216,372],{}," with no event) work the same as ",[14,1219,1220],{},"\u003Cform @submit.prevent>","; the ",[14,1223,1224],{},"preventDefault"," step is skipped.",[38,1227,1229],{"id":1228},"where-to-next","Where to next",[538,1231,1232,1241,1256,1271],{},[541,1233,1234,1240],{},[1020,1235,1237],{"href":1236},"\u002Fdocs\u002Fmultistep\u002Fuse-wizard",[14,1238,1239],{},"useWizard"," for the construction signature and the full wizard handle.",[541,1242,1243,1247,1248,365,1250,1252,1253,1255],{},[1020,1244,1246],{"href":1245},"\u002Fdocs\u002Fmultistep\u002Faggregates","Aggregates"," for ",[14,1249,549],{},[14,1251,1025],{},", which mirror the data ",[14,1254,545],{}," carries.",[541,1257,1258,1262,1263,1266,1267,1270],{},[1020,1259,1261],{"href":1260},"\u002Fdocs\u002Fmultistep\u002Fstatuses","Statuses"," for the per-step ",[14,1264,1265],{},"FormStatus"," rollup that flips ",[14,1268,1269],{},"submitted: true"," when the callback succeeds.",[541,1272,1273,1277,1278,1280],{},[1020,1274,1276],{"href":1275},"\u002Fdocs\u002Fmultistep\u002Fpatterns","Patterns"," for branching flows that lean on ",[14,1279,46],{}," for the final-step validation sweep.",[1282,1283,1284],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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);}",{"title":54,"searchDepth":89,"depth":89,"links":1286},[1287,1288,1289,1290,1292,1293,1295,1296],{"id":40,"depth":89,"text":41},{"id":376,"depth":89,"text":377},{"id":741,"depth":89,"text":742},{"id":814,"depth":89,"text":1291},"Error aggregation with onError",{"id":1029,"depth":89,"text":1032},{"id":1092,"depth":89,"text":1294},"wizard.submitting for re-entrance",{"id":1182,"depth":89,"text":1183},{"id":1228,"depth":89,"text":1229},"wizard.handleSubmit(onSubmit, onError?) returns one event handler that fits every step. Intermediate calls validate the active form and advance; the final call validates every form in parallel and stays put. Same context shape on every step, with isFinal as the only differentiator.","md",{},[1301,1304,1306,1309],{"label":1302,"value":1303},"Category","Submission",{"label":1305,"value":24,"kind":14},"Signature",{"label":1307,"value":1308,"kind":14},"Context","{ values, get(form), currentKey, isFinal }",{"label":1310,"value":1311,"kind":14},"Error handler","(errors: AggregateError[]) => void | Promise\u003Cvoid>","\u002Fdocs\u002Fmultistep\u002Fhandle-submit",{"title":5,"description":1297},null,"docs\u002Fmultistep\u002Fhandle-submit","JQ9OjjHHLBB46ixA96DGKSofSKxF-gOV4LbLcp0TgHk",1781745874407]