Toggle Sidebar B
AppearanceLight & dark mode D

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.

Dark previewReplay previewOpen in new tab

Cards

Icon cards beside image cards. The panel lines up with its trigger.

Dark previewReplay previewOpen in new tab

Notch

MegaMenuIndicator slides a notch under the active trigger, so the panel points at where it came from.

Dark previewReplay previewOpen in new tab

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.

Dark previewReplay previewOpen in new tab

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.

Dark previewReplay previewOpen in new tab

Fixed Underlay Navigation

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.

Dark previewReplay previewOpen in new tab

Anatomy

Import all parts and piece them together.

vue
<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

PropTypeDefaultDescription
modelValuestring—Value of the open item. Supports v-model. Empty when closed.
defaultValuestring—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.
staggerbooleantrueReveal each link, label and tinted column on its own beat when a panel opens.
delayDurationnumber120Milliseconds the pointer rests on a trigger before the first panel opens.
skipDelayDurationnumber300Window 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.
sheetNamestring—Share the sheet's state under a name. A HeaderMenuPage with the same name, anywhere in the layout, follows it.
headerHeightstring"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.
sheetContainerstring | HTMLElement—Keep the sheet inside this element instead of on the page, for a menu shown in a frame.
SlotDescription
defaultThe bar. Receives { mode } with "desktop" or "mobile".

MegaMenuList

PropTypeDefaultDescription
mobileClassstring—Classes for the list inside the mobile sheet.

MegaMenuItem

PropTypeDefaultDescription
valuestringautoIdentifies the item. Set it on items that carry a MegaMenuContent.

MegaMenuTrigger

PropTypeDefaultDescription
hideIconbooleanfalseHide the chevron.

MegaMenuContent

PropTypeDefaultDescription
classstring—Layout and width of the panel on desktop. Set an explicit width: the viewport sizes itself to this element.
mobileClassstring—Layout of the same content inside its mobile accordion section.

MegaMenuViewport

PropTypeDefaultDescription
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

PropTypeDefaultDescription
labelstring—Small heading above the column.
labelClassstring—Classes for the heading.
tintedbooleanfalseFill the column with --mm-tint, which defaults to the muted colour.

MegaMenuLink

PropTypeDefaultDescription
variant"nav" | "plain"inferrednav looks like a trigger. plain carries no styling. Top-level links default to nav, links inside a panel to plain.
activebooleanfalseMarks the current page.
asstring | Component"a"Element or component to render, for example the resolved NuxtLink component.
EventDescription
selectFires when the link is activated. Receives the event.

MegaMenuToggle

PropTypeDefaultDescription
textstring—A visible label next to the icon, for example Menu.
barClassstring—Replaces the bar colour.

MegaMenuSheet

PropTypeDefaultDescription
classstring—Classes for the panel.
bodyClassstring—Classes for the scrolling area that holds the content.
SlotDescription
defaultWhat 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

PropTypeDefaultDescription
asstring"div"Wrap any block of a panel so it joins the staggered reveal.

MegaMenuIndicator

PropTypeDefaultDescription
classstring—Position of the notch. Set top to the gap between the bar and the panel.
arrowClassstring—Shape and colours of the notch.

Accessibility

Keyboard shortcuts and ARIA behavior.

Shortcut Description
TabMove through the triggers and links.
EnterOpen or close the focused trigger's panel.
SpaceOpen or close the focused trigger's panel.
↓From an open trigger, move into its panel.
← + →Move between triggers.
EscClose 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.