Environment
- Operating system: Linux 5.0 (Macintosh; Intel Mac OS X 10_15_7) – Chrome 147.0.0.0
- CPU: Intel Core i9-9880H @ 2.30GHz (8 cores)
- Node.js: v22.22.0
- Nuxt CLI: 3.34.0
- Package manager: pnpm 8.15.6
- Nuxt: 4.4.2
- Nitro: 2.13.3
- Builder: Vite 7.3.2
- Config flags: compatibilityDate, devtools, modules
- Modules: reka-ui/nuxt 2.9.6
Link to minimal reproduction
https://stackblitz.com/edit/github-whqv4pfb?file=app%2Fcomponents%2FNavigation.vue
Steps to reproduce
- Open Dropdown 1 (hover or click the trigger)
- Click the blue area inside the content (not the red link)
- Actual: Dropdown 1 closes immediately
- Expected: Dropdown 1 stays open (clicking inside content should not dismiss it)
- Now open Dropdown 2 and click its blue area, it correctly stays open
Describe the bug
When unmountOnHide is false, NavigationMenuContent passes force-mount to Presence, which keeps all NavigationMenuContentImpl instances mounted, including closed ones. Each instance wraps a DismissableLayer that registers itself in the global layers set on mount and only deregisters on unmount.
When the user clicks anywhere, every mounted DismissableLayer evaluates the click. Closed dropdowns have pointer-events: none, so the click is never detected as "inside" their layer. This causes each closed dropdown's DismissableLayer to fire pointerDownOutside → interactOutside → dismiss.
The handleDismiss function in NavigationMenuContentImpl unconditionally dispatches EVENT_ROOT_CONTENT_DISMISS, which calls menuContext.onItemDismiss(), resetting modelValue to "" and closing whichever dropdown was actually open.
The last dropdown appears unaffected because there are no closed-but-mounted DismissableLayer instances after it in the set to erroneously trigger a dismiss.
Suggested fix
Guard handleDismiss in NavigationMenuContentImpl so that only the currently active content can trigger dismissal:
function handleDismiss() {
if (menuContext.modelValue.value !== itemContext.value) return
// ... existing dismiss logic
}
This ensures closed (but still mounted) content panels ignore the dismiss event entirely.
Environment
- Operating system: Linux 5.0 (Macintosh; Intel Mac OS X 10_15_7) – Chrome 147.0.0.0 - CPU: Intel Core i9-9880H @ 2.30GHz (8 cores) - Node.js: v22.22.0 - Nuxt CLI: 3.34.0 - Package manager: pnpm 8.15.6 - Nuxt: 4.4.2 - Nitro: 2.13.3 - Builder: Vite 7.3.2 - Config flags: compatibilityDate, devtools, modules - Modules: reka-ui/nuxt 2.9.6Link to minimal reproduction
https://stackblitz.com/edit/github-whqv4pfb?file=app%2Fcomponents%2FNavigation.vue
Steps to reproduce
Describe the bug
When
unmountOnHideisfalse,NavigationMenuContentpassesforce-mounttoPresence, which keeps allNavigationMenuContentImplinstances mounted, including closed ones. Each instance wraps aDismissableLayerthat registers itself in the global layers set on mount and only deregisters on unmount.When the user clicks anywhere, every mounted
DismissableLayerevaluates the click. Closed dropdowns havepointer-events: none, so the click is never detected as "inside" their layer. This causes each closed dropdown'sDismissableLayerto firepointerDownOutside→interactOutside→dismiss.The
handleDismissfunction inNavigationMenuContentImplunconditionally dispatchesEVENT_ROOT_CONTENT_DISMISS, which callsmenuContext.onItemDismiss(), resettingmodelValueto""and closing whichever dropdown was actually open.The last dropdown appears unaffected because there are no closed-but-mounted
DismissableLayerinstances after it in the set to erroneously trigger a dismiss.Suggested fix
Guard
handleDismissinNavigationMenuContentImplso that only the currently active content can trigger dismissal:This ensures closed (but still mounted) content panels ignore the dismiss event entirely.