Site navigation along the top of a page: plain links, and triggers that open a shared panel of grouped links (a mega-menu). Built from NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent and NavigationMenuLink. It is a set of links, not a menu of actions.
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from "@rdloom/react";
export default function NavigationMenuBasicExample() {
return (
<div className="flex min-h-[22rem] w-full items-start justify-center">
<NavigationMenu label="Main">
<NavigationMenuItem>
<NavigationMenuTrigger>Product</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-80 gap-1">
<NavigationMenuLink href="#analytics" title="Analytics" description="Track visits, sign-ups and revenue in one place." />
<NavigationMenuLink href="#automations" title="Automations" description="Run routine steps without doing them by hand." />
<NavigationMenuLink href="#integrations" title="Integrations" description="Connect the tools your team already uses." />
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Resources</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-80 gap-1">
<NavigationMenuLink href="#guides" title="Guides" description="Step-by-step help for common tasks." />
<NavigationMenuLink href="#changelog" title="Changelog" description="What changed in each release." />
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#pricing">Pricing</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenu>
</div>
);
}Installation
npx rdloom add navigation-menuCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/navigation-menu.jsonWorks, but without upgrade tracking.
Usage
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from "@rdloom/react";
<div className="flex min-h-[22rem] w-full items-start justify-center">
<NavigationMenu label="Main">
<NavigationMenuItem>
<NavigationMenuTrigger>Product</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-80 gap-1">
<NavigationMenuLink href="#analytics" title="Analytics" description="Track visits, sign-ups and revenue in one place." />
<NavigationMenuLink href="#automations" title="Automations" description="Run routine steps without doing them by hand." />
<NavigationMenuLink href="#integrations" title="Integrations" description="Connect the tools your team already uses." />
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Resources</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-80 gap-1">
<NavigationMenuLink href="#guides" title="Guides" description="Step-by-step help for common tasks." />
<NavigationMenuLink href="#changelog" title="Changelog" description="What changed in each release." />
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#pricing">Pricing</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenu>
</div>Featured and grid
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from "@rdloom/react";
export default function NavigationMenuFeaturedAndGridExample() {
return (
<div className="flex min-h-[24rem] w-full items-start justify-center">
<NavigationMenu label="Main" align="center">
<NavigationMenuItem>
<NavigationMenuTrigger>Solutions</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-[34rem] max-w-full grid-cols-[1fr_1.4fr] gap-2">
<NavigationMenuLink href="#overview" isFeatured title="Solutions overview" description="See how teams of different sizes use the platform." />
<div className="grid grid-cols-2 gap-1">
<NavigationMenuLink href="#startups" title="Startups" description="Launch quickly." />
<NavigationMenuLink href="#agencies" title="Agencies" description="Manage many clients." />
<NavigationMenuLink href="#enterprise" title="Enterprise" description="Control and audit." />
<NavigationMenuLink href="#education" title="Education" description="Courses and cohorts." />
</div>
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#docs">Docs</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#blog">Blog</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenu>
</div>
);
}With current page
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from "@rdloom/react";
export default function NavigationMenuWithCurrentPageExample() {
return (
<div className="flex min-h-[22rem] w-full items-start justify-center">
<NavigationMenu label="Main">
<NavigationMenuItem>
<NavigationMenuLink href="#home">Home</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger isCurrent>Guides</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid w-80 gap-1">
<NavigationMenuLink href="#start" title="Getting started" description="Install and build your first page." />
<NavigationMenuLink href="#theming" title="Theming" description="Colors, type and spacing through tokens." isCurrent />
<NavigationMenuLink href="#testing" title="Testing" description="Check keyboard and screen reader behavior." />
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#reference">Reference</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenu>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
labelThe accessible name of the navigation landmark, e.g. 'Main'. Give each nav on a page a different name. | string | "Main" |
delayMilliseconds the pointer rests on a trigger before its panel opens, and before it closes after the pointer leaves. Keyboard and click open at once. | number | 150 |
alignWhere an open panel sits under the bar: start aligns it with the bar start, center puts it in the middle of the bar, end aligns it with the bar end. Use center or end for a wide panel near the edge of the page. | "start" | "center" | "end" | "start" |
childrenrequiredNavigationMenuItem elements. Each holds either a NavigationMenuLink, or a NavigationMenuTrigger with a NavigationMenuContent. | node | none |
Accessibility
Role navigation, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
- Tab moves through the top-level triggers and links, then into the open panel's links, then on
- Enter or Space on a trigger opens or closes its panel
- Down Arrow on a trigger opens its panel and moves to the first link
- Left and Right Arrow move between the top-level triggers and links (reversed in right-to-left text)
- Home and End move to the first and last top-level item
- Esc closes the open panel and returns focus to its trigger
Screen readers announce
- The landmark is announced as navigation with its name
- A trigger is announced as a button, expanded or collapsed
- Links in the panel are read as links with their title and description, and the current one as current page
What your code must do
- A nav landmark with an accessible name
- Each trigger is a button with aria-expanded and aria-controls pointing at its panel
- The panel closes on a click outside it and when focus leaves the navigation
- Hover opens a panel after a short delay, and everything hover does is also available by keyboard and click
- The current page is marked with aria-current="page" and a visible mark that is not color alone
- Opening and closing respect reduced motion
Guidelines
Use it when
- A marketing or documentation site with several sections, some with many links
- A header where a few links need a short description each
Avoid it when
- Actions such as Copy or Delete: use Menu
- A desktop application's File, Edit, View bar: use Menubar
- Navigation inside an app with many levels: use Sidebar
- Five or fewer links with no groups: plain links are enough
Don't
- Opening a panel only on hover with no click or keyboard route
- A trigger that is also a link to a page: the trigger only opens the panel
- Panels with more than about eight links without grouping
- Putting forms or other controls in the panel
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-surface-default--rd-color-surface-raised--rd-color-surface-subtle--rd-color-border-default--rd-color-text-default--rd-color-text-muted--rd-color-focus-ring--rd-radius-control--rd-radius-overlay