Build · New
Navigation Menu
Website navigation with dropdown panels: a few destinations each with an icon and one short line, and at most one featured card.
Preview
Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.
Installation
SoonInstalling from the registry opens at launch. Until then the command below is what it will be.
npx shadcn@latest add @ritla/navigation-menuDependencies it brings: @base-ui/react, @phosphor-icons/react
Usage
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuLinks,
NavigationMenuList,
NavigationMenuPanelLink,
NavigationMenuTrigger,
} from "@/components/ui/navigation-menu";<NavigationMenu aria-label="Main">
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Products</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLinks>
<NavigationMenuPanelLink href="/payments" icon={CreditCardIcon} title="Payments" description="Accept cards, Apple Pay and CliQ." />
</NavigationMenuLinks>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="/pricing">Pricing</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>Examples
One column, and the current page
columns={1} for short panels, with no featured card. The plain link for the current page takes active (aria-current="page").
API reference
NavigationMenu
| Prop | Type | Default | Description |
|---|---|---|---|
aria-label | string | The navigation's name, when the page has more than one nav. | |
delay / closeDelay | number | 50 / 50 | The wait before opening and closing on hover (ms). |
value / onValueChange | string | null | The open panel, to control it from code. |
NavigationMenuTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | Figma's Label. The caret is added for you. |
NavigationMenuLink
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | A plain link in the row, with no panel. | |
active | boolean | The current page. | |
render | ReactElement | Your framework's link, e.g. Next's <Link />. |
NavigationMenuLinks
| Prop | Type | Default | Description |
|---|---|---|---|
columns | 1 | 2 | 2 | Link columns, 220px each. |
NavigationMenuPanelLink
| Prop | Type | Default | Description |
|---|---|---|---|
icon | IconComponent | An icon in a brand/faint box. | |
title | ReactNode | Figma's Title: the destination. | |
description | ReactNode | Figma's Description: one short line. | |
href / render | string / ReactElement | The link. |
NavigationMenuFeatured
| Prop | Type | Default | Description |
|---|---|---|---|
tag | ReactNode | The small tag at the top ("New"). | |
title / description | ReactNode | Title and description. | |
linkLabel | ReactNode | The call to action at the bottom; the whole card is the link. |
Accessibility
Keyboard
Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.
| Key | Action |
|---|---|
| Tab | Along the row; from an open trigger through its panel's links, then on to the next item. |
| EnterSpace | On a trigger: opens or closes its panel. |
| ArrowRightArrowLeft | Along the row; in Arabic, ArrowLeft goes to the next. |
| Esc | Closes the panel and returns focus to its trigger. |
ARIA
- A
<nav>with a list (ul) of items; each trigger hasaria-expandedandaria-controls. - Panel links are real links, and the featured card is one link.
- Triggers are 32px tall with a 48px hit area vertically only.
- On phones: a menu button that opens a Drawer with the same groups in an Accordion.
Arabic and RTL notes
Mirrors
- The first item sits on the right, and the panel starts at the row's right edge.
- Panel links read from the right, and the featured card sits on the left.
Does not mirror
- The trigger's caret points down and turns when open; it doesn't mirror.
- The links' icons don't mirror.
- Numerals
- Numbers in descriptions follow the numerals setting (
toNumeralsfor fixed strings). - Arabic typography
- Triggers
label-14Medium, link titleslabel-14Semibold, descriptionslabel-12, the card titlelabel-16Semibold. - Mixed-direction text
- Latin product names (Apple Pay, iOS) inside an Arabic description keep their order. The panel carries the page's direction and language into the portal.