[{"data":1,"prerenderedAt":752},["ShallowReactive",2],{"navigation_docs":3,"-concepts-architecture":188,"-concepts-architecture-surround":747},[4,9,27,52,101,130,163],{"title":5,"path":6,"stem":7,"icon":8},"Playground","\u002Fplayground","1.playground","i-lucide-flask-conical",{"title":10,"path":11,"stem":12,"children":13,"page":26},"Getting Started","\u002Fgetting-started","2.getting-started",[14,18,22],{"title":15,"path":16,"stem":17},"Introduction","\u002Fgetting-started\u002Fintroduction","2.getting-started\u002F1.introduction",{"title":19,"path":20,"stem":21},"Installation","\u002Fgetting-started\u002Finstallation","2.getting-started\u002F2.installation",{"title":23,"path":24,"stem":25},"First modal","\u002Fgetting-started\u002Ffirst-modal","2.getting-started\u002F3.first-modal",false,{"title":28,"path":29,"stem":30,"children":31,"page":26},"Concepts","\u002Fconcepts","3.concepts",[32,36,40,44,48],{"title":33,"path":34,"stem":35},"Architecture","\u002Fconcepts\u002Farchitecture","3.concepts\u002F1.architecture",{"title":37,"path":38,"stem":39},"Imperative flow","\u002Fconcepts\u002Fimperative-flow","3.concepts\u002F2.imperative-flow",{"title":41,"path":42,"stem":43},"Stacking","\u002Fconcepts\u002Fstacking","3.concepts\u002F3.stacking",{"title":45,"path":46,"stem":47},"Groups","\u002Fconcepts\u002Fgroups","3.concepts\u002F4.groups",{"title":49,"path":50,"stem":51},"Headless primitives","\u002Fconcepts\u002Fheadless-primitives","3.concepts\u002F5.headless-primitives",{"title":53,"path":54,"stem":55,"children":56,"page":26},"Guide","\u002Fguide","4.guide",[57,61,65,69,73,77,81,85,89,93,97],{"title":58,"path":59,"stem":60},"Writing a modal","\u002Fguide\u002Fwriting-a-modal","4.guide\u002F01.writing-a-modal",{"title":62,"path":63,"stem":64},"Opening & closing","\u002Fguide\u002Fopening-and-closing","4.guide\u002F02.opening-and-closing",{"title":66,"path":67,"stem":68},"Props & results","\u002Fguide\u002Fpassing-props-and-results","4.guide\u002F03.passing-props-and-results",{"title":70,"path":71,"stem":72},"Behavior options","\u002Fguide\u002Fbehavior-options","4.guide\u002F04.behavior-options",{"title":74,"path":75,"stem":76},"Animations & styling","\u002Fguide\u002Fstyling-and-animations","4.guide\u002F05.styling-and-animations",{"title":78,"path":79,"stem":80},"useModal composable","\u002Fguide\u002Fusemodal-composable","4.guide\u002F06.usemodal-composable",{"title":82,"path":83,"stem":84},"Modal context","\u002Fguide\u002Fmodal-context","4.guide\u002F07.modal-context",{"title":86,"path":87,"stem":88},"Multiple targets","\u002Fguide\u002Fmultiple-targets","4.guide\u002F08.multiple-targets",{"title":90,"path":91,"stem":92},"Overlay","\u002Fguide\u002Foverlay","4.guide\u002F09.overlay",{"title":94,"path":95,"stem":96},"Async components","\u002Fguide\u002Fasync-components","4.guide\u002F10.async-components",{"title":98,"path":99,"stem":100},"TypeScript","\u002Fguide\u002Ftypescript","4.guide\u002F11.typescript",{"title":102,"path":103,"stem":104,"children":105,"page":26},"Recipes","\u002Frecipes","5.recipes",[106,110,114,118,122,126],{"title":107,"path":108,"stem":109},"Confirm dialog","\u002Frecipes\u002Fconfirm-dialog","5.recipes\u002F1.confirm-dialog",{"title":111,"path":112,"stem":113},"Form modal with validation","\u002Frecipes\u002Fform-modal-with-validation","5.recipes\u002F2.form-modal-with-validation",{"title":115,"path":116,"stem":117},"Image lightbox","\u002Frecipes\u002Fimage-lightbox","5.recipes\u002F3.image-lightbox",{"title":119,"path":120,"stem":121},"Command palette","\u002Frecipes\u002Fcommand-palette","5.recipes\u002F4.command-palette",{"title":123,"path":124,"stem":125},"Nested flows \u002F wizards","\u002Frecipes\u002Fnested-flows","5.recipes\u002F5.nested-flows",{"title":127,"path":128,"stem":129},"Global error modal","\u002Frecipes\u002Fglobal-error-modal","5.recipes\u002F6.global-error-modal",{"title":131,"path":132,"stem":133,"children":134,"page":26},"Api","\u002Fapi","6.api",[135,139,143,147,151,155,159],{"title":136,"path":137,"stem":138},"Functions","\u002Fapi\u002Ffunctions","6.api\u002F1.functions",{"title":140,"path":141,"stem":142},"Components","\u002Fapi\u002Fcomponents","6.api\u002F2.components",{"title":144,"path":145,"stem":146},"Composables","\u002Fapi\u002Fcomposables","6.api\u002F3.composables",{"title":148,"path":149,"stem":150},"Plugin","\u002Fapi\u002Fplugin","6.api\u002F4.plugin",{"title":152,"path":153,"stem":154},"State helpers","\u002Fapi\u002Fstate","6.api\u002F5.state",{"title":156,"path":157,"stem":158},"Global events","\u002Fapi\u002Fevents","6.api\u002F6.events",{"title":160,"path":161,"stem":162},"Types","\u002Fapi\u002Ftypes","6.api\u002F7.types",{"title":164,"path":165,"stem":166,"children":167,"page":26},"Resources","\u002Fresources","7.resources",[168,172,176,180,184],{"title":169,"path":170,"stem":171},"Migration from v1","\u002Fresources\u002Fmigration-from-v1","7.resources\u002F1.migration-from-v1",{"title":173,"path":174,"stem":175},"FAQ","\u002Fresources\u002Ffaq","7.resources\u002F2.faq",{"title":177,"path":178,"stem":179},"Troubleshooting","\u002Fresources\u002Ftroubleshooting","7.resources\u002F3.troubleshooting",{"title":181,"path":182,"stem":183},"Comparison","\u002Fresources\u002Fcomparison","7.resources\u002F4.comparison",{"title":185,"path":186,"stem":187},"Changelog","\u002Fresources\u002Fchangelog","7.resources\u002F5.changelog",{"id":189,"title":33,"body":190,"description":740,"extension":741,"links":742,"meta":743,"navigation":744,"path":34,"seo":745,"stem":35,"__hash__":746},"docs\u002F3.concepts\u002F1.architecture.md",{"type":191,"value":192,"toc":733},"minimark",[193,197,214,219,230,312,316,323,351,358,362,373,563,572,576,715,719,726,729],[194,195,33],"h1",{"id":196},"architecture",[198,199,200,201,205,206,209,210,213],"p",{},"The package is built around three layers: a per-group ",[202,203,204],"strong",{},"host",", a per-modal ",[202,207,208],{},"wrapper",", and ",[202,211,212],{},"presentational"," primitives you compose inside your modal component.",[215,216,218],"h2",{"id":217},"three-layers","Three layers",[220,221,226],"pre",{"className":222,"code":224,"language":225},[223],"language-text","\u003CModalTarget group=\"...\">       ← group host (fixed, full-viewport)\n  \u003CModalOverlay \u002F>              ← optional backdrop\n  \u003CYourModal>\n    \u003CModalRoot>                 ← per-modal wrapper\n      \u003CModalContent>            ← focus trap, ARIA, exit-animation handling\n        \u003C!-- your markup -->\n      \u003C\u002FModalContent>\n    \u003C\u002FModalRoot>\n  \u003C\u002FYourModal>\n\u003C\u002FModalTarget>\n","text",[227,228,224],"code",{"__ignoreMap":229},"",[231,232,233,249],"table",{},[234,235,236],"thead",{},[237,238,239,243,246],"tr",{},[240,241,242],"th",{},"Layer",[240,244,245],{},"Component",[240,247,248],{},"Responsibility",[250,251,252,268,283],"tbody",{},[237,253,254,260,265],{},[255,256,257],"td",{},[202,258,259],{},"Host",[255,261,262],{},[227,263,264],{},"\u003CModalTarget>",[255,266,267],{},"Mounts modals of one group. Owns scroll lock, press-outside, stack sequencing.",[237,269,270,275,280],{},[255,271,272],{},[202,273,274],{},"Wrapper",[255,276,277],{},[227,278,279],{},"\u003CModalRoot>",[255,281,282],{},"Per-modal layer. Provides focus trap, ARIA, Esc routing.",[237,284,285,290,305],{},[255,286,287],{},[202,288,289],{},"Primitives",[255,291,292,295,296,295,299,295,302],{},[227,293,294],{},"\u003CModalContent>",", ",[227,297,298],{},"\u003CModalOverlay>",[227,300,301],{},"\u003CModalTitle>",[227,303,304],{},"\u003CModalDescription>",[255,306,307,308,311],{},"Zero-style elements with ",[227,309,310],{},"data-state"," hooks for your CSS.",[215,313,315],{"id":314},"what-happens-when-you-open-a-modal","What happens when you open a modal",[198,317,318,319,322],{},"When you call ",[227,320,321],{},"openModal(Component, options)",":",[324,325,326,330,338,341],"ol",{},[327,328,329],"li",{},"The target for that group mounts your component automatically.",[327,331,332,334,335,337],{},[227,333,279],{}," + ",[227,336,294],{}," set up focus trap, ARIA, and Esc\u002Foverlay handling.",[327,339,340],{},"Body scroll is locked while any modal in that group is open.",[327,342,318,343,346,347,350],{},[227,344,345],{},"confirm(data)"," or ",[227,348,349],{},"close()",", the package waits for your CSS exit animation, then unmounts and settles the promise.",[198,352,353,354,357],{},"You write the modal component and call ",[227,355,356],{},"openModal",". Mounting, focus, scroll, and animation timing are handled.",[215,359,361],{"id":360},"layout-contract","Layout contract",[198,363,364,365,368,369,372],{},"Each layer ships a tiny CSS reset using ",[227,366,367],{},":where()"," (specificity 0), so your own styles override without ",[227,370,371],{},"!important",".",[220,374,378],{"className":375,"code":376,"language":377,"meta":229,"style":229},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight",":where([data-modal-region]) {\n  position: fixed;\n  inset: 0;\n  pointer-events: none;\n}\n:where([data-modal-root]) {\n  position: absolute;\n  inset: 0;\n  pointer-events: auto;\n}\n:where([data-modal-overlay]) {\n  position: absolute;\n  inset: 0;\n  pointer-events: none;\n}\n","css",[227,379,380,404,420,434,447,453,469,481,492,504,509,525,536,547,558],{"__ignoreMap":229},[381,382,385,388,392,395,398,401],"span",{"class":383,"line":384},"line",1,[381,386,322],{"class":387},"sMK4o",[381,389,391],{"class":390},"spNyl","where",[381,393,394],{"class":387},"([",[381,396,397],{"class":390},"data-modal-region",[381,399,400],{"class":387},"])",[381,402,403],{"class":387}," {\n",[381,405,407,411,413,417],{"class":383,"line":406},2,[381,408,410],{"class":409},"sqsOY","  position",[381,412,322],{"class":387},[381,414,416],{"class":415},"sTEyZ"," fixed",[381,418,419],{"class":387},";\n",[381,421,423,426,428,432],{"class":383,"line":422},3,[381,424,425],{"class":409},"  inset",[381,427,322],{"class":387},[381,429,431],{"class":430},"sbssI"," 0",[381,433,419],{"class":387},[381,435,437,440,442,445],{"class":383,"line":436},4,[381,438,439],{"class":409},"  pointer-events",[381,441,322],{"class":387},[381,443,444],{"class":415}," none",[381,446,419],{"class":387},[381,448,450],{"class":383,"line":449},5,[381,451,452],{"class":387},"}\n",[381,454,456,458,460,462,465,467],{"class":383,"line":455},6,[381,457,322],{"class":387},[381,459,391],{"class":390},[381,461,394],{"class":387},[381,463,464],{"class":390},"data-modal-root",[381,466,400],{"class":387},[381,468,403],{"class":387},[381,470,472,474,476,479],{"class":383,"line":471},7,[381,473,410],{"class":409},[381,475,322],{"class":387},[381,477,478],{"class":415}," absolute",[381,480,419],{"class":387},[381,482,484,486,488,490],{"class":383,"line":483},8,[381,485,425],{"class":409},[381,487,322],{"class":387},[381,489,431],{"class":430},[381,491,419],{"class":387},[381,493,495,497,499,502],{"class":383,"line":494},9,[381,496,439],{"class":409},[381,498,322],{"class":387},[381,500,501],{"class":415}," auto",[381,503,419],{"class":387},[381,505,507],{"class":383,"line":506},10,[381,508,452],{"class":387},[381,510,512,514,516,518,521,523],{"class":383,"line":511},11,[381,513,322],{"class":387},[381,515,391],{"class":390},[381,517,394],{"class":387},[381,519,520],{"class":390},"data-modal-overlay",[381,522,400],{"class":387},[381,524,403],{"class":387},[381,526,528,530,532,534],{"class":383,"line":527},12,[381,529,410],{"class":409},[381,531,322],{"class":387},[381,533,478],{"class":415},[381,535,419],{"class":387},[381,537,539,541,543,545],{"class":383,"line":538},13,[381,540,425],{"class":409},[381,542,322],{"class":387},[381,544,431],{"class":430},[381,546,419],{"class":387},[381,548,550,552,554,556],{"class":383,"line":549},14,[381,551,439],{"class":409},[381,553,322],{"class":387},[381,555,444],{"class":415},[381,557,419],{"class":387},[381,559,561],{"class":383,"line":560},15,[381,562,452],{"class":387},[198,564,565,566,569,570,372],{},"The region is fixed and full-viewport, but does not block the page when empty (",[227,567,568],{},"pointer-events: none","). Each mounted modal re-enables pointer events on its own root. The overlay is purely visual — close-on-overlay-click is handled at the modal layer, so it works whether or not you render ",[227,571,298],{},[215,573,575],{"id":574},"data-attributes","Data attributes",[231,577,578,594],{},[234,579,580],{},[237,581,582,585,588,591],{},[240,583,584],{},"Attribute",[240,586,587],{},"Element",[240,589,590],{},"Values",[240,592,593],{},"Purpose",[250,595,596,612,627,643,658,685],{},[237,597,598,602,606,609],{},[255,599,600],{},[227,601,397],{},[255,603,604],{},[227,605,264],{},[255,607,608],{},"—",[255,610,611],{},"CSS scope for the host.",[237,613,614,618,622,624],{},[255,615,616],{},[227,617,464],{},[255,619,620],{},[227,621,279],{},[255,623,608],{},[255,625,626],{},"CSS scope per modal.",[237,628,629,634,638,640],{},[255,630,631],{},[227,632,633],{},"data-modal-content",[255,635,636],{},[227,637,294],{},[255,639,608],{},[255,641,642],{},"Style the visible card.",[237,644,645,649,653,655],{},[255,646,647],{},[227,648,520],{},[255,650,651],{},[227,652,298],{},[255,654,608],{},[255,656,657],{},"Style the backdrop.",[237,659,660,664,670,679],{},[255,661,662],{},[227,663,310],{},[255,665,666,295,668],{},[227,667,294],{},[227,669,298],{},[255,671,672,675,676],{},[227,673,674],{},"\"open\""," | ",[227,677,678],{},"\"closed\"",[255,680,681,682,684],{},"Drive enter\u002Fexit animations. Set to ",[227,683,678],{}," while the exit animation plays.",[237,686,687,692,698,704],{},[255,688,689],{},[227,690,691],{},"data-instant",[255,693,694,295,696],{},[227,695,294],{},[227,697,298],{},[255,699,700,703],{},[227,701,702],{},"\"\""," | absent",[255,705,706,707,710,711,714],{},"Present for the lifetime of a modal opened with ",[227,708,709],{},"instantEnter: true",". Built-in CSS scoped to ",[227,712,713],{},"[data-state=\"open\"]"," suppresses only the enter animation.",[215,716,718],{"id":717},"stack-behavior","Stack behavior",[198,720,721,722,725],{},"Modals in one group form a stack. Underlying modals stay mounted (preserving form values, scroll, and local state) but switch to ",[227,723,724],{},"data-state=\"closed\""," so your CSS hides or animates them out. Only the topmost modal reacts to Esc, overlay clicks, and Tab\u002Ffocus.",[198,727,728],{},"When the top modal closes or another opens on top, the package waits for the outgoing modal's exit animation before promoting the next one — you never see two modals \"open\" mid-transition.",[730,731,732],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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":229,"searchDepth":406,"depth":406,"links":734},[735,736,737,738,739],{"id":217,"depth":406,"text":218},{"id":314,"depth":406,"text":315},{"id":360,"depth":406,"text":361},{"id":574,"depth":406,"text":575},{"id":717,"depth":406,"text":718},"How ModalTarget, ModalRoot, and the headless primitives fit together.","md",null,{},true,{"title":33,"description":740},"PACDM7x40uNeH0DEnzG-XJ4jTq0dAUgljEM44BxQgt8",[748,750],{"title":23,"path":24,"stem":25,"description":749,"children":-1},"Write a modal component, open it imperatively, handle the result.",{"title":37,"path":38,"stem":39,"description":751,"children":-1},"Why the API is promise-based and how the modal lifecycle works.",1779523617515]