Navigation menu
Rich hover-menu for site-level nav (marketing / docs sections). Radix-powered with an animated viewport that resizes to fit the current panel. Each trigger is h-9, rounded-md; hover/open use bg-accent + accent-foreground; the viewport uses shadow-sm.
Anatomy
- 1NavigationMenu (root)
The root that owns the viewport container. Renders the trigger list and the shared viewport below.
- 2NavigationMenuList
Horizontal list of menu items. gap-1 between triggers.
- 3NavigationMenuTrigger
One label in the top bar. h-9 rounded-md, hover/open bg-accent + accent-foreground. Optional trailing CaretDown that rotates on open.
- 4NavigationMenuLink
A plain link that doesn't open a panel — use inside a NavigationMenuItem to represent a direct destination.
- 5NavigationMenuContent
The panel that lives inside the shared viewport when a trigger opens. Free-form layout: single column, 2-column grid, featured card, etc.
- 6NavigationMenuViewport
The shared floating surface (rounded-md, border, bg-popover, shadow-sm) that all panels render into. Auto-sizes to the active content.
- 7NavigationMenuIndicator
Optional arrow above the viewport that follows the active trigger.
Content layouts
The viewport is a blank surface — the panel decides the layout. Five canonical shapes from the playground: Featured card, 2-column grid, List with title + description, Simple list, and List with icons.
<NavigationMenuContent>
<ul className="grid gap-3 p-4 md:w-[500px] md:grid-cols-[.75fr_1fr]">
<li className="row-span-3">
<a href="/" className="flex h-full flex-col justify-end rounded-md bg-muted/50 p-6 no-underline outline-none">
<div className="text-lg font-medium">shadcn/ui</div>
<p className="mt-2 text-sm text-muted-foreground">Beautifully designed components built with Tailwind CSS.</p>
</a>
</li>
<ListRow title="Introduction" desc="Re-usable components built using Radix UI and Tailwind CSS." />
<ListRow title="Installation" desc="How to install dependencies and structure your app." />
<ListRow title="Typography" desc="Styles for headings, paragraphs, lists, etc." />
</ul>
</NavigationMenuContent><NavigationMenuContent>
<ul className="grid gap-3 p-4 md:w-[520px] md:grid-cols-2">
{items.map((c) => <ListRow key={c.title} title={c.title} desc={c.desc} />)}
</ul>
</NavigationMenuContent><NavigationMenuContent>
<ul className="grid w-80 gap-1 p-2">
{items.map((it) => <ListRow key={it.title} title={it.title} desc={it.desc} />)}
</ul>
</NavigationMenuContent><NavigationMenuContent>
<ul className="grid w-64 gap-1 p-2">
<ListRow title="Components" />
<ListRow title="Documentation" />
<ListRow title="Blocks" />
</ul>
</NavigationMenuContent><NavigationMenuContent>
<ul className="grid w-64 gap-1 p-2">
{items.map((it) => (
<li key={it.title}>
<NavigationMenuLink href="#" className="…flex items-center gap-2…">
<it.icon weight="light" className="size-4 text-muted-foreground" />
{it.title}
</NavigationMenuLink>
</li>
))}
</ul>
</NavigationMenuContent>States
Trigger states: Default, Hover (bg-accent + accent-foreground), Open (bg-accent + accent-foreground + CaretDown rotated 180°), Active (bg-accent when marked as current), Disabled (opacity-50, pointer-events-none).
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink className={navigationMenuTriggerStyle()}>Default</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink className={cn(navigationMenuTriggerStyle(), "bg-accent text-accent-foreground")}>Active</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink className={cn(navigationMenuTriggerStyle(), "opacity-50 pointer-events-none")}>Disabled</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>Recipes
Ready-to-copy compositions covering the most common Yuno usages of this atom.
Left column is a brand card; right column stacks 3 titled items. The canonical shadcn/ui landing menu.
2-column grid of items with title + description. Use when the menu enumerates many peers (products, features, docs sections).
Single-column list of plain links, no descriptions. Use when the destinations are self-explanatory.
Single-column list with a leading Phosphor icon per item. Use for status pickers, filters, or icon-annotated destinations.
Import
Copy this import line at the top of the file where you compose this atom.
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";Props
Everything else from the underlying HTML or Radix primitive is forwarded via ...props.
| Prop | Type | Default | Description |
|---|---|---|---|
| NavigationMenu.orientation | "horizontal" | "vertical" | "horizontal" | Trigger layout direction. Default matches marketing top-nav. |
| NavigationMenu.value / defaultValue | string | — | Controlled or uncontrolled open trigger key. Useful for programmatic control. |
| NavigationMenu.delayDuration | number | 200 | How long the user must hover before a menu opens. |
| NavigationMenuTrigger.disabled | boolean | false | Dims to opacity-50 and blocks the menu from opening. |
| NavigationMenuContent.className | string | — | Layout the content freely (grid, columns, featured card). The viewport auto-resizes. |
| NavigationMenuLink.href | string | — | Destination. Use for direct-link triggers (no dropdown) inside a NavigationMenuItem. |
| NavigationMenuLink.active | boolean | false | Marks the link as current. Applies data-[active] on the element. |
| navigationMenuTriggerStyle() | () => string | — | CVA class helper to make a NavigationMenuLink look like a Trigger (used for standalone link items without a dropdown). |
| NavigationMenuViewport | component | — | Auto-rendered inside NavigationMenu — do not mount manually. |
| NavigationMenuIndicator | component | — | Optional arrow above the viewport that follows the active trigger. Mount inside NavigationMenu if you want it. |
When to use
- Marketing sites with multi-column hover dropdowns.
- Docs sites with rich sub-navigation panels.
- Public partner surfaces that need a hover-first top nav.
When not to use
- Dashboard shells — use Sidebar.
- Simple links — use plain <a> or next/link.
- Mobile-only prototypes — hover doesn't exist there.
Usage
- Keep each menu column focused on one topic.
- Use NavigationMenuLink for each item so semantics stay correct.
- Let the viewport auto-size — don't force widths on panels.
- Keep the trigger label to one or two words.
- Don't animate too aggressively — subtle fade works best.
- Don't nest a NavigationMenu inside another — one level only.
- Don't hide critical destinations behind hover — they need a visible link somewhere.
Related
Cross-links to atoms and patterns you may reach for next.
- MenubarFor editor/desktop-app menus (File / Edit / View) instead of marketing hover-menus.
- Dropdown menuFor a single trigger button that opens a compact action menu.
- SidebarYuno's Dashboard nav lives here, not in a NavigationMenu.
- CommandFor a searchable ⌘K palette instead of a hover-driven menu.