NavigationMenu

A site's top navigation: links and buttons that reveal panels of links, from a short list to a full-width mega menu.

BetaSource

Import

import { NavigationMenu } from "@meridui/react";

Anatomy

<NavigationMenu.Root>
  <NavigationMenu.List>
    <NavigationMenu.Item value="products">
      <NavigationMenu.Trigger />
      <NavigationMenu.Content>
        <NavigationMenu.Link />
      </NavigationMenu.Content>
    </NavigationMenu.Item>
    <NavigationMenu.Item>
      <NavigationMenu.Link />
    </NavigationMenu.Item>
  </NavigationMenu.List>
</NavigationMenu.Root>
  • Root is the <nav> landmark and holds which panel is open (one at a time).
  • List and Item are the <ul> and <li> of the bar.
  • Trigger is a disclosure <button>; Content is its panel of links. fullWidth spans the bar for a mega menu.
  • Link is an <a>, directly in an Item (a top-level link) or inside Content. description adds a second line.

Examples

asChild renders your router's link with the same styling and behaviour; active sets aria-current="page".

import NextLink from "next/link";

<NavigationMenu.Link asChild active={pathname === "/pricing"}>
  <NextLink href="/pricing">Pricing</NextLink>
</NavigationMenu.Link>

Mega menu

Pass fullWidth to Content: the panel spans the whole bar and lays links out in a responsive grid. Below 640px every panel spans the bar.

API reference

Root

Accepts every <nav> attribute.

PropTypeDefaultDescription
valuestring–Controlled open item ("" when none).
defaultValuestring""Initially open item when uncontrolled.
onValueChange(value: string) => void–Called with the open item value.
openDelaynumber150Hover delay before a panel opens, in ms. Clicks and keys open at once.
closeDelaynumber250Delay before a panel closes after the pointer leaves, in ms.
aria-labelstring"Main"Accessible name of the navigation landmark.
refRef<HTMLElement>–Forwarded ref to the <nav>.

Item

PropTypeDefaultDescription
valuestring–Unique value; needed for controlled use. Defaults to a generated id.

Trigger, Content

Trigger accepts every <button> attribute; Content every <div> attribute.

PropTypeDefaultDescription
Content fullWidthbooleanfalseSpan the full width of the bar (a mega menu).

Accepts every <a> attribute.

PropTypeDefaultDescription
activebooleanfalseMarks the current page (aria-current="page").
descriptionstring–Second line under the label, for links inside a panel.
asChildbooleanfalseRender the single child element (a router link) instead of an <a>.
refRef<HTMLAnchorElement>–Forwarded ref.

Styling

ClassElement
.mrd-navmenuRoot
.mrd-navmenu__list, .mrd-navmenu__itemList and Item
.mrd-navmenu__trigger, .mrd-navmenu__chevronTrigger and its icon
.mrd-navmenu__contentContent
.mrd-navmenu__link, .mrd-navmenu__link-title, .mrd-navmenu__link-descriptionLink parts
AttributeOnValues
data-stateRoot, Item, Trigger, Contentopen, closed
data-fullContentpresent with fullWidth
data-activeLinkpresent when active

Accessibility

Follows the WAI-ARIA Disclosure navigation menu example rather than role="menubar": site navigation is a list of links, and every trigger and link stays in the Tab order. Panels stay in the DOM while closed (hidden), so their links are crawlable. Focus leaving the nav, Escape or an outside press close the open panel.

KeyAction
EnterSpaceOn a trigger: open or close its panel.
ArrowDownOn a trigger: open and focus the first link. In a panel: next link.
ArrowUpIn a panel: previous link.
ArrowRightArrowLeftNext / previous trigger or top-level link (mirrored in RTL).
HomeEndFirst / last trigger or top-level link.
EscapeClose the panel and return focus to its trigger.
TabMove through triggers and links in order.

Guidelines

Do

Keep top-level labels short and put the most-visited destinations first.

Avoid

Use NavigationMenu for app commands. Actions belong in a DropdownMenu or Toolbar.