[{"data":1,"prerenderedAt":1304},["ShallowReactive",2],{"content-\u002Fdocs\u002Fmultistep\u002Fhandle-submit":3},{"id":4,"title":5,"body":6,"description":1284,"extension":1285,"meta":1286,"metaRows":1287,"navigation":108,"path":1299,"seo":1300,"source":1301,"stem":1302,"__hash__":1303},"docs\u002Fdocs\u002Fmultistep\u002Fhandle-submit.md","handleSubmit",{"type":7,"value":8,"toc":1272},"minimark",[9,16,34,37,42,48,351,374,378,387,537,581,739,743,746,795,802,808,814,988,1014,1020,1035,1072,1078,1085,1097,1151,1168,1172,1213,1217,1268],[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: wizard has already advanced; track a step-complete\n    \u002F\u002F event and let the user keep going.\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: wizard has already advanced; track a step-complete\n",[58,631,632],{"class":60,"line":112},[58,633,634],{"class":287},"    \u002F\u002F event and let the user keep going.\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,770],{},[541,749,750,157,754,757,758,762,763,765,766,769],{},[751,752,753],"strong",{},"Intermediate call",[14,755,756],{},"ctx.isFinal === false","). Validates the active form only. On success, the wizard advances to the next compiled step ",[759,760,761],"em",{},"before"," ",[14,764,28],{}," runs, so any side effect in the callback fires from the new step. On failure, the wizard stays put and ",[14,767,768],{},"onError"," fires.",[541,771,772,157,775,778,779,781,782,785,786,788,789,792,793,769],{},[751,773,774],{},"Final call",[14,776,777],{},"ctx.isFinal === true","). Validates every form in parallel. On success, ",[14,780,28],{}," runs once and ",[14,783,784],{},"wizard.done"," flips to ",[14,787,571],{}," (monotonic, only ",[14,790,791],{},"reset()"," flips it back). On failure, the wizard stays on the terminal step and ",[14,794,768],{},[20,796,797,798,801],{},"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,799,800],{},"if (!ctx.isFinal) return"," guard at the top of the callback.",[38,803,805,806],{"id":804},"error-aggregation-with-onerror","Error aggregation with ",[14,807,768],{},[20,809,810,811,813],{},"The optional ",[14,812,768],{}," callback receives every error the submission produced, flat:",[49,815,817],{"className":389,"code":816,"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,818,819,834,849,861,872,877,891,917,976,980,984],{"__ignoreMap":54},[58,820,821,823,825,827,829,831],{"class":60,"line":61},[58,822,590],{"class":92},[58,824,141],{"class":118},[58,826,122],{"class":92},[58,828,146],{"class":64},[58,830,5],{"class":72},[58,832,833],{"class":64},"(\n",[58,835,836,839,841,843,845,847],{"class":60,"line":89},[58,837,838],{"class":92},"  async",[58,840,157],{"class":64},[58,842,161],{"class":160},[58,844,164],{"class":64},[58,846,167],{"class":92},[58,848,170],{"class":64},[58,850,851,853,855,857,859],{"class":60,"line":105},[58,852,176],{"class":92},[58,854,157],{"class":64},[58,856,181],{"class":92},[58,858,184],{"class":64},[58,860,187],{"class":92},[58,862,863,865,867,869],{"class":60,"line":112},[58,864,193],{"class":92},[58,866,196],{"class":64},[58,868,199],{"class":72},[58,870,871],{"class":64},"(ctx.values)\n",[58,873,874],{"class":60,"line":131},[58,875,876],{"class":64},"  },\n",[58,878,879,882,885,887,889],{"class":60,"line":136},[58,880,881],{"class":64},"  (",[58,883,884],{"class":160},"errors",[58,886,164],{"class":64},[58,888,167],{"class":92},[58,890,170],{"class":64},[58,892,893,896,899,901,904,906,908,911,914],{"class":60,"line":173},[58,894,895],{"class":64},"    toast.",[58,897,898],{"class":72},"error",[58,900,151],{"class":64},[58,902,903],{"class":82},"`${",[58,905,884],{"class":64},[58,907,724],{"class":82},[58,909,910],{"class":118},"length",[58,912,913],{"class":82},"} issue(s) before you can finish.`",[58,915,916],{"class":64},", {\n",[58,918,919,922,925,928,931,933,935,938,940,942,945,948,950,952,955,957,960,963,965,968,971,973],{"class":60,"line":190},[58,920,921],{"class":64},"      description: errors.",[58,923,924],{"class":72},"map",[58,926,927],{"class":64},"((",[58,929,930],{"class":160},"e",[58,932,164],{"class":64},[58,934,167],{"class":92},[58,936,937],{"class":82}," `${",[58,939,930],{"class":64},[58,941,724],{"class":82},[58,943,944],{"class":64},"formKey",[58,946,947],{"class":82},"}: ${",[58,949,930],{"class":64},[58,951,724],{"class":82},[58,953,954],{"class":64},"message",[58,956,730],{"class":82},[58,958,959],{"class":64},").",[58,961,962],{"class":72},"join",[58,964,151],{"class":64},[58,966,967],{"class":82},"'",[58,969,970],{"class":118},"\\n",[58,972,967],{"class":82},[58,974,975],{"class":64},"),\n",[58,977,978],{"class":60,"line":205},[58,979,231],{"class":64},[58,981,982],{"class":60,"line":217},[58,983,660],{"class":64},[58,985,986],{"class":60,"line":228},[58,987,733],{"class":64},[20,989,990,991,432,993,432,996,998,999,1001,1002,1005,1006,1013],{},"Each error carries ",[14,992,944],{},[14,994,995],{},"path",[14,997,954],{},", and an optional ",[14,1000,14],{},". The list combines validation errors from every form processed on this call with any activation failures (e.g., a form whose async ",[14,1003,1004],{},"defaultValues"," rejected). For wizard-wide error summaries that persist between submissions, drive them off ",[1007,1008,1010],"a",{"href":1009},"\u002Fdocs\u002Fmultistep\u002Faggregates#allerrors-for-wizard-wide-summaries",[14,1011,1012],{},"wizard.allErrors"," instead.",[38,1015,1017],{"id":1016},"focusfirsterror",[14,1018,1019],{},"focusFirstError",[20,1021,1022,1023,1026,1027,1030,1031,1034],{},"When a submission produces errors, the wizard jumps to the first failing form and invokes its ",[14,1024,1025],{},"applyInvalidSubmitPolicy()"," (focus \u002F scroll per the form's own ",[14,1028,1029],{},"onInvalidSubmit"," configuration). The behavior is on by default; opt out by passing ",[14,1032,1033],{},"focusFirstError: false"," on the wizard:",[49,1036,1038],{"className":389,"code":1037,"language":391,"meta":54,"style":54},"const wizard = useWizard({\n  steps: [shipping, payment, review],\n  focusFirstError: false,\n})\n",[14,1039,1040,1052,1057,1068],{"__ignoreMap":54},[58,1041,1042,1044,1046,1048,1050],{"class":60,"line":61},[58,1043,590],{"class":92},[58,1045,119],{"class":118},[58,1047,122],{"class":92},[58,1049,125],{"class":72},[58,1051,202],{"class":64},[58,1053,1054],{"class":60,"line":89},[58,1055,1056],{"class":64},"  steps: [shipping, payment, review],\n",[58,1058,1059,1062,1065],{"class":60,"line":105},[58,1060,1061],{"class":64},"  focusFirstError: ",[58,1063,1064],{"class":118},"false",[58,1066,1067],{"class":64},",\n",[58,1069,1070],{"class":60,"line":112},[58,1071,738],{"class":64},[20,1073,1074,1075,1077],{},"With the focus jump disabled, the wizard stays on the terminal step and leaves navigation to the consumer's ",[14,1076,768],{}," callback. Useful when you've built a custom error-summary panel that owns the click-to-jump behavior.",[38,1079,1081,1084],{"id":1080},"wizardsubmitting-for-re-entrance",[14,1082,1083],{},"wizard.submitting"," for re-entrance",[20,1086,1087,1089,1090,1092,1093,1096],{},[14,1088,46],{}," guards against re-entrant calls: while a prior submission is still in flight (the ",[14,1091,28],{}," promise hasn't settled), subsequent calls dev-warn and resolve no-op. The ",[14,1094,1095],{},"submitting"," flag is the gate:",[49,1098,1100],{"className":51,"code":1099,"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,1101,1102,1110,1130,1135,1143],{"__ignoreMap":54},[58,1103,1104,1106,1108],{"class":60,"line":61},[58,1105,65],{"class":64},[58,1107,260],{"class":68},[58,1109,86],{"class":64},[58,1111,1112,1114,1116,1118,1120,1122,1124,1126,1128],{"class":60,"line":89},[58,1113,268],{"class":64},[58,1115,297],{"class":68},[58,1117,300],{"class":72},[58,1119,79],{"class":64},[58,1121,305],{"class":82},[58,1123,308],{"class":72},[58,1125,79],{"class":64},[58,1127,313],{"class":82},[58,1129,86],{"class":64},[58,1131,1132],{"class":60,"line":105},[58,1133,1134],{"class":64},"    {{ wizard.submitting ? 'Submitting…' : 'Finish' }}\n",[58,1136,1137,1139,1141],{"class":60,"line":112},[58,1138,337],{"class":64},[58,1140,297],{"class":68},[58,1142,86],{"class":64},[58,1144,1145,1147,1149],{"class":60,"line":131},[58,1146,243],{"class":64},[58,1148,260],{"class":68},[58,1150,86],{"class":64},[20,1152,1153,1154,432,1157,1160,1161,1164,1165,1167],{},"Disabling the button is belt-and-braces; the wizard refuses re-entry on its own. The flag also gates navigation: ",[14,1155,1156],{},"wizard.next()",[14,1158,1159],{},"wizard.back()",", and ",[14,1162,1163],{},"wizard.goTo()"," all refuse while ",[14,1166,1095],{}," is true so an in-flight submit can't be torn out from underneath itself.",[38,1169,1171],{"id":1170},"degenerate-inputs","Degenerate inputs",[538,1173,1174,1187,1193],{},[541,1175,1176,762,1179,1181,1182,365,1184,1186],{},[751,1177,1178],{},"Empty steps list.",[14,1180,5],{}," dev-warns and resolves no-op. ",[14,1183,28],{},[14,1185,768],{}," are never invoked.",[541,1188,1189,1192],{},[751,1190,1191],{},"Re-entrant submission."," The second call dev-warns and resolves no-op; the first call continues to settle.",[541,1194,1195,1201,1202,1204,1205,1208,1209,1212],{},[751,1196,1197,1198,1200],{},"No ",[14,1199,356],{}," argument."," Imperative calls (",[14,1203,372],{}," with no event) work the same as ",[14,1206,1207],{},"\u003Cform @submit.prevent>","; the ",[14,1210,1211],{},"preventDefault"," step is skipped.",[38,1214,1216],{"id":1215},"where-to-next","Where to next",[538,1218,1219,1228,1243,1258],{},[541,1220,1221,1227],{},[1007,1222,1224],{"href":1223},"\u002Fdocs\u002Fmultistep\u002Fuse-wizard",[14,1225,1226],{},"useWizard"," for the construction signature and the full wizard handle.",[541,1229,1230,1234,1235,365,1237,1239,1240,1242],{},[1007,1231,1233],{"href":1232},"\u002Fdocs\u002Fmultistep\u002Faggregates","Aggregates"," for ",[14,1236,549],{},[14,1238,1012],{},", which mirror the data ",[14,1241,545],{}," carries.",[541,1244,1245,1249,1250,1253,1254,1257],{},[1007,1246,1248],{"href":1247},"\u002Fdocs\u002Fmultistep\u002Fstatuses","Statuses"," for the per-step ",[14,1251,1252],{},"FormStatus"," rollup that flips ",[14,1255,1256],{},"submitted: true"," when the callback resolves.",[541,1259,1260,1264,1265,1267],{},[1007,1261,1263],{"href":1262},"\u002Fdocs\u002Fmultistep\u002Fpatterns","Patterns"," for branching flows that lean on ",[14,1266,46],{}," for the final-step validation sweep.",[1269,1270,1271],"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":1273},[1274,1275,1276,1277,1279,1280,1282,1283],{"id":40,"depth":89,"text":41},{"id":376,"depth":89,"text":377},{"id":741,"depth":89,"text":742},{"id":804,"depth":89,"text":1278},"Error aggregation with onError",{"id":1016,"depth":89,"text":1019},{"id":1080,"depth":89,"text":1281},"wizard.submitting for re-entrance",{"id":1170,"depth":89,"text":1171},{"id":1215,"depth":89,"text":1216},"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",{},[1288,1291,1293,1296],{"label":1289,"value":1290},"Category","Submission",{"label":1292,"value":24,"kind":14},"Signature",{"label":1294,"value":1295,"kind":14},"Context","{ values, get(form), currentKey, isFinal }",{"label":1297,"value":1298,"kind":14},"Error handler","(errors: AggregateError[]) => void | Promise\u003Cvoid>","\u002Fdocs\u002Fmultistep\u002Fhandle-submit",{"title":5,"description":1284},null,"docs\u002Fmultistep\u002Fhandle-submit","1J_cLc3pZl2UH85-hnR63TiXmuTxYwvx5kuSlvRPlnM",1780949761856]