Mega Menu
A navigation menu with one shared panel. Moving between triggers slides the content in the direction you moved while the panel resizes to fit.
Default
The panel is part of the bar and grows downward. Move across the triggers to see the direction follow you.
Dropdown
A floating panel that opens under the trigger you are on and slides sideways to the next one. Each item sets its own width.
Cards
Icon cards beside image cards. The panel lines up with its trigger.
Notch
MegaMenuIndicator slides a notch under the active trigger, so the panel points at where it came from.
Centered navigation
The navigation sits in the middle of the bar, whatever the widths of the logo and the buttons. Three columns of 1fr, auto and 1fr do it.
Underlay
A mega menu for the sections and a Menu button for everything else, with sheet-variant="underlay". At desktop width the button opens a panel that stays underneath while the page slides away from it; below that it is a sheet. The page layer follows the menu by sheet-name, so it can live in a layout while the menu sits in the header.
Click to open
open-on="click" holds the panel open until you click again, press Escape or click away. A single trigger is enough, and breakpoint="none" skips the mobile layout.
Anatomy
Import all parts and piece them together.
<script setup>
import {
MegaMenu,
MegaMenuColumn,
MegaMenuContent,
MegaMenuIndicator,
MegaMenuItem,
MegaMenuLink,
MegaMenuList,
MegaMenuReveal,
MegaMenuSheet,
MegaMenuToggle,
MegaMenuTrigger,
MegaMenuViewport,
} from "@/components/ui/mega-menu";
</script>
<template>
<MegaMenu>
<MegaMenuList>
<MegaMenuItem>
<MegaMenuTrigger />
<MegaMenuContent>
<MegaMenuColumn>
<MegaMenuLink />
<MegaMenuReveal />
</MegaMenuColumn>
</MegaMenuContent>
</MegaMenuItem>
<MegaMenuItem>
<MegaMenuLink />
</MegaMenuItem>
<MegaMenuIndicator />
</MegaMenuList>
<MegaMenuToggle />
<MegaMenuViewport />
<MegaMenuSheet />
</MegaMenu>
</template>API Reference
MegaMenu
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | — | Value of the open item. Supports v-model. Empty when closed. |
defaultValue | string | — | Item that starts open. |
breakpoint | "none" | "md" | "lg" | "md" | Width of the menu itself, not the window, below which it becomes a toggle and an accordion. md is 768px, lg is 1024px, none never switches. |
openOn | "hover" | "click" | "hover" | click opens on press and stays open until you click again, press Escape or click away. |
stagger | boolean | true | Reveal each link, label and tinted column on its own beat when a panel opens. |
delayDuration | number | 120 | Milliseconds the pointer rests on a trigger before the first panel opens. |
skipDelayDuration | number | 300 | Window after a panel closes during which the next one opens without a delay. |
sheetSide | "right" | "left" | "top" | "bottom" | "right" | Edge the mobile sheet slides in from. |
sheetVariant | "straight" | "floating" | "glass" | "full" | "underlay" | "straight" | Look of the menu sheet. See Header Menu for what each one is. underlay shows the menu button at every width: at desktop width the panel stays in place and the page slides away from it, below that it is a sheet. Put what it holds in MegaMenuSheet. |
sheetName | string | — | Share the sheet's state under a name. A HeaderMenuPage with the same name, anywhere in the layout, follows it. |
headerHeight | string | "3.5rem" | Height of the header the mobile sheet hangs under, any CSS length. The sheet starts below it, so the header and its button stay visible. |
sheetContainer | string | HTMLElement | — | Keep the sheet inside this element instead of on the page, for a menu shown in a frame. |
| Slot | Description |
|---|---|
default | The bar. Receives { mode } with "desktop" or "mobile". |
MegaMenuList
| Prop | Type | Default | Description |
|---|---|---|---|
mobileClass | string | — | Classes for the list inside the mobile sheet. |
MegaMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | auto | Identifies the item. Set it on items that carry a MegaMenuContent. |
MegaMenuTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
hideIcon | boolean | false | Hide the chevron. |
MegaMenuContent
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | — | Layout and width of the panel on desktop. Set an explicit width: the viewport sizes itself to this element. |
mobileClass | string | — | Layout of the same content inside its mobile accordion section. |
MegaMenuViewport
| Prop | Type | Default | Description |
|---|---|---|---|
placement | "inline" | "floating" | "floating" | inline is part of the host card and grows it downward. floating is a panel under the menu. |
align | "trigger-start" | "trigger-center" | "trigger-end" | "start" | "center" | "stretch" | "trigger-start" | Where a floating panel sits. trigger-start lines its left edge up with the active trigger and flips to the right edge when it would be cut off by the menu. trigger-center and trigger-end follow the trigger as well. start and center use the menu's own edge or middle, stretch fills its width. |
MegaMenuColumn
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Small heading above the column. |
labelClass | string | — | Classes for the heading. |
tinted | boolean | false | Fill the column with --mm-tint, which defaults to the muted colour. |
MegaMenuLink
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "nav" | "plain" | inferred | nav looks like a trigger. plain carries no styling. Top-level links default to nav, links inside a panel to plain. |
active | boolean | false | Marks the current page. |
as | string | Component | "a" | Element or component to render, for example the resolved NuxtLink component. |
| Event | Description |
|---|---|
select | Fires when the link is activated. Receives the event. |
MegaMenuToggle
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | A visible label next to the icon, for example Menu. |
barClass | string | — | Replaces the bar colour. |
MegaMenuSheet
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | — | Classes for the panel. |
bodyClass | string | — | Classes for the scrolling area that holds the content. |
| Slot | Description |
|---|---|
default | What the menu button opens. Receives { underlay }: true while it is the panel under a sliding page, false while it is an ordinary sheet. While it is mounted the mobile accordion is not drawn. |
MegaMenuReveal
| Prop | Type | Default | Description |
|---|---|---|---|
as | string | "div" | Wrap any block of a panel so it joins the staggered reveal. |
MegaMenuIndicator
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | — | Position of the notch. Set top to the gap between the bar and the panel. |
arrowClass | string | — | Shape and colours of the notch. |
Accessibility
Keyboard shortcuts and ARIA behavior.
| Shortcut | Description |
|---|---|
| Tab | Move through the triggers and links. |
| Enter | Open or close the focused trigger's panel. |
| Space | Open or close the focused trigger's panel. |
| ↓ | From an open trigger, move into its panel. |
| ← + → | Move between triggers. |
| Esc | Close the panel and return focus to its trigger. |
- Built on the reka-ui NavigationMenu, so triggers carry aria-expanded and panels are labelled by their trigger.
- Below the breakpoint the menu opens in a Header Menu sheet: it traps focus, closes on Escape, a swipe or a tap outside, and the toggle morphs into a cross. Each section header is a button and closed sections are inert.
- Animations are replaced by instant changes under prefers-reduced-motion.