[{"data":1,"prerenderedAt":1678},["ShallowReactive",2],{"navigation_docs":3,"-guide-core-concepts-tree-coordination-explained":271,"-guide-core-concepts-tree-coordination-explained-surround":1673},[4,135],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":28},"Guide","i-lucide-book-open","\u002Fguide","1.guide",[10,29,51,73,91,109],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":28},"Getting Started","i-lucide-rocket","\u002Fguide\u002Fgetting-started","1.guide\u002F1.getting-started",[16,20,24],{"title":17,"path":18,"stem":19},"Introduction","\u002Fguide\u002Fgetting-started\u002Fintroduction","1.guide\u002F1.getting-started\u002F1.introduction",{"title":21,"path":22,"stem":23},"First Tooltip","\u002Fguide\u002Fgetting-started\u002Ffirst-tooltip","1.guide\u002F1.getting-started\u002F2.first-tooltip",{"title":25,"path":26,"stem":27},"First Popover","\u002Fguide\u002Fgetting-started\u002Ffirst-popover","1.guide\u002F1.getting-started\u002F3.first-popover",false,{"title":30,"icon":31,"path":32,"stem":33,"children":34,"page":28},"Core Concepts","i-lucide-boxes","\u002Fguide\u002Fcore-concepts","1.guide\u002F2.core-concepts",[35,39,43,47],{"title":36,"path":37,"stem":38},"Floating Node","\u002Fguide\u002Fcore-concepts\u002Ffloating-node","1.guide\u002F2.core-concepts\u002F1.floating-node",{"title":40,"path":41,"stem":42},"Placement & Positioning","\u002Fguide\u002Fcore-concepts\u002Fplacement-and-positioning","1.guide\u002F2.core-concepts\u002F2.placement-and-positioning",{"title":44,"path":45,"stem":46},"Interaction Model","\u002Fguide\u002Fcore-concepts\u002Finteraction-model","1.guide\u002F2.core-concepts\u002F3.interaction-model",{"title":48,"path":49,"stem":50},"Tree Coordination","\u002Fguide\u002Fcore-concepts\u002Ftree-coordination-explained","1.guide\u002F2.core-concepts\u002F4.tree-coordination-explained",{"title":52,"icon":53,"path":54,"stem":55,"children":56,"page":28},"Patterns","i-lucide-component","\u002Fguide\u002Fcomponents","1.guide\u002F3.components",[57,61,65,69],{"title":58,"path":59,"stem":60},"Tooltips","\u002Fguide\u002Fcomponents\u002Fbuild-accessible-tooltips","1.guide\u002F3.components\u002F1.build-accessible-tooltips",{"title":62,"path":63,"stem":64},"Popovers & Dropdowns","\u002Fguide\u002Fcomponents\u002Fbuild-popovers-and-dropdowns","1.guide\u002F3.components\u002F2.build-popovers-and-dropdowns",{"title":66,"path":67,"stem":68},"Dialogs & Modals","\u002Fguide\u002Fcomponents\u002Fbuild-dialogs-and-modals","1.guide\u002F3.components\u002F3.build-dialogs-and-modals",{"title":70,"path":71,"stem":72},"Nested Menus","\u002Fguide\u002Fcomponents\u002Fbuild-nested-menus","1.guide\u002F3.components\u002F4.build-nested-menus",{"title":74,"icon":75,"path":76,"stem":77,"children":78,"page":28},"Positioning","i-lucide-crosshair","\u002Fguide\u002Fpositioning","1.guide\u002F4.positioning",[79,83,87],{"title":80,"path":81,"stem":82},"Keep in View","\u002Fguide\u002Fpositioning\u002Fkeep-content-in-view","1.guide\u002F4.positioning\u002F1.keep-content-in-view",{"title":84,"path":85,"stem":86},"Virtual Anchors","\u002Fguide\u002Fpositioning\u002Fuse-virtual-anchors","1.guide\u002F4.positioning\u002F2.use-virtual-anchors",{"title":88,"path":89,"stem":90},"Middleware Pipeline","\u002Fguide\u002Fpositioning\u002Fmiddleware-pipeline","1.guide\u002F4.positioning\u002F3.middleware-pipeline",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":28},"Accessibility","i-lucide-person-standing","\u002Fguide\u002Faccessibility","1.guide\u002F5.accessibility",[97,101,105],{"title":98,"path":99,"stem":100},"Open State","\u002Fguide\u002Faccessibility\u002Fcontrol-open-state","1.guide\u002F5.accessibility\u002F1.control-open-state",{"title":102,"path":103,"stem":104},"Focus Models","\u002Fguide\u002Faccessibility\u002Ffocus-models","1.guide\u002F5.accessibility\u002F2.focus-models",{"title":106,"path":107,"stem":108},"Keyboard Navigation","\u002Fguide\u002Faccessibility\u002Fkeyboard-navigation","1.guide\u002F5.accessibility\u002F3.keyboard-navigation",{"title":110,"icon":111,"path":112,"stem":113,"children":114,"page":28},"Advanced","i-lucide-cpu","\u002Fguide\u002Fadvanced","1.guide\u002F6.advanced",[115,119,123,127,131],{"title":116,"path":117,"stem":118},"Controlled vs Uncontrolled","\u002Fguide\u002Fadvanced\u002Fcontrolled-vs-uncontrolled","1.guide\u002F6.advanced\u002F1.controlled-vs-uncontrolled",{"title":120,"path":121,"stem":122},"Safe Polygons","\u002Fguide\u002Fadvanced\u002Fsafe-polygon-gotchas","1.guide\u002F6.advanced\u002F2.safe-polygon-gotchas",{"title":124,"path":125,"stem":126},"Virtual Anchor Gotchas","\u002Fguide\u002Fadvanced\u002Fvirtual-anchor-gotchas","1.guide\u002F6.advanced\u002F3.virtual-anchor-gotchas",{"title":128,"path":129,"stem":130},"Middleware Ordering","\u002Fguide\u002Fadvanced\u002Fmiddleware-ordering-gotchas","1.guide\u002F6.advanced\u002F4.middleware-ordering-gotchas",{"title":132,"path":133,"stem":134},"List Navigation","\u002Fguide\u002Fadvanced\u002Flist-navigation-gotchas","1.guide\u002F6.advanced\u002F5.list-navigation-gotchas",{"title":136,"icon":137,"path":138,"stem":139,"children":140},"API Reference","i-lucide-code-xml","\u002Fapi","2.api",[141,145,155,165,182,216,233],{"title":142,"path":138,"stem":143,"icon":144},"Overview","2.api\u002Findex","i-lucide-file-text",{"title":146,"icon":147,"path":148,"stem":149,"children":150,"page":28},"Reference","i-lucide-braces","\u002Fapi\u002Foverview","2.api\u002F1.overview",[151],{"title":152,"path":153,"stem":154},"Types","\u002Fapi\u002Foverview\u002Ftypes","2.api\u002F1.overview\u002F1.types",{"title":156,"icon":157,"path":158,"stem":159,"children":160,"page":28},"Core","i-lucide-box","\u002Fapi\u002Fcore","2.api\u002F2.core",[161],{"title":162,"path":163,"stem":164},"useFloatingNode","\u002Fapi\u002Fcore\u002Fuse-floating-node","2.api\u002F2.core\u002F1.use-floating-node",{"title":74,"icon":166,"path":167,"stem":168,"children":169,"page":28},"i-lucide-move","\u002Fapi\u002Fpositioning","2.api\u002F3.positioning",[170,174,178],{"title":171,"path":172,"stem":173},"usePosition","\u002Fapi\u002Fpositioning\u002Fuse-position","2.api\u002F3.positioning\u002F1.use-position",{"title":175,"path":176,"stem":177},"useArrow","\u002Fapi\u002Fpositioning\u002Fuse-arrow","2.api\u002F3.positioning\u002F2.use-arrow",{"title":179,"path":180,"stem":181},"useClientPoint","\u002Fapi\u002Fpositioning\u002Fuse-client-point","2.api\u002F3.positioning\u002F3.use-client-point",{"title":183,"icon":184,"path":185,"stem":186,"children":187,"page":28},"Interactions","i-lucide-mouse-pointer-click","\u002Fapi\u002Finteractions","2.api\u002F4.interactions",[188,192,196,200,204,208,212],{"title":189,"path":190,"stem":191},"useClick","\u002Fapi\u002Finteractions\u002Fuse-click","2.api\u002F4.interactions\u002F1.use-click",{"title":193,"path":194,"stem":195},"useHover","\u002Fapi\u002Finteractions\u002Fuse-hover","2.api\u002F4.interactions\u002F2.use-hover",{"title":197,"path":198,"stem":199},"useFocus","\u002Fapi\u002Finteractions\u002Fuse-focus","2.api\u002F4.interactions\u002F3.use-focus",{"title":201,"path":202,"stem":203},"useFocusTrap","\u002Fapi\u002Finteractions\u002Fuse-focus-trap","2.api\u002F4.interactions\u002F4.use-focus-trap",{"title":205,"path":206,"stem":207},"useOutsideClick","\u002Fapi\u002Finteractions\u002Fuse-outside-click","2.api\u002F4.interactions\u002F5.use-outside-click",{"title":209,"path":210,"stem":211},"useEscapeKey","\u002Fapi\u002Finteractions\u002Fuse-escape-key","2.api\u002F4.interactions\u002F6.use-escape-key",{"title":213,"path":214,"stem":215},"useRole","\u002Fapi\u002Finteractions\u002Fuse-role","2.api\u002F4.interactions\u002F7.use-role",{"title":106,"icon":217,"path":218,"stem":219,"children":220,"page":28},"i-lucide-keyboard","\u002Fapi\u002Fkeyboard-navigation","2.api\u002F5.keyboard-navigation",[221,225,229],{"title":222,"path":223,"stem":224},"useRovingFocus","\u002Fapi\u002Fkeyboard-navigation\u002Fuse-roving-focus","2.api\u002F5.keyboard-navigation\u002F1.use-roving-focus",{"title":226,"path":227,"stem":228},"useAriaActivedescendant","\u002Fapi\u002Fkeyboard-navigation\u002Fuse-aria-activedescendant","2.api\u002F5.keyboard-navigation\u002F2.use-aria-activedescendant",{"title":230,"path":231,"stem":232},"useTypeahead","\u002Fapi\u002Fkeyboard-navigation\u002Fuse-typeahead","2.api\u002F5.keyboard-navigation\u002F3.use-typeahead",{"title":234,"icon":235,"path":236,"stem":237,"children":238,"page":28},"Middleware","i-lucide-blocks","\u002Fapi\u002Fmiddleware","2.api\u002F6.middleware",[239,243,247,251,255,259,263,267],{"title":240,"path":241,"stem":242},"offset","\u002Fapi\u002Fmiddleware\u002Foffset","2.api\u002F6.middleware\u002F1.offset",{"title":244,"path":245,"stem":246},"flip","\u002Fapi\u002Fmiddleware\u002Fflip","2.api\u002F6.middleware\u002F2.flip",{"title":248,"path":249,"stem":250},"shift","\u002Fapi\u002Fmiddleware\u002Fshift","2.api\u002F6.middleware\u002F3.shift",{"title":252,"path":253,"stem":254},"autoPlacement","\u002Fapi\u002Fmiddleware\u002Fautoplacement","2.api\u002F6.middleware\u002F4.autoplacement",{"title":256,"path":257,"stem":258},"size","\u002Fapi\u002Fmiddleware\u002Fsize","2.api\u002F6.middleware\u002F5.size",{"title":260,"path":261,"stem":262},"inline","\u002Fapi\u002Fmiddleware\u002Finline","2.api\u002F6.middleware\u002F6.inline",{"title":264,"path":265,"stem":266},"arrow","\u002Fapi\u002Fmiddleware\u002Farrow","2.api\u002F6.middleware\u002F7.arrow",{"title":268,"path":269,"stem":270},"hide","\u002Fapi\u002Fmiddleware\u002Fhide","2.api\u002F6.middleware\u002F8.hide",{"id":272,"title":48,"body":273,"description":1667,"extension":1668,"links":1669,"meta":1670,"navigation":614,"path":49,"seo":1671,"stem":50,"__hash__":1672},"docs\u002F1.guide\u002F2.core-concepts\u002F4.tree-coordination-explained.md",{"type":274,"value":275,"toc":1647},"minimark",[276,280,316,323,326,331,340,350,379,381,385,388,393,408,467,478,485,499,840,1030,1037,1044,1131,1133,1137,1141,1157,1163,1167,1173,1230,1233,1240,1249,1386,1393,1395,1399,1410,1572,1576,1613,1615,1619,1643],[277,278,279],"p",{},"Coordinating nested and hierarchical floating components (like multi-level submenus, dropdowns inside dialogs, or cascading popovers) is notoriously difficult. If you try to coordinate them using DOM parent-child relationships, you quickly run into issues:",[281,282,283,300,306],"ul",{},[284,285,286,290,291,295,296,299],"li",{},[287,288,289],"strong",{},"Teleportation gaps."," Floating panels are frequently teleported to ",[292,293,294],"code",{},"\u003CTeleport to=\"body\">"," to avoid CSS overflow clipping. When portals move elements out of their original DOM hierarchy, standard DOM methods like ",[292,297,298],{},".contains()"," break across portal boundaries.",[284,301,302,305],{},[287,303,304],{},"Premature dismissal."," An outside-click listener on a parent modal or menu assumes a click inside a teleported child overlay was \"outside\" and abruptly closes the parent.",[284,307,308,311,312,315],{},[287,309,310],{},"Escape key collisions."," Pressing ",[292,313,314],{},"Escape"," can trigger all open overlay listeners simultaneously instead of closing only the active topmost child.",[277,317,318,319,322],{},"VFloat solves these challenges with the ",[287,320,321],{},"Unified Composite Node Architecture",". Every floating surface is a composite node with intrinsic hierarchy and spatial awareness. There is no separate tree coordinator class—a single tooltip ($N = 0$) and a deep menu hierarchy ($N > 0$) share the exact same data structure.",[324,325],"hr",{},[327,328,330],"h2",{"id":329},"the-unified-composite-node-n-0-vs-n-0","The Unified Composite Node ($N = 0$ vs $N > 0$)",[277,332,333,334,339],{},"Every floating surface is created with ",[335,336,337],"a",{"href":163},[292,338,162],{},". A node intrinsically tracks its parent, its children, and its open state:",[341,342,347],"pre",{"className":343,"code":345,"language":346},[344],"language-text","┌────────────────────────────────────────────────────────────────────────┐\n│                        COMPOSITE FLOATING NODE                         │\n├────────────────────────────────────────────────────────────────────────┤\n│ - Refs: anchorEl, floatingEl                                           │\n│ - Topology: parent (FloatingNode | null), children (Set\u003CFloatingNode>) │\n│ - Predicate: node.contains(target)                                     │\n└──────────────────┬──────────────────────────────────┬──────────────────┘\n                   │                                  │\n    If target is in local DOM           If target was teleported to \u003Cbody>\n                   │                                  │\n                   ▼                                  ▼\n         [Physical DOM Fast-Path]            [Check Open Children]\n         (el.contains(target))               (child.contains(target))\n","text",[292,348,345],{"__ignoreMap":349},"",[277,351,352,353,356,357,361,362,361,366,361,370,361,374,378],{},"Because hierarchy is built directly into ",[292,354,355],{},"FloatingNode",", companion composables (",[335,358,359],{"href":206},[292,360,205],{},", ",[335,363,364],{"href":210},[292,365,209],{},[335,367,368],{"href":194},[292,369,193],{},[335,371,372],{"href":202},[292,373,201],{},[335,375,376],{"href":223},[292,377,222],{},") interact with a uniform contract without branching on tree existence.",[324,380],{},[327,382,384],{"id":383},"_3-tier-parenting-resolution","3-Tier Parenting Resolution",[277,386,387],{},"VFloat resolves parent-child relationships through three ergonomic tiers:",[389,390,392],"h3",{"id":391},"_1-standalone-by-default-zero-accidental-adoption","1. Standalone by Default (Zero Accidental Adoption)",[277,394,395,396,399,400,403,404,407],{},"Most floating surfaces (tooltips, popovers, dropdowns, dialogs) are independent roots. By default (when ",[292,397,398],{},"parent"," is omitted or ",[292,401,402],{},"undefined","), a floating node is completely standalone (",[292,405,406],{},"parent.value === null","):",[341,409,413],{"className":410,"code":411,"language":412,"meta":349,"style":349},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Standalone by default: will never adopt or be adopted by other surfaces\nconst node = useFloatingNode({ anchorEl, floatingEl });\n","ts",[292,414,415,424],{"__ignoreMap":349},[416,417,420],"span",{"class":418,"line":419},"line",1,[416,421,423],{"class":422},"sHwdD","\u002F\u002F Standalone by default: will never adopt or be adopted by other surfaces\n",[416,425,427,431,435,439,443,446,449,452,455,458,461,464],{"class":418,"line":426},2,[416,428,430],{"class":429},"spNyl","const",[416,432,434],{"class":433},"sTEyZ"," node ",[416,436,438],{"class":437},"sMK4o","=",[416,440,442],{"class":441},"s2Zo4"," useFloatingNode",[416,444,445],{"class":433},"(",[416,447,448],{"class":437},"{",[416,450,451],{"class":433}," anchorEl",[416,453,454],{"class":437},",",[416,456,457],{"class":433}," floatingEl ",[416,459,460],{"class":437},"}",[416,462,463],{"class":433},")",[416,465,466],{"class":437},";\n",[277,468,469,470,473,474,477],{},"This guarantees that a tooltip in ",[292,471,472],{},"App.vue"," or a layout header will never accidentally adopt dropdowns or modals across your application. Passing ",[292,475,476],{},"parent: null"," explicitly achieves the same standalone behavior.",[389,479,481,482,463],{"id":480},"_2-opt-in-di-parent-auto","2. Opt-In DI (",[292,483,484],{},"parent: \"auto\"",[277,486,487,488,490,491,494,495,498],{},"In multi-component architectures, child components opt into discovering and linking to their nearest ancestor floating node by passing ",[292,489,484],{},". This leverages Vue's Dependency Injection (",[292,492,493],{},"provide"," \u002F ",[292,496,497],{},"inject",") without manual prop drilling:",[341,500,504],{"className":501,"code":502,"language":503,"meta":349,"style":349},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- RootMenu.vue -->\n\u003Cscript setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { useFloatingNode } from \"v-float\";\nimport SubMenu from \".\u002FSubMenu.vue\";\n\nconst anchorEl = ref\u003CHTMLElement | null>(null);\nconst floatingEl = ref\u003CHTMLElement | null>(null);\n\n\u002F\u002F Automatically provides rootNode to descendant components (provide defaults to true)\nconst rootNode = useFloatingNode({ anchorEl, floatingEl });\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cbutton ref=\"anchorEl\">Menu\u003C\u002Fbutton>\n  \u003Cdiv v-if=\"rootNode.open.value\" ref=\"floatingEl\">\n    \u003CSubMenu \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","vue",[292,505,506,511,539,567,589,609,616,652,681,686,692,720,730,735,745,776,809,821,831],{"__ignoreMap":349},[416,507,508],{"class":418,"line":419},[416,509,510],{"class":422},"\u003C!-- RootMenu.vue -->\n",[416,512,513,516,520,523,526,528,531,534,536],{"class":418,"line":426},[416,514,515],{"class":437},"\u003C",[416,517,519],{"class":518},"swJcz","script",[416,521,522],{"class":429}," setup",[416,524,525],{"class":429}," lang",[416,527,438],{"class":437},[416,529,530],{"class":437},"\"",[416,532,412],{"class":533},"sfazB",[416,535,530],{"class":437},[416,537,538],{"class":437},">\n",[416,540,542,546,549,552,555,558,561,563,565],{"class":418,"line":541},3,[416,543,545],{"class":544},"s7zQu","import",[416,547,548],{"class":437}," {",[416,550,551],{"class":433}," ref",[416,553,554],{"class":437}," }",[416,556,557],{"class":544}," from",[416,559,560],{"class":437}," \"",[416,562,503],{"class":533},[416,564,530],{"class":437},[416,566,466],{"class":437},[416,568,570,572,574,576,578,580,582,585,587],{"class":418,"line":569},4,[416,571,545],{"class":544},[416,573,548],{"class":437},[416,575,442],{"class":433},[416,577,554],{"class":437},[416,579,557],{"class":544},[416,581,560],{"class":437},[416,583,584],{"class":533},"v-float",[416,586,530],{"class":437},[416,588,466],{"class":437},[416,590,592,594,597,600,602,605,607],{"class":418,"line":591},5,[416,593,545],{"class":544},[416,595,596],{"class":433}," SubMenu ",[416,598,599],{"class":544},"from",[416,601,560],{"class":437},[416,603,604],{"class":533},".\u002FSubMenu.vue",[416,606,530],{"class":437},[416,608,466],{"class":437},[416,610,612],{"class":418,"line":611},6,[416,613,615],{"emptyLinePlaceholder":614},true,"\n",[416,617,619,621,624,626,628,630,634,637,640,643,645,648,650],{"class":418,"line":618},7,[416,620,430],{"class":429},[416,622,623],{"class":433}," anchorEl ",[416,625,438],{"class":437},[416,627,551],{"class":441},[416,629,515],{"class":437},[416,631,633],{"class":632},"sBMFI","HTMLElement",[416,635,636],{"class":437}," |",[416,638,639],{"class":632}," null",[416,641,642],{"class":437},">",[416,644,445],{"class":433},[416,646,647],{"class":437},"null",[416,649,463],{"class":433},[416,651,466],{"class":437},[416,653,655,657,659,661,663,665,667,669,671,673,675,677,679],{"class":418,"line":654},8,[416,656,430],{"class":429},[416,658,457],{"class":433},[416,660,438],{"class":437},[416,662,551],{"class":441},[416,664,515],{"class":437},[416,666,633],{"class":632},[416,668,636],{"class":437},[416,670,639],{"class":632},[416,672,642],{"class":437},[416,674,445],{"class":433},[416,676,647],{"class":437},[416,678,463],{"class":433},[416,680,466],{"class":437},[416,682,684],{"class":418,"line":683},9,[416,685,615],{"emptyLinePlaceholder":614},[416,687,689],{"class":418,"line":688},10,[416,690,691],{"class":422},"\u002F\u002F Automatically provides rootNode to descendant components (provide defaults to true)\n",[416,693,695,697,700,702,704,706,708,710,712,714,716,718],{"class":418,"line":694},11,[416,696,430],{"class":429},[416,698,699],{"class":433}," rootNode ",[416,701,438],{"class":437},[416,703,442],{"class":441},[416,705,445],{"class":433},[416,707,448],{"class":437},[416,709,451],{"class":433},[416,711,454],{"class":437},[416,713,457],{"class":433},[416,715,460],{"class":437},[416,717,463],{"class":433},[416,719,466],{"class":437},[416,721,723,726,728],{"class":418,"line":722},12,[416,724,725],{"class":437},"\u003C\u002F",[416,727,519],{"class":518},[416,729,538],{"class":437},[416,731,733],{"class":418,"line":732},13,[416,734,615],{"emptyLinePlaceholder":614},[416,736,738,740,743],{"class":418,"line":737},14,[416,739,515],{"class":437},[416,741,742],{"class":518},"template",[416,744,538],{"class":437},[416,746,748,751,754,756,758,760,763,765,767,770,772,774],{"class":418,"line":747},15,[416,749,750],{"class":437},"  \u003C",[416,752,753],{"class":518},"button",[416,755,551],{"class":429},[416,757,438],{"class":437},[416,759,530],{"class":437},[416,761,762],{"class":533},"anchorEl",[416,764,530],{"class":437},[416,766,642],{"class":437},[416,768,769],{"class":433},"Menu",[416,771,725],{"class":437},[416,773,753],{"class":518},[416,775,538],{"class":437},[416,777,779,781,784,787,789,791,794,796,798,800,802,805,807],{"class":418,"line":778},16,[416,780,750],{"class":437},[416,782,783],{"class":518},"div",[416,785,786],{"class":429}," v-if",[416,788,438],{"class":437},[416,790,530],{"class":437},[416,792,793],{"class":533},"rootNode.open.value",[416,795,530],{"class":437},[416,797,551],{"class":429},[416,799,438],{"class":437},[416,801,530],{"class":437},[416,803,804],{"class":533},"floatingEl",[416,806,530],{"class":437},[416,808,538],{"class":437},[416,810,812,815,818],{"class":418,"line":811},17,[416,813,814],{"class":437},"    \u003C",[416,816,817],{"class":518},"SubMenu",[416,819,820],{"class":437}," \u002F>\n",[416,822,824,827,829],{"class":418,"line":823},18,[416,825,826],{"class":437},"  \u003C\u002F",[416,828,783],{"class":518},[416,830,538],{"class":437},[416,832,834,836,838],{"class":418,"line":833},19,[416,835,725],{"class":437},[416,837,742],{"class":518},[416,839,538],{"class":437},[341,841,843],{"className":501,"code":842,"language":503,"meta":349,"style":349},"\u003C!-- SubMenu.vue -->\n\u003Cscript setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { useFloatingNode } from \"v-float\";\n\nconst anchorEl = ref\u003CHTMLElement | null>(null);\nconst floatingEl = ref\u003CHTMLElement | null>(null);\n\n\u002F\u002F Opt into DI parenting to link with RootMenu\nconst subNode = useFloatingNode({ anchorEl, floatingEl, parent: \"auto\" });\n\u003C\u002Fscript>\n",[292,844,845,850,870,890,910,914,942,970,974,979,1022],{"__ignoreMap":349},[416,846,847],{"class":418,"line":419},[416,848,849],{"class":422},"\u003C!-- SubMenu.vue -->\n",[416,851,852,854,856,858,860,862,864,866,868],{"class":418,"line":426},[416,853,515],{"class":437},[416,855,519],{"class":518},[416,857,522],{"class":429},[416,859,525],{"class":429},[416,861,438],{"class":437},[416,863,530],{"class":437},[416,865,412],{"class":533},[416,867,530],{"class":437},[416,869,538],{"class":437},[416,871,872,874,876,878,880,882,884,886,888],{"class":418,"line":541},[416,873,545],{"class":544},[416,875,548],{"class":437},[416,877,551],{"class":433},[416,879,554],{"class":437},[416,881,557],{"class":544},[416,883,560],{"class":437},[416,885,503],{"class":533},[416,887,530],{"class":437},[416,889,466],{"class":437},[416,891,892,894,896,898,900,902,904,906,908],{"class":418,"line":569},[416,893,545],{"class":544},[416,895,548],{"class":437},[416,897,442],{"class":433},[416,899,554],{"class":437},[416,901,557],{"class":544},[416,903,560],{"class":437},[416,905,584],{"class":533},[416,907,530],{"class":437},[416,909,466],{"class":437},[416,911,912],{"class":418,"line":591},[416,913,615],{"emptyLinePlaceholder":614},[416,915,916,918,920,922,924,926,928,930,932,934,936,938,940],{"class":418,"line":611},[416,917,430],{"class":429},[416,919,623],{"class":433},[416,921,438],{"class":437},[416,923,551],{"class":441},[416,925,515],{"class":437},[416,927,633],{"class":632},[416,929,636],{"class":437},[416,931,639],{"class":632},[416,933,642],{"class":437},[416,935,445],{"class":433},[416,937,647],{"class":437},[416,939,463],{"class":433},[416,941,466],{"class":437},[416,943,944,946,948,950,952,954,956,958,960,962,964,966,968],{"class":418,"line":618},[416,945,430],{"class":429},[416,947,457],{"class":433},[416,949,438],{"class":437},[416,951,551],{"class":441},[416,953,515],{"class":437},[416,955,633],{"class":632},[416,957,636],{"class":437},[416,959,639],{"class":632},[416,961,642],{"class":437},[416,963,445],{"class":433},[416,965,647],{"class":437},[416,967,463],{"class":433},[416,969,466],{"class":437},[416,971,972],{"class":418,"line":654},[416,973,615],{"emptyLinePlaceholder":614},[416,975,976],{"class":418,"line":683},[416,977,978],{"class":422},"\u002F\u002F Opt into DI parenting to link with RootMenu\n",[416,980,981,983,986,988,990,992,994,996,998,1001,1003,1006,1009,1011,1014,1016,1018,1020],{"class":418,"line":688},[416,982,430],{"class":429},[416,984,985],{"class":433}," subNode ",[416,987,438],{"class":437},[416,989,442],{"class":441},[416,991,445],{"class":433},[416,993,448],{"class":437},[416,995,451],{"class":433},[416,997,454],{"class":437},[416,999,1000],{"class":433}," floatingEl",[416,1002,454],{"class":437},[416,1004,1005],{"class":518}," parent",[416,1007,1008],{"class":437},":",[416,1010,560],{"class":437},[416,1012,1013],{"class":533},"auto",[416,1015,530],{"class":437},[416,1017,554],{"class":437},[416,1019,463],{"class":433},[416,1021,466],{"class":437},[416,1023,1024,1026,1028],{"class":418,"line":694},[416,1025,725],{"class":437},[416,1027,519],{"class":518},[416,1029,538],{"class":437},[389,1031,1033,1034,463],{"id":1032},"_3-explicit-reference-parent-rootnode","3. Explicit Reference (",[292,1035,1036],{},"parent: rootNode",[277,1038,1039,1040,1043],{},"For flat single-component ",[292,1041,1042],{},"\u003Cscript setup>"," scripts or explicit prop forwarding, pass the parent node directly:",[341,1045,1047],{"className":410,"code":1046,"language":412,"meta":349,"style":349},"const root = useFloatingNode({ anchorEl: rootBtn, floatingEl: rootMenu });\nconst sub = useFloatingNode({ anchorEl: subBtn, floatingEl: subMenu, parent: root });\n",[292,1048,1049,1086],{"__ignoreMap":349},[416,1050,1051,1053,1056,1058,1060,1062,1064,1066,1068,1071,1073,1075,1077,1080,1082,1084],{"class":418,"line":419},[416,1052,430],{"class":429},[416,1054,1055],{"class":433}," root ",[416,1057,438],{"class":437},[416,1059,442],{"class":441},[416,1061,445],{"class":433},[416,1063,448],{"class":437},[416,1065,451],{"class":518},[416,1067,1008],{"class":437},[416,1069,1070],{"class":433}," rootBtn",[416,1072,454],{"class":437},[416,1074,1000],{"class":518},[416,1076,1008],{"class":437},[416,1078,1079],{"class":433}," rootMenu ",[416,1081,460],{"class":437},[416,1083,463],{"class":433},[416,1085,466],{"class":437},[416,1087,1088,1090,1093,1095,1097,1099,1101,1103,1105,1108,1110,1112,1114,1117,1119,1121,1123,1125,1127,1129],{"class":418,"line":426},[416,1089,430],{"class":429},[416,1091,1092],{"class":433}," sub ",[416,1094,438],{"class":437},[416,1096,442],{"class":441},[416,1098,445],{"class":433},[416,1100,448],{"class":437},[416,1102,451],{"class":518},[416,1104,1008],{"class":437},[416,1106,1107],{"class":433}," subBtn",[416,1109,454],{"class":437},[416,1111,1000],{"class":518},[416,1113,1008],{"class":437},[416,1115,1116],{"class":433}," subMenu",[416,1118,454],{"class":437},[416,1120,1005],{"class":518},[416,1122,1008],{"class":437},[416,1124,1055],{"class":433},[416,1126,460],{"class":437},[416,1128,463],{"class":433},[416,1130,466],{"class":437},[324,1132],{},[327,1134,1136],{"id":1135},"what-composite-coordination-solves","What Composite Coordination Solves",[389,1138,1140],{"id":1139},"teleportation-safe-outside-clicks","Teleportation-Safe Outside Clicks",[277,1142,1143,1144,1147,1148,1152,1153,1156],{},"When a user clicks inside a child submenu teleported to ",[292,1145,1146],{},"\u003Cbody>",", the parent's ",[335,1149,1150],{"href":206},[292,1151,205],{}," handler calls ",[292,1154,1155],{},"node.contains(target)",".",[277,1158,1159,1162],{},[292,1160,1161],{},"node.contains"," first tests the fast-path physical DOM element. If the target is not in the local DOM, it recursively queries open child nodes. Because the child is linked in the composite hierarchy, the click is recognized as internal, keeping the parent open.",[389,1164,1166],{"id":1165},"deterministic-leaf-first-escape-protocol","Deterministic Leaf-First Escape Protocol",[277,1168,1169,1170,1172],{},"Rather than maintaining brittle global event registries, each composite node resolves ",[292,1171,314],{}," deterministically based on its local topology:",[1174,1175,1176,1213],"ol",{},[284,1177,1178,1179,1181,1182,1185,1186,1185,1188,1191,1192],{},"When ",[292,1180,314],{}," is pressed in ",[292,1183,1184],{},"Root"," → ",[292,1187,817],{},[292,1189,1190],{},"SubSubMenu",":\n",[281,1193,1194,1200,1204],{},[284,1195,1196,1199],{},[292,1197,1198],{},"RootMenu"," checks: has open children → bails out.",[284,1201,1202,1199],{},[292,1203,817],{},[284,1205,1206,1208,1209,1212],{},[292,1207,1190],{}," checks: ",[287,1210,1211],{},"no open children"," → closes!",[284,1214,1215,1216,1191,1218],{},"On a second press of ",[292,1217,314],{},[281,1219,1220,1225],{},[284,1221,1222,1224],{},[292,1223,1190],{}," is now closed.",[284,1226,1227,1229],{},[292,1228,817],{}," has no open children → closes!",[277,1231,1232],{},"This gives predictable LIFO (last-in, first-out) dismissal across any depth. When multiple independent floating surfaces are open on the page, Escape dismisses the focused surface first, or the most recently opened surface when focus is neutral, preventing unrelated overlays from intercepting keystrokes from each other.",[389,1234,1236,1237],{"id":1235},"cascading-teardown-with-nodetraverse","Cascading Teardown with ",[292,1238,1239],{},"node.traverse",[277,1241,1242,1243,1246,1247,1008],{},"Closing a parent node does not cascade on its own (closing a node only modifies that specific node's ",[292,1244,1245],{},"open"," ref). When parent teardown must close all open descendants, traverse the subtree bottom-up using ",[292,1248,1239],{},[341,1250,1252],{"className":410,"code":1251,"language":412,"meta":349,"style":349},"node.traverse(\n  (descendant, depth) => {\n    if (depth > 0 && descendant.open.value) {\n      descendant.open.value = false;\n    }\n  },\n  { order: \"bottom-up\" },\n);\n",[292,1253,1254,1267,1289,1328,1350,1355,1360,1380],{"__ignoreMap":349},[416,1255,1256,1259,1261,1264],{"class":418,"line":419},[416,1257,1258],{"class":433},"node",[416,1260,1156],{"class":437},[416,1262,1263],{"class":441},"traverse",[416,1265,1266],{"class":433},"(\n",[416,1268,1269,1272,1276,1278,1281,1283,1286],{"class":418,"line":426},[416,1270,1271],{"class":437},"  (",[416,1273,1275],{"class":1274},"sHdIc","descendant",[416,1277,454],{"class":437},[416,1279,1280],{"class":1274}," depth",[416,1282,463],{"class":437},[416,1284,1285],{"class":429}," =>",[416,1287,1288],{"class":437}," {\n",[416,1290,1291,1294,1297,1300,1303,1307,1310,1313,1315,1317,1319,1322,1325],{"class":418,"line":541},[416,1292,1293],{"class":544},"    if",[416,1295,1296],{"class":518}," (",[416,1298,1299],{"class":433},"depth",[416,1301,1302],{"class":437}," >",[416,1304,1306],{"class":1305},"sbssI"," 0",[416,1308,1309],{"class":437}," &&",[416,1311,1312],{"class":433}," descendant",[416,1314,1156],{"class":437},[416,1316,1245],{"class":433},[416,1318,1156],{"class":437},[416,1320,1321],{"class":433},"value",[416,1323,1324],{"class":518},") ",[416,1326,1327],{"class":437},"{\n",[416,1329,1330,1333,1335,1337,1339,1341,1344,1348],{"class":418,"line":569},[416,1331,1332],{"class":433},"      descendant",[416,1334,1156],{"class":437},[416,1336,1245],{"class":433},[416,1338,1156],{"class":437},[416,1340,1321],{"class":433},[416,1342,1343],{"class":437}," =",[416,1345,1347],{"class":1346},"sfNiH"," false",[416,1349,466],{"class":437},[416,1351,1352],{"class":418,"line":591},[416,1353,1354],{"class":437},"    }\n",[416,1356,1357],{"class":418,"line":611},[416,1358,1359],{"class":437},"  },\n",[416,1361,1362,1365,1368,1370,1372,1375,1377],{"class":418,"line":618},[416,1363,1364],{"class":437},"  {",[416,1366,1367],{"class":518}," order",[416,1369,1008],{"class":437},[416,1371,560],{"class":437},[416,1373,1374],{"class":533},"bottom-up",[416,1376,530],{"class":437},[416,1378,1379],{"class":437}," },\n",[416,1381,1382,1384],{"class":418,"line":654},[416,1383,463],{"class":433},[416,1385,466],{"class":437},[277,1387,1388,1389,1392],{},"Walking ",[292,1390,1391],{},"'bottom-up'"," closes open descendants from the innermost child outward so no orphaned submenus remain visible.",[324,1394],{},[327,1396,1398],{"id":1397},"contextual-teleportation-dom-first","Contextual Teleportation (DOM-First)",[277,1400,1401,1402,1405,1406,1409],{},"Rather than blindly teleporting every floating surface to ",[292,1403,1404],{},"document.body",", prioritize teleporting to the ",[287,1407,1408],{},"nearest contextual container"," (such as an enclosing Dialog Root or Popover boundary):",[341,1411,1415],{"className":1412,"code":1413,"language":1414,"meta":349,"style":349},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- DOM Hierarchy preserved inside Dialog Root -->\n\u003Cdiv class=\"dialog-root\" data-portal-target>\n  \u003Cdiv class=\"dialog-content\">\n    \u003Cbutton ref=\"dropdownTrigger\">Country\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Teleported here (inside dialog root, NOT to \u003Cbody>) -->\n  \u003Cdiv class=\"dropdown-content\">\n    \u003Cdiv class=\"option\">Canada\u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n","html",[292,1416,1417,1422,1445,1464,1492,1500,1504,1509,1528,1556,1564],{"__ignoreMap":349},[416,1418,1419],{"class":418,"line":419},[416,1420,1421],{"class":422},"\u003C!-- DOM Hierarchy preserved inside Dialog Root -->\n",[416,1423,1424,1426,1428,1431,1433,1435,1438,1440,1443],{"class":418,"line":426},[416,1425,515],{"class":437},[416,1427,783],{"class":518},[416,1429,1430],{"class":429}," class",[416,1432,438],{"class":437},[416,1434,530],{"class":437},[416,1436,1437],{"class":533},"dialog-root",[416,1439,530],{"class":437},[416,1441,1442],{"class":429}," data-portal-target",[416,1444,538],{"class":437},[416,1446,1447,1449,1451,1453,1455,1457,1460,1462],{"class":418,"line":541},[416,1448,750],{"class":437},[416,1450,783],{"class":518},[416,1452,1430],{"class":429},[416,1454,438],{"class":437},[416,1456,530],{"class":437},[416,1458,1459],{"class":533},"dialog-content",[416,1461,530],{"class":437},[416,1463,538],{"class":437},[416,1465,1466,1468,1470,1472,1474,1476,1479,1481,1483,1486,1488,1490],{"class":418,"line":569},[416,1467,814],{"class":437},[416,1469,753],{"class":518},[416,1471,551],{"class":429},[416,1473,438],{"class":437},[416,1475,530],{"class":437},[416,1477,1478],{"class":533},"dropdownTrigger",[416,1480,530],{"class":437},[416,1482,642],{"class":437},[416,1484,1485],{"class":433},"Country",[416,1487,725],{"class":437},[416,1489,753],{"class":518},[416,1491,538],{"class":437},[416,1493,1494,1496,1498],{"class":418,"line":591},[416,1495,826],{"class":437},[416,1497,783],{"class":518},[416,1499,538],{"class":437},[416,1501,1502],{"class":418,"line":611},[416,1503,615],{"emptyLinePlaceholder":614},[416,1505,1506],{"class":418,"line":618},[416,1507,1508],{"class":422},"  \u003C!-- Teleported here (inside dialog root, NOT to \u003Cbody>) -->\n",[416,1510,1511,1513,1515,1517,1519,1521,1524,1526],{"class":418,"line":654},[416,1512,750],{"class":437},[416,1514,783],{"class":518},[416,1516,1430],{"class":429},[416,1518,438],{"class":437},[416,1520,530],{"class":437},[416,1522,1523],{"class":533},"dropdown-content",[416,1525,530],{"class":437},[416,1527,538],{"class":437},[416,1529,1530,1532,1534,1536,1538,1540,1543,1545,1547,1550,1552,1554],{"class":418,"line":683},[416,1531,814],{"class":437},[416,1533,783],{"class":518},[416,1535,1430],{"class":429},[416,1537,438],{"class":437},[416,1539,530],{"class":437},[416,1541,1542],{"class":533},"option",[416,1544,530],{"class":437},[416,1546,642],{"class":437},[416,1548,1549],{"class":433},"Canada",[416,1551,725],{"class":437},[416,1553,783],{"class":518},[416,1555,538],{"class":437},[416,1557,1558,1560,1562],{"class":418,"line":688},[416,1559,826],{"class":437},[416,1561,783],{"class":518},[416,1563,538],{"class":437},[416,1565,1566,1568,1570],{"class":418,"line":694},[416,1567,725],{"class":437},[416,1569,783],{"class":518},[416,1571,538],{"class":437},[389,1573,1575],{"id":1574},"key-benefits","Key Benefits:",[1174,1577,1578,1592,1603],{},[284,1579,1580,1583,1584,1587,1588,1591],{},[287,1581,1582],{},"Physical DOM Ancestry Preserved:"," Standard ",[292,1585,1586],{},"dialogRoot.contains(target)"," naturally returns ",[292,1589,1590],{},"true"," for nested controls.",[284,1593,1594,1597,1598,1602],{},[287,1595,1596],{},"Native Focus Traps Remain Intact:"," ",[335,1599,1600],{"href":202},[292,1601,201],{}," on the modal requires zero custom exclusion allowlists for nested controls.",[284,1604,1605,1608,1609,1612],{},[287,1606,1607],{},"Top-Layer Alignment:"," Integrates seamlessly with native HTML ",[292,1610,1611],{},"\u003Cdialog>"," and Popover API.",[324,1614],{},[327,1616,1618],{"id":1617},"where-to-go-next","Where to Go Next",[281,1620,1621,1627,1633,1638],{},[284,1622,1623,1624,1156],{},"Read the tutorial on ",[335,1625,1626],{"href":71},"Build Nested Menus",[284,1628,1629,1630,1156],{},"Read the ",[335,1631,1632],{"href":163},"useFloatingNode API Reference",[284,1634,1629,1635,1156],{},[335,1636,1637],{"href":223},"useRovingFocus API Reference",[284,1639,1629,1640,1156],{},[335,1641,1642],{"href":153},"Types & Interfaces Reference",[1644,1645,1646],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":349,"searchDepth":426,"depth":426,"links":1648},[1649,1650,1657,1663,1666],{"id":329,"depth":426,"text":330},{"id":383,"depth":426,"text":384,"children":1651},[1652,1653,1655],{"id":391,"depth":541,"text":392},{"id":480,"depth":541,"text":1654},"2. Opt-In DI (parent: \"auto\")",{"id":1032,"depth":541,"text":1656},"3. Explicit Reference (parent: rootNode)",{"id":1135,"depth":426,"text":1136,"children":1658},[1659,1660,1661],{"id":1139,"depth":541,"text":1140},{"id":1165,"depth":541,"text":1166},{"id":1235,"depth":541,"text":1662},"Cascading Teardown with node.traverse",{"id":1397,"depth":426,"text":1398,"children":1664},[1665],{"id":1574,"depth":541,"text":1575},{"id":1617,"depth":426,"text":1618},"Understand how VFloat coordinates nested overlays, submenus, and composite floating surface hierarchies.","md",null,{},{"title":48,"description":1667},"ZDMroiQhUjPxLNuM1AzeUbQM9QPhGC22vOX6pzaBUGk",[1674,1676],{"title":44,"path":45,"stem":46,"description":1675,"children":-1},"Learn how VFloat opens, closes, and coordinates floating surfaces.",{"title":58,"path":59,"stem":60,"description":1677,"children":-1},"Build accessible tooltips with the right interaction and dismissal behavior.",1791046167564]