[{"data":1,"prerenderedAt":790},["ShallowReactive",2],{"navigation_docs":3,"-resources-changelog":188,"-resources-changelog-surround":787},[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":185,"body":190,"description":780,"extension":781,"links":782,"meta":783,"navigation":784,"path":186,"seo":785,"stem":187,"__hash__":786},"docs\u002F7.resources\u002F5.changelog.md",{"type":191,"value":192,"toc":756},"minimark",[193,197,209,212,217,222,274,276,280,284,310,312,316,319,338,340,344,347,365,367,371,374,579,583,624,628,692,694,702,711],[194,195,185],"h1",{"id":196},"changelog",[198,199,200,201,208],"p",{},"Full history is on ",[202,203,207],"a",{"href":204,"rel":205},"https:\u002F\u002Fgithub.com\u002Fkolirt\u002Fvue-modal\u002Fcommits\u002Fv2",[206],"nofollow","GitHub",". This page summarises notable changes by release.",[210,211],"hr",{},[213,214,216],"h2",{"id":215},"v230","v2.3.0",[218,219,221],"h3",{"id":220},"added","Added",[223,224,225],"ul",{},[226,227,228,240,241,244,245,248,249,252,253,255,256,258,259,262,263,266,267,270,271,273],"li",{},[229,230,231,232,236,237],"strong",{},"Global lifecycle events ",[233,234,235],"code",{},"onModalOpen"," \u002F ",[233,238,239],{},"onModalClose"," — subscribe to modal open\u002Fclose events globally or scoped to a single group, with overloads ",[233,242,243],{},"(handler)"," and ",[233,246,247],{},"(group, handler)",". Handlers receive the ",[233,250,251],{},"ModalItem"," and run synchronously — ",[233,254,235],{}," fires right after the modal is pushed to state, ",[233,257,239],{}," fires after the modal is finalized and removed (before the ",[233,260,261],{},"openModal"," promise settles). Both return an unsubscribe function. Useful for cross-group coordination (e.g. closing every ",[233,264,265],{},"'sidebar'"," modal whenever something opens in ",[233,268,269],{},"'main'","), analytics, focus restoration. Thrown errors inside handlers are caught and logged so a faulty subscriber can't break the open\u002Fclose flow. See ",[202,272,156],{"href":157},".",[210,275],{},[213,277,279],{"id":278},"v221","v2.2.1",[218,281,283],{"id":282},"fixed","Fixed",[223,285,286],{},[226,287,288,294,295,298,299,302,303,306,307,309],{},[229,289,290,293],{},[233,291,292],{},"disableCloseOnInteractOutside"," now correctly suppresses true outside clicks"," — clicks landing outside the entire ",[233,296,297],{},"\u003CModalTarget>"," region (e.g. on the host site's header when the region is positioned below it) used to close the modal regardless of this flag, because reka-ui's ",[233,300,301],{},"pointer-down-outside"," handler treated them as overlay interactions. ",[233,304,305],{},"\u003CModalRoot>"," now scopes its overlay-close path to clicks whose target lies inside the region; outside-region clicks are handled exclusively by the ",[233,308,292],{}," gesture. The two flags are now fully independent.",[210,311],{},[213,313,315],{"id":314},"v220","v2.2.0",[218,317,221],{"id":318},"added-1",[223,320,321],{},[226,322,323,329,330,333,334,337],{},[229,324,325,328],{},[233,326,327],{},"\u003CModalOverlay>"," default slot"," — overlay now exposes a default slot so you can place decorative elements (blur layers, gradients, noise textures, branding watermarks, animated backgrounds) on top of the dimming layer. The overlay keeps ",[233,331,332],{},"pointer-events: none"," by default; set ",[233,335,336],{},"pointer-events: auto"," on slotted elements that need to receive interaction.",[210,339],{},[213,341,343],{"id":342},"v210","v2.1.0",[218,345,221],{"id":346},"added-2",[223,348,349],{},[226,350,351,356,357,360,361,364],{},[229,352,353],{},[233,354,355],{},"useModal().isTop"," — reactive ",[233,358,359],{},"ComputedRef\u003Cboolean>",", true only when the controller's instance is the topmost modal in the global stack. Complements ",[233,362,363],{},"isOpen",", which stays true while the instance is mounted regardless of stack position.",[210,366],{},[213,368,370],{"id":369},"v200","v2.0.0",[218,372,221],{"id":373},"added-3",[223,375,376,386,408,433,441,449,481,498,509,523,540,549,562],{},[226,377,378,381,382,385],{},[229,379,380],{},"Modal groups"," — every modal belongs to a named group; groups are registered via ",[233,383,384],{},"declare module '@kolirt\u002Fvue-modal' { interface ModalGroupRegistry { … } }"," for compile-time safety.",[226,387,388,403,404,407],{},[229,389,390,236,392,236,395,236,398,236,401],{},[233,391,305],{},[233,393,394],{},"\u003CModalContent>",[233,396,397],{},"\u003CModalTitle>",[233,399,400],{},"\u003CModalDescription>",[233,402,327],{}," — headless component primitives replacing the v1 ",[233,405,406],{},"BaseModal"," scoped-slot pattern.",[226,409,410,415,416,419,420,419,423,419,426,419,429,432],{},[229,411,412],{},[233,413,414],{},"useModalContext()"," — composable for ",[233,417,418],{},"confirm(data)",", ",[233,421,422],{},"close()",[233,424,425],{},"onBeforeClose(guard)",[233,427,428],{},"isTopmost",[233,430,431],{},"effectiveOptions"," inside a modal component.",[226,434,435,440],{},[229,436,437],{},[233,438,439],{},"useModal()"," — composable that binds a controller (open \u002F close \u002F isOpen \u002F on \u002F off) to a component with auto-cleanup on scope dispose.",[226,442,443,448],{},[229,444,445],{},[233,446,447],{},"replaceModal()"," — replaces the topmost modal in a group with a new one (instant exit, then open).",[226,450,451,462,463,244,466,469,470,473,474,236,477,480],{},[229,452,453,236,456,236,459],{},[233,454,455],{},"closeAllModals()",[233,457,458],{},"closeModalsByGroup()",[233,460,461],{},"closeModalById()"," — close helpers with optional ",[233,464,465],{},"ignoreGuard",[233,467,468],{},"instantExit"," flags (",[233,471,472],{},"closeModalById"," also accepts ",[233,475,476],{},"success",[233,478,479],{},"data",").",[226,482,483,489,490,493,494,497],{},[229,484,485,488],{},[233,486,487],{},"beforeClose"," guards"," — return ",[233,491,492],{},"false"," from a guard registered with ",[233,495,496],{},"onBeforeClose()"," to veto a close attempt.",[226,499,500,508],{},[229,501,502,236,505,507],{},[233,503,504],{},"instantEnter",[233,506,468],{}," options"," — skip enter or exit animations for programmatic flows.",[226,510,511,519,520,522],{},[229,512,513,236,516],{},[233,514,515],{},"ModalHandle.on",[233,517,518],{},".off"," — subscribe to events emitted by the modal component after ",[233,521,261],{}," returns.",[226,524,525,539],{},[229,526,527,236,530,236,533,236,536],{},[233,528,529],{},"modals",[233,531,532],{},"isOpened",[233,534,535],{},"groupModals()",[233,537,538],{},"isGroupOpen()"," — reactive state exports for reading the current stack.",[226,541,542,548],{},[229,543,544,547],{},[233,545,546],{},"ModalGroupRegistry"," TypeScript augmentation"," — all group strings are checked at compile time.",[226,550,551,554,555,557,558,561],{},[229,552,553],{},"reka-ui integration"," — ",[233,556,305],{}," delegates to ",[233,559,560],{},"\u003CDialogRoot>"," for ARIA, focus trap, and Escape handling.",[226,563,564,554,567,570,571,574,575,578],{},[229,565,566],{},"Scroll lock with layout-shift compensation",[233,568,569],{},"useScrollLock"," sets ",[233,572,573],{},"body.overflow"," and adds compensating ",[233,576,577],{},"body.paddingRight"," equal to the scrollbar width.",[218,580,582],{"id":581},"changed","Changed",[223,584,585,598,608,614],{},[226,586,587,590,591,594,595,273],{},[233,588,589],{},"openModal(Component, props, options?)"," → ",[233,592,593],{},"openModal(Component, options?)"," — props moved inside ",[233,596,597],{},"options.props",[226,599,600,601,604,605,273],{},"Plugin registration: ",[233,602,603],{},"createModal(Options)"," animation\u002Fstyle options removed; replaced with ",[233,606,607],{},"createModal({ groups: ModalGroupsConfig })",[226,609,610,613],{},[233,611,612],{},"ModalTarget"," group prop is now required and type-checked.",[226,615,616,617,620,621,273],{},"Source moved from ",[233,618,619],{},"lib\u002F"," to ",[233,622,623],{},"packages\u002Fcore\u002Fsrc\u002F",[218,625,627],{"id":626},"removed","Removed",[223,629,630,644,660,666,672,677],{},[226,631,632,635,636,639,640,643],{},[233,633,634],{},"confirmModal()"," global function (use ",[233,637,638],{},"useModalContext().confirm()"," from inside a modal, or ",[233,641,642],{},"closeModalById(id, { success: true, data })"," from outside).",[226,645,646,236,649,236,652,655,656,659],{},[233,647,648],{},"$on",[233,650,651],{},"$off",[233,653,654],{},"$emit"," event bus and ",[233,657,658],{},"Events"," enum.",[226,661,662,665],{},[233,663,664],{},"SimpleModal"," built-in layout component.",[226,667,668,671],{},[233,669,670],{},"useLock"," scroll-lock composable (scroll lock is now automatic per target).",[226,673,674,676],{},[233,675,406],{}," internal component.",[226,678,679,680,419,683,419,686,419,689,480],{},"Animation \u002F style options (",[233,681,682],{},"transitionTime",[233,684,685],{},"animationType",[233,687,688],{},"modalStyle",[233,690,691],{},"overlayStyle",[210,693],{},[213,695,697,698,701],{"id":696},"v1x-on-master-branch","v1.x (on ",[233,699,700],{},"master"," branch)",[198,703,704,705,710],{},"See ",[202,706,709],{"href":707,"rel":708},"https:\u002F\u002Fgithub.com\u002Fkolirt\u002Fvue-modal\u002Freleases",[206],"GitHub releases"," for the v1 history. Notable v1 milestones:",[223,712,713,729,741],{},[226,714,715,554,718,721,722,725,726,728],{},[229,716,717],{},"v1.2",[233,719,720],{},"backdrop-filter"," overlay option, ",[233,723,724],{},"force"," option on ",[233,727,261],{}," to close all before opening.",[226,730,731,734,735,738,739,273],{},[229,732,733],{},"v1.1"," — multiple group support, ",[233,736,737],{},"withoutOverlay"," prop on ",[233,740,612],{},[226,742,743,746,747,749,750,752,753,755],{},[229,744,745],{},"v1.0"," — initial release: imperative ",[233,748,261],{},", global event bus, ",[233,751,664],{}," layout, ",[233,754,670],{}," scroll lock.",{"title":757,"searchDepth":758,"depth":758,"links":759},"",2,[760,764,767,770,773,778],{"id":215,"depth":758,"text":216,"children":761},[762],{"id":220,"depth":763,"text":221},3,{"id":278,"depth":758,"text":279,"children":765},[766],{"id":282,"depth":763,"text":283},{"id":314,"depth":758,"text":315,"children":768},[769],{"id":318,"depth":763,"text":221},{"id":342,"depth":758,"text":343,"children":771},[772],{"id":346,"depth":763,"text":221},{"id":369,"depth":758,"text":370,"children":774},[775,776,777],{"id":373,"depth":763,"text":221},{"id":581,"depth":763,"text":582},{"id":626,"depth":763,"text":627},{"id":696,"depth":758,"text":779},"v1.x (on master branch)","Version history for @kolirt\u002Fvue-modal.","md",null,{},true,{"title":185,"description":780},"8TRElRtzf8HYxU75JdfQ_hbuPghgCZG_CP6MIeUZxZU",[788,782],{"title":181,"path":182,"stem":183,"description":789,"children":-1},"How @kolirt\u002Fvue-modal compares to other dialog solutions for Vue 3.",1779523622211]