[{"data":1,"prerenderedAt":1416},["ShallowReactive",2],{"content-\u002Fdocs\u002Fmultistep\u002Finject-wizard":3},{"id":4,"title":5,"body":6,"description":1396,"extension":1397,"meta":1398,"metaRows":1399,"navigation":143,"path":1411,"seo":1412,"source":1413,"stem":1414,"__hash__":1415},"docs\u002Fdocs\u002Fmultistep\u002Finject-wizard.md","injectWizard",{"type":7,"value":8,"toc":1382},"minimark",[9,16,27,30,51,56,63,362,365,573,588,592,598,670,864,878,887,897,900,942,948,956,973,1025,1039,1045,1111,1117,1121,1131,1156,1159,1274,1278,1281,1299,1305,1309,1319,1323,1339,1343,1378],[10,11,13],"h1",{"id":12},"injectwizard",[14,15,5],"code",{},[17,18,19],"blockquote",{},[20,21,22,23,26],"p",{},"Reach a registered wizard from any descendant component. Ambient resolution for the parent's own wizard, keyed resolution for distant ones, and a single ",[14,24,25],{},"null"," on miss instead of a thrown error so floating panels, sticky nav rails, and sidebar widgets stay robust to mount-order quirks.",[28,29],"docs-meta-table",{},[20,31,32,35,36,38,39,42,43,50],{},[14,33,34],{},"useWizard"," creates and provides the wizard handle; ",[14,37,5],{}," looks it up. The two compose the way ",[14,40,41],{},"useForm"," and ",[44,45,47],"a",{"href":46},"\u002Fdocs\u002Fcross-cutting-state\u002Finject-form",[14,48,49],{},"injectForm"," do, scaled up to the wizard handle so a progress rail, a floating finish button, or a deep-tree review summary can reach the wizard without prop-threading.",[52,53,55],"h2",{"id":54},"the-common-case-ambient-resolution","The common case, ambient resolution",[20,57,58,59,62],{},"The parent owns the wizard (no ",[14,60,61],{},"key","):",[64,65,70],"pre",{"className":66,"code":67,"language":68,"meta":69,"style":69},"language-vue shiki shiki-themes github-light github-dark","\u003C!-- CheckoutWizard.vue -->\n\u003Cscript setup lang=\"ts\">\n  import { useForm, useWizard } from 'attaform\u002Fzod'\n  import { z } from 'zod'\n\n  const shippingSchema = z.object({ address: z.string(), city: z.string() })\n  const paymentSchema = z.object({ cardNumber: z.string(), cvv: z.string() })\n\n  const shipping = useForm({ schema: shippingSchema, key: 'shipping' })\n  const payment = useForm({ schema: paymentSchema, key: 'payment' })\n\n  const wizard = useWizard({\n    steps: ['welcome', shipping, payment, 'final-review'],\n  })\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CProgressRail \u002F>\n  \u003CStepBody \u002F>\n  \u003CNavButtons \u002F>\n\u003C\u002Ftemplate>\n","vue","",[14,71,72,81,109,125,138,145,178,204,209,231,251,256,272,290,296,306,311,321,333,343,353],{"__ignoreMap":69},[73,74,77],"span",{"class":75,"line":76},"line",1,[73,78,80],{"class":79},"sJ8bj","\u003C!-- CheckoutWizard.vue -->\n",[73,82,84,88,92,96,99,102,106],{"class":75,"line":83},2,[73,85,87],{"class":86},"sVt8B","\u003C",[73,89,91],{"class":90},"s9eBZ","script",[73,93,95],{"class":94},"sScJk"," setup",[73,97,98],{"class":94}," lang",[73,100,101],{"class":86},"=",[73,103,105],{"class":104},"sZZnC","\"ts\"",[73,107,108],{"class":86},">\n",[73,110,112,116,119,122],{"class":75,"line":111},3,[73,113,115],{"class":114},"szBVR","  import",[73,117,118],{"class":86}," { useForm, useWizard } ",[73,120,121],{"class":114},"from",[73,123,124],{"class":104}," 'attaform\u002Fzod'\n",[73,126,128,130,133,135],{"class":75,"line":127},4,[73,129,115],{"class":114},[73,131,132],{"class":86}," { z } ",[73,134,121],{"class":114},[73,136,137],{"class":104}," 'zod'\n",[73,139,141],{"class":75,"line":140},5,[73,142,144],{"emptyLinePlaceholder":143},true,"\n",[73,146,148,151,155,158,161,164,167,170,173,175],{"class":75,"line":147},6,[73,149,150],{"class":114},"  const",[73,152,154],{"class":153},"sj4cs"," shippingSchema",[73,156,157],{"class":114}," =",[73,159,160],{"class":86}," z.",[73,162,163],{"class":94},"object",[73,165,166],{"class":86},"({ address: z.",[73,168,169],{"class":94},"string",[73,171,172],{"class":86},"(), city: z.",[73,174,169],{"class":94},[73,176,177],{"class":86},"() })\n",[73,179,181,183,186,188,190,192,195,197,200,202],{"class":75,"line":180},7,[73,182,150],{"class":114},[73,184,185],{"class":153}," paymentSchema",[73,187,157],{"class":114},[73,189,160],{"class":86},[73,191,163],{"class":94},[73,193,194],{"class":86},"({ cardNumber: z.",[73,196,169],{"class":94},[73,198,199],{"class":86},"(), cvv: z.",[73,201,169],{"class":94},[73,203,177],{"class":86},[73,205,207],{"class":75,"line":206},8,[73,208,144],{"emptyLinePlaceholder":143},[73,210,212,214,217,219,222,225,228],{"class":75,"line":211},9,[73,213,150],{"class":114},[73,215,216],{"class":153}," shipping",[73,218,157],{"class":114},[73,220,221],{"class":94}," useForm",[73,223,224],{"class":86},"({ schema: shippingSchema, key: ",[73,226,227],{"class":104},"'shipping'",[73,229,230],{"class":86}," })\n",[73,232,234,236,239,241,243,246,249],{"class":75,"line":233},10,[73,235,150],{"class":114},[73,237,238],{"class":153}," payment",[73,240,157],{"class":114},[73,242,221],{"class":94},[73,244,245],{"class":86},"({ schema: paymentSchema, key: ",[73,247,248],{"class":104},"'payment'",[73,250,230],{"class":86},[73,252,254],{"class":75,"line":253},11,[73,255,144],{"emptyLinePlaceholder":143},[73,257,259,261,264,266,269],{"class":75,"line":258},12,[73,260,150],{"class":114},[73,262,263],{"class":153}," wizard",[73,265,157],{"class":114},[73,267,268],{"class":94}," useWizard",[73,270,271],{"class":86},"({\n",[73,273,275,278,281,284,287],{"class":75,"line":274},13,[73,276,277],{"class":86},"    steps: [",[73,279,280],{"class":104},"'welcome'",[73,282,283],{"class":86},", shipping, payment, ",[73,285,286],{"class":104},"'final-review'",[73,288,289],{"class":86},"],\n",[73,291,293],{"class":75,"line":292},14,[73,294,295],{"class":86},"  })\n",[73,297,299,302,304],{"class":75,"line":298},15,[73,300,301],{"class":86},"\u003C\u002F",[73,303,91],{"class":90},[73,305,108],{"class":86},[73,307,309],{"class":75,"line":308},16,[73,310,144],{"emptyLinePlaceholder":143},[73,312,314,316,319],{"class":75,"line":313},17,[73,315,87],{"class":86},[73,317,318],{"class":90},"template",[73,320,108],{"class":86},[73,322,324,327,330],{"class":75,"line":323},18,[73,325,326],{"class":86},"  \u003C",[73,328,329],{"class":90},"ProgressRail",[73,331,332],{"class":86}," \u002F>\n",[73,334,336,338,341],{"class":75,"line":335},19,[73,337,326],{"class":86},[73,339,340],{"class":90},"StepBody",[73,342,332],{"class":86},[73,344,346,348,351],{"class":75,"line":345},20,[73,347,326],{"class":86},[73,349,350],{"class":90},"NavButtons",[73,352,332],{"class":86},[73,354,356,358,360],{"class":75,"line":355},21,[73,357,301],{"class":86},[73,359,318],{"class":90},[73,361,108],{"class":86},[20,363,364],{},"Any descendant grabs the same wizard:",[64,366,368],{"className":66,"code":367,"language":68,"meta":69,"style":69},"\u003C!-- ProgressRail.vue -->\n\u003Cscript setup lang=\"ts\">\n  import { injectWizard } from 'attaform\u002Fzod'\n\n  const wizard = injectWizard()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Col v-if=\"wizard\">\n    \u003Cli\n      v-for=\"(step, i) in wizard.steps\"\n      :key=\"step.key\"\n      :class=\"{\n        done: wizard.statuses[step.key]?.valid,\n        current: wizard.currentStep === step.key,\n      }\"\n    >\n      \u003Cbutton type=\"button\" @click=\"wizard.goTo(step.key)\">Step {{ i + 1 }}\u003C\u002Fbutton>\n    \u003C\u002Fli>\n  \u003C\u002Fol>\n\u003C\u002Ftemplate>\n",[14,369,370,375,391,402,406,420,428,432,440,457,465,475,485,495,500,505,510,515,546,556,565],{"__ignoreMap":69},[73,371,372],{"class":75,"line":76},[73,373,374],{"class":79},"\u003C!-- ProgressRail.vue -->\n",[73,376,377,379,381,383,385,387,389],{"class":75,"line":83},[73,378,87],{"class":86},[73,380,91],{"class":90},[73,382,95],{"class":94},[73,384,98],{"class":94},[73,386,101],{"class":86},[73,388,105],{"class":104},[73,390,108],{"class":86},[73,392,393,395,398,400],{"class":75,"line":111},[73,394,115],{"class":114},[73,396,397],{"class":86}," { injectWizard } ",[73,399,121],{"class":114},[73,401,124],{"class":104},[73,403,404],{"class":75,"line":127},[73,405,144],{"emptyLinePlaceholder":143},[73,407,408,410,412,414,417],{"class":75,"line":140},[73,409,150],{"class":114},[73,411,263],{"class":153},[73,413,157],{"class":114},[73,415,416],{"class":94}," injectWizard",[73,418,419],{"class":86},"()\n",[73,421,422,424,426],{"class":75,"line":147},[73,423,301],{"class":86},[73,425,91],{"class":90},[73,427,108],{"class":86},[73,429,430],{"class":75,"line":180},[73,431,144],{"emptyLinePlaceholder":143},[73,433,434,436,438],{"class":75,"line":206},[73,435,87],{"class":86},[73,437,318],{"class":90},[73,439,108],{"class":86},[73,441,442,444,447,450,452,455],{"class":75,"line":211},[73,443,326],{"class":86},[73,445,446],{"class":90},"ol",[73,448,449],{"class":94}," v-if",[73,451,101],{"class":86},[73,453,454],{"class":104},"\"wizard\"",[73,456,108],{"class":86},[73,458,459,462],{"class":75,"line":233},[73,460,461],{"class":86},"    \u003C",[73,463,464],{"class":90},"li\n",[73,466,467,470,472],{"class":75,"line":253},[73,468,469],{"class":94},"      v-for",[73,471,101],{"class":86},[73,473,474],{"class":104},"\"(step, i) in wizard.steps\"\n",[73,476,477,480,482],{"class":75,"line":258},[73,478,479],{"class":94},"      :key",[73,481,101],{"class":86},[73,483,484],{"class":104},"\"step.key\"\n",[73,486,487,490,492],{"class":75,"line":274},[73,488,489],{"class":94},"      :class",[73,491,101],{"class":86},[73,493,494],{"class":104},"\"{\n",[73,496,497],{"class":75,"line":292},[73,498,499],{"class":104},"        done: wizard.statuses[step.key]?.valid,\n",[73,501,502],{"class":75,"line":298},[73,503,504],{"class":104},"        current: wizard.currentStep === step.key,\n",[73,506,507],{"class":75,"line":308},[73,508,509],{"class":104},"      }\"\n",[73,511,512],{"class":75,"line":313},[73,513,514],{"class":86},"    >\n",[73,516,517,520,523,526,528,531,534,536,539,542,544],{"class":75,"line":323},[73,518,519],{"class":86},"      \u003C",[73,521,522],{"class":90},"button",[73,524,525],{"class":94}," type",[73,527,101],{"class":86},[73,529,530],{"class":104},"\"button\"",[73,532,533],{"class":94}," @click",[73,535,101],{"class":86},[73,537,538],{"class":104},"\"wizard.goTo(step.key)\"",[73,540,541],{"class":86},">Step {{ i + 1 }}\u003C\u002F",[73,543,522],{"class":90},[73,545,108],{"class":86},[73,547,548,551,554],{"class":75,"line":335},[73,549,550],{"class":86},"    \u003C\u002F",[73,552,553],{"class":90},"li",[73,555,108],{"class":86},[73,557,558,561,563],{"class":75,"line":345},[73,559,560],{"class":86},"  \u003C\u002F",[73,562,446],{"class":90},[73,564,108],{"class":86},[73,566,567,569,571],{"class":75,"line":355},[73,568,301],{"class":86},[73,570,318],{"class":90},[73,572,108],{"class":86},[20,574,575,576,579,580,583,584,587],{},"The rail reads ",[14,577,578],{},"wizard.currentStep",", ",[14,581,582],{},"wizard.statuses",", and ",[14,585,586],{},"wizard.steps"," exactly the way the parent does. Same reactive surface, same identity. Updates in the parent propagate to the child without a roundtrip.",[52,589,591],{"id":590},"reaching-a-wizard-that-isnt-an-ancestor","Reaching a wizard that isn't an ancestor",[20,593,594,595,597],{},"Sticky finish buttons, sidebar status widgets, or any component in a different branch of the tree look up the wizard by ",[14,596,61],{},":",[64,599,601],{"className":66,"code":600,"language":68,"meta":69,"style":69},"\u003C!-- CheckoutWizard.vue -->\n\u003Cscript setup lang=\"ts\">\n  const wizard = useWizard({\n    steps: ['welcome', shipping, payment, 'final-review'],\n    key: 'checkout-wizard',\n  })\n\u003C\u002Fscript>\n",[14,602,603,607,623,635,647,658,662],{"__ignoreMap":69},[73,604,605],{"class":75,"line":76},[73,606,80],{"class":79},[73,608,609,611,613,615,617,619,621],{"class":75,"line":83},[73,610,87],{"class":86},[73,612,91],{"class":90},[73,614,95],{"class":94},[73,616,98],{"class":94},[73,618,101],{"class":86},[73,620,105],{"class":104},[73,622,108],{"class":86},[73,624,625,627,629,631,633],{"class":75,"line":111},[73,626,150],{"class":114},[73,628,263],{"class":153},[73,630,157],{"class":114},[73,632,268],{"class":94},[73,634,271],{"class":86},[73,636,637,639,641,643,645],{"class":75,"line":127},[73,638,277],{"class":86},[73,640,280],{"class":104},[73,642,283],{"class":86},[73,644,286],{"class":104},[73,646,289],{"class":86},[73,648,649,652,655],{"class":75,"line":140},[73,650,651],{"class":86},"    key: ",[73,653,654],{"class":104},"'checkout-wizard'",[73,656,657],{"class":86},",\n",[73,659,660],{"class":75,"line":147},[73,661,295],{"class":86},[73,663,664,666,668],{"class":75,"line":180},[73,665,301],{"class":86},[73,667,91],{"class":90},[73,669,108],{"class":86},[64,671,673],{"className":66,"code":672,"language":68,"meta":69,"style":69},"\u003C!-- FloatingFinishButton.vue (anywhere in the app) -->\n\u003Cscript setup lang=\"ts\">\n  import { injectWizard } from 'attaform\u002Fzod'\n\n  const wizard = injectWizard('checkout-wizard')\n\n  const finish = wizard?.handleSubmit(async (ctx) => {\n    if (!ctx.isFinal) return\n    await api.checkout(ctx.values)\n  })\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cbutton v-if=\"wizard\" :disabled=\"!wizard.complete\" @click=\"finish\">Finish\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n",[14,674,675,680,696,706,710,728,732,768,784,798,802,810,814,822,856],{"__ignoreMap":69},[73,676,677],{"class":75,"line":76},[73,678,679],{"class":79},"\u003C!-- FloatingFinishButton.vue (anywhere in the app) -->\n",[73,681,682,684,686,688,690,692,694],{"class":75,"line":83},[73,683,87],{"class":86},[73,685,91],{"class":90},[73,687,95],{"class":94},[73,689,98],{"class":94},[73,691,101],{"class":86},[73,693,105],{"class":104},[73,695,108],{"class":86},[73,697,698,700,702,704],{"class":75,"line":111},[73,699,115],{"class":114},[73,701,397],{"class":86},[73,703,121],{"class":114},[73,705,124],{"class":104},[73,707,708],{"class":75,"line":127},[73,709,144],{"emptyLinePlaceholder":143},[73,711,712,714,716,718,720,723,725],{"class":75,"line":140},[73,713,150],{"class":114},[73,715,263],{"class":153},[73,717,157],{"class":114},[73,719,416],{"class":94},[73,721,722],{"class":86},"(",[73,724,654],{"class":104},[73,726,727],{"class":86},")\n",[73,729,730],{"class":75,"line":147},[73,731,144],{"emptyLinePlaceholder":143},[73,733,734,736,739,741,744,747,749,752,755,759,762,765],{"class":75,"line":180},[73,735,150],{"class":114},[73,737,738],{"class":153}," finish",[73,740,157],{"class":114},[73,742,743],{"class":86}," wizard?.",[73,745,746],{"class":94},"handleSubmit",[73,748,722],{"class":86},[73,750,751],{"class":114},"async",[73,753,754],{"class":86}," (",[73,756,758],{"class":757},"s4XuR","ctx",[73,760,761],{"class":86},") ",[73,763,764],{"class":114},"=>",[73,766,767],{"class":86}," {\n",[73,769,770,773,775,778,781],{"class":75,"line":206},[73,771,772],{"class":114},"    if",[73,774,754],{"class":86},[73,776,777],{"class":114},"!",[73,779,780],{"class":86},"ctx.isFinal) ",[73,782,783],{"class":114},"return\n",[73,785,786,789,792,795],{"class":75,"line":211},[73,787,788],{"class":114},"    await",[73,790,791],{"class":86}," api.",[73,793,794],{"class":94},"checkout",[73,796,797],{"class":86},"(ctx.values)\n",[73,799,800],{"class":75,"line":233},[73,801,295],{"class":86},[73,803,804,806,808],{"class":75,"line":253},[73,805,301],{"class":86},[73,807,91],{"class":90},[73,809,108],{"class":86},[73,811,812],{"class":75,"line":258},[73,813,144],{"emptyLinePlaceholder":143},[73,815,816,818,820],{"class":75,"line":274},[73,817,87],{"class":86},[73,819,318],{"class":90},[73,821,108],{"class":86},[73,823,824,826,828,830,832,834,837,839,842,844,846,849,852,854],{"class":75,"line":292},[73,825,326],{"class":86},[73,827,522],{"class":90},[73,829,449],{"class":94},[73,831,101],{"class":86},[73,833,454],{"class":104},[73,835,836],{"class":94}," :disabled",[73,838,101],{"class":86},[73,840,841],{"class":104},"\"!wizard.complete\"",[73,843,533],{"class":94},[73,845,101],{"class":86},[73,847,848],{"class":104},"\"finish\"",[73,850,851],{"class":86},">Finish\u003C\u002F",[73,853,522],{"class":90},[73,855,108],{"class":86},[73,857,858,860,862],{"class":75,"line":298},[73,859,301],{"class":86},[73,861,318],{"class":90},[73,863,108],{"class":86},[20,865,866,867,869,870,873,874,877],{},"Pass the same ",[14,868,61],{}," the parent passed to ",[14,871,872],{},"useWizard({ key: 'checkout-wizard' })",". The handle returned is identity-equal to the parent's, so ",[14,875,876],{},"wizard.handleSubmit"," wired from a floating button runs the same submission pipeline the parent's Finish button would.",[20,879,880,882,883,886],{},[14,881,5],{}," accepts an object form too: ",[14,884,885],{},"injectWizard({ key: 'checkout-wizard' })",". The positional and object forms are equivalent; pick whichever spreads better into the surrounding setup.",[52,888,890,891,893,894,896],{"id":889},"do-i-need-to-pass-a-key-to-usewizard","Do I need to pass a ",[14,892,61],{}," to ",[14,895,34],{},"?",[20,898,899],{},"The two resolution modes are cleanly split:",[901,902,903,921],"ul",{},[553,904,905,912,913,916,917,920],{},[906,907,908,909,911],"strong",{},"Anonymous (no ",[14,910,61],{},") reaches ambient."," ",[14,914,915],{},"useWizard({ steps })"," fills the parent's ambient slot. Any descendant's ",[14,918,919],{},"injectWizard()"," (no key) resolves to it; closest ancestor wins when nested.",[553,922,923,912,930,933,934,937,938,941],{},[906,924,925,926,929],{},"Keyed (",[14,927,928],{},"key: 'x'",") reaches explicit access only.",[14,931,932],{},"useWizard({ steps, key: 'x' })"," registers the wizard under ",[14,935,936],{},"'x'"," but does NOT fill the ambient slot. Descendants reach it via ",[14,939,940],{},"injectWizard('x')",", not via the no-key form.",[20,943,944,945,947],{},"Skip ",[14,946,61],{}," for single-component wizards (an in-page checkout, a modal flow). Supply one when you want cross-tree lookup, a stable identifier for DevTools, or a sticky finish button rendered far from the step container.",[949,950,952,953,955],"h3",{"id":951},"gotcha-multiple-anonymous-usewizard-in-one-component","Gotcha: multiple anonymous ",[14,954,34],{}," in one component",[20,957,958,959,962,963,966,967,969,970,972],{},"Vue's ",[14,960,961],{},"provide"," \u002F ",[14,964,965],{},"inject"," is last-write-wins per component. If a parent calls ",[14,968,34],{}," twice without keys, the second overwrites the first in the ambient slot, and descendants using ",[14,971,919],{}," only see the second.",[64,974,978],{"className":975,"code":976,"language":977,"meta":69,"style":69},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F Parent component\nconst checkout = useWizard({ steps: [shipping, payment] }) \u002F\u002F ambient → checkout\nconst cancel = useWizard({ steps: [reasons, confirm] }) \u002F\u002F ambient → cancel (overwrites checkout)\n\u002F\u002F Descendants' injectWizard() reads cancel. checkout is unreachable via ambient.\n","ts",[14,979,980,985,1003,1020],{"__ignoreMap":69},[73,981,982],{"class":75,"line":76},[73,983,984],{"class":79},"\u002F\u002F Parent component\n",[73,986,987,990,993,995,997,1000],{"class":75,"line":83},[73,988,989],{"class":114},"const",[73,991,992],{"class":153}," checkout",[73,994,157],{"class":114},[73,996,268],{"class":94},[73,998,999],{"class":86},"({ steps: [shipping, payment] }) ",[73,1001,1002],{"class":79},"\u002F\u002F ambient → checkout\n",[73,1004,1005,1007,1010,1012,1014,1017],{"class":75,"line":111},[73,1006,989],{"class":114},[73,1008,1009],{"class":153}," cancel",[73,1011,157],{"class":114},[73,1013,268],{"class":94},[73,1015,1016],{"class":86},"({ steps: [reasons, confirm] }) ",[73,1018,1019],{"class":79},"\u002F\u002F ambient → cancel (overwrites checkout)\n",[73,1021,1022],{"class":75,"line":127},[73,1023,1024],{"class":79},"\u002F\u002F Descendants' injectWizard() reads cancel. checkout is unreachable via ambient.\n",[20,1026,1027,1028,1031,1032,1034,1035,1038],{},"Attaform emits a dev-mode ",[14,1029,1030],{},"console.warn"," lazily, when (and only when) a descendant actually consumes the ambient slot via ",[14,1033,919],{}," with no key. The warning lists each anonymous ",[14,1036,1037],{},"useWizard()"," call by source frame so you can navigate to the offending sites.",[20,1040,1041,1044],{},[906,1042,1043],{},"Fix:"," give each wizard a key (which removes them from the ambient slot entirely) and look them up explicitly:",[64,1046,1048],{"className":975,"code":1047,"language":977,"meta":69,"style":69},"useWizard({ steps: [shipping, payment], key: 'checkout' })\nuseWizard({ steps: [reasons, confirm], key: 'cancel' })\n\u002F\u002F Descendants:\nconst checkout = injectWizard('checkout')\nconst cancel = injectWizard('cancel')\n",[14,1049,1050,1062,1074,1079,1095],{"__ignoreMap":69},[73,1051,1052,1054,1057,1060],{"class":75,"line":76},[73,1053,34],{"class":94},[73,1055,1056],{"class":86},"({ steps: [shipping, payment], key: ",[73,1058,1059],{"class":104},"'checkout'",[73,1061,230],{"class":86},[73,1063,1064,1066,1069,1072],{"class":75,"line":83},[73,1065,34],{"class":94},[73,1067,1068],{"class":86},"({ steps: [reasons, confirm], key: ",[73,1070,1071],{"class":104},"'cancel'",[73,1073,230],{"class":86},[73,1075,1076],{"class":75,"line":111},[73,1077,1078],{"class":79},"\u002F\u002F Descendants:\n",[73,1080,1081,1083,1085,1087,1089,1091,1093],{"class":75,"line":127},[73,1082,989],{"class":114},[73,1084,992],{"class":153},[73,1086,157],{"class":114},[73,1088,416],{"class":94},[73,1090,722],{"class":86},[73,1092,1059],{"class":104},[73,1094,727],{"class":86},[73,1096,1097,1099,1101,1103,1105,1107,1109],{"class":75,"line":140},[73,1098,989],{"class":114},[73,1100,1009],{"class":153},[73,1102,157],{"class":114},[73,1104,416],{"class":94},[73,1106,722],{"class":86},[73,1108,1071],{"class":104},[73,1110,727],{"class":86},[20,1112,1113,1114,1116],{},"Mixing modes is fine. Keyed wizards don't interfere with an ambient sibling. A parent with three keyed wizards plus one anonymous wizard produces no warning; the descendant's ",[14,1115,919],{}," unambiguously resolves to the (only) anonymous one.",[52,1118,1120],{"id":1119},"when-resolution-fails","When resolution fails",[20,1122,1123,1125,1126,1128,1129,597],{},[14,1124,5],{}," returns ",[14,1127,25],{}," rather than throwing, so descendants are robust to mount-order quirks (a sidebar widget that renders before the wizard's parent setup runs, a conditional wizard ancestor, dynamic imports). Two cases produce ",[14,1130,25],{},[901,1132,1133,1147],{},[553,1134,1135,912,1138,1140,1141,1143,1144,1146],{},[906,1136,1137],{},"No ambient wizard.",[14,1139,919],{}," called from a tree with no ancestor ",[14,1142,34],{}," and no key. Returns ",[14,1145,25],{}," silently. Ambient lookup is opportunistic, so a floating widget reading the ambient slot stays quiet in trees that don't have a wizard rather than spamming consumers' consoles.",[553,1148,1149,912,1152,1155],{},[906,1150,1151],{},"Key not registered.",[14,1153,1154],{},"injectWizard('checkout-wizard')"," called when nothing is registered under that key. Dev mode logs the unresolved key alongside any keys that ARE registered, so a typo surfaces at a glance.",[20,1157,1158],{},"Guard the return so the consumer disappears cleanly when the wizard isn't mounted:",[64,1160,1162],{"className":66,"code":1161,"language":68,"meta":69,"style":69},"\u003Cscript setup lang=\"ts\">\n  import { injectWizard } from 'attaform\u002Fzod'\n\n  const wizard = injectWizard('checkout-wizard')\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Caside v-if=\"wizard\" class=\"wizard-status\">\n    Step {{ wizard.activeIndex + 1 }} of {{ wizard.count }}\n  \u003C\u002Faside>\n\u003C\u002Ftemplate>\n",[14,1163,1164,1180,1190,1194,1210,1218,1222,1230,1253,1258,1266],{"__ignoreMap":69},[73,1165,1166,1168,1170,1172,1174,1176,1178],{"class":75,"line":76},[73,1167,87],{"class":86},[73,1169,91],{"class":90},[73,1171,95],{"class":94},[73,1173,98],{"class":94},[73,1175,101],{"class":86},[73,1177,105],{"class":104},[73,1179,108],{"class":86},[73,1181,1182,1184,1186,1188],{"class":75,"line":83},[73,1183,115],{"class":114},[73,1185,397],{"class":86},[73,1187,121],{"class":114},[73,1189,124],{"class":104},[73,1191,1192],{"class":75,"line":111},[73,1193,144],{"emptyLinePlaceholder":143},[73,1195,1196,1198,1200,1202,1204,1206,1208],{"class":75,"line":127},[73,1197,150],{"class":114},[73,1199,263],{"class":153},[73,1201,157],{"class":114},[73,1203,416],{"class":94},[73,1205,722],{"class":86},[73,1207,654],{"class":104},[73,1209,727],{"class":86},[73,1211,1212,1214,1216],{"class":75,"line":140},[73,1213,301],{"class":86},[73,1215,91],{"class":90},[73,1217,108],{"class":86},[73,1219,1220],{"class":75,"line":147},[73,1221,144],{"emptyLinePlaceholder":143},[73,1223,1224,1226,1228],{"class":75,"line":180},[73,1225,87],{"class":86},[73,1227,318],{"class":90},[73,1229,108],{"class":86},[73,1231,1232,1234,1237,1239,1241,1243,1246,1248,1251],{"class":75,"line":206},[73,1233,326],{"class":86},[73,1235,1236],{"class":90},"aside",[73,1238,449],{"class":94},[73,1240,101],{"class":86},[73,1242,454],{"class":104},[73,1244,1245],{"class":94}," class",[73,1247,101],{"class":86},[73,1249,1250],{"class":104},"\"wizard-status\"",[73,1252,108],{"class":86},[73,1254,1255],{"class":75,"line":211},[73,1256,1257],{"class":86},"    Step {{ wizard.activeIndex + 1 }} of {{ wizard.count }}\n",[73,1259,1260,1262,1264],{"class":75,"line":233},[73,1261,560],{"class":86},[73,1263,1236],{"class":90},[73,1265,108],{"class":86},[73,1267,1268,1270,1272],{"class":75,"line":253},[73,1269,301],{"class":86},[73,1271,318],{"class":90},[73,1273,108],{"class":86},[52,1275,1277],{"id":1276},"lifetime","Lifetime",[20,1279,1280],{},"Both resolution modes ref-count the wizard handle in the registry. In practice:",[901,1282,1283,1286,1289],{},[553,1284,1285],{},"The wizard survives until every component that reached it unmounts.",[553,1287,1288],{},"Cleanup is automatic; no explicit dispose call from the consumer.",[553,1290,1291,1292,1295,1296,1298],{},"A wizard accessed only by ",[14,1293,1294],{},"injectWizard(key)"," stays alive as long as at least one consumer is mounted, even if the parent ",[14,1297,34],{}," owner unmounted first.",[20,1300,1301,1302,1304],{},"Hot-module reload reuses the existing handle when the parent SFC re-mounts (deferred-eviction-cancel within the same microtask). Child ",[14,1303,5],{}," consumers see the same wizard reactive surface they had before, not a freshly created one, so a rail's pre-filled state survives every save.",[52,1306,1308],{"id":1307},"duplicate-keys","Duplicate keys",[20,1310,1311,1312,1315,1316,1318],{},"Two calls to ",[14,1313,1314],{},"useWizard({ steps, key: 'checkout-wizard' })"," in the same app: the first wizard stays in the registry under that key, the second call dev-warns and the registry entry is left untouched. Any ",[14,1317,1154],{}," resolves to the original. The dev-warn names the colliding key so the accidental duplicate setup surfaces at a glance.",[52,1320,1322],{"id":1321},"ssr-isolation","SSR isolation",[20,1324,1325,1326,1329,1330,1333,1334,1338],{},"The wizard registry lives on the per-request ",[14,1327,1328],{},"AttaformRegistry"," instance created by ",[14,1331,1332],{},"createAttaform()",". A wizard registered in one server request does not leak into a sibling request rendering at the same time. The same isolation applies to forms registered through ",[44,1335,1336],{"href":46},[14,1337,49],{},".",[52,1340,1342],{"id":1341},"where-to-next","Where to next",[901,1344,1345,1353,1360,1371],{},[553,1346,1347,1352],{},[44,1348,1350],{"href":1349},"\u002Fdocs\u002Fmultistep\u002Fuse-wizard",[14,1351,34],{}," for the construction signature and the wizard's full reactive surface.",[553,1354,1355,1359],{},[44,1356,1358],{"href":1357},"\u002Fdocs\u002Fmultistep\u002Fstatuses","Statuses"," for the per-step rollup that drives a progress rail's classes.",[553,1361,1362,1366,1367,1370],{},[44,1363,1365],{"href":1364},"\u002Fdocs\u002Fmultistep\u002Fstep-slots","Step slots"," for the slot kinds that fill the ",[14,1368,1369],{},"steps"," list.",[553,1372,1373,1377],{},[44,1374,1375],{"href":46},[14,1376,49],{}," for single-form sharing across a tree.",[1379,1380,1381],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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 .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":69,"searchDepth":83,"depth":83,"links":1383},[1384,1385,1386,1391,1392,1393,1394,1395],{"id":54,"depth":83,"text":55},{"id":590,"depth":83,"text":591},{"id":889,"depth":83,"text":1387,"children":1388},"Do I need to pass a key to useWizard?",[1389],{"id":951,"depth":111,"text":1390},"Gotcha: multiple anonymous useWizard in one component",{"id":1119,"depth":83,"text":1120},{"id":1276,"depth":83,"text":1277},{"id":1307,"depth":83,"text":1308},{"id":1321,"depth":83,"text":1322},{"id":1341,"depth":83,"text":1342},"Reach a useWizard handle from any descendant component. Ambient resolution for the parent's own wizard, keyed resolution for distant ones. Returns the same reactive wizard that useWizard exposes; mutations on one are observable on the other.","md",{},[1400,1403,1406,1408],{"label":1401,"value":1402},"Category","Composable",{"label":1404,"value":1405,"kind":14},"Signature","injectWizard(input?: string | { key? }) => UseWizardReturnType | null",{"label":1407,"value":915,"kind":14},"Ambient mode",{"label":1409,"value":1410,"kind":14},"Explicit mode","useWizard({ steps, key })","\u002Fdocs\u002Fmultistep\u002Finject-wizard",{"title":5,"description":1396},null,"docs\u002Fmultistep\u002Finject-wizard","TAGgdpzxP1Lv8UceI9jLFUET5FofUyyCCiBT41mVtQM",1780949761572]