Simple link navigation
A flat navigation bar with no dropdowns. Apply navigationMenuTriggerStyle() to
each NavigationMenuLink for consistent hover/focus styling.
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink className={navigationMenuTriggerStyle()} href="/dashboard">
Dashboard
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink className={navigationMenuTriggerStyle()} href="/projects">
Projects
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>Complex mega menu
A Stripe-style product navigation with grouped links, icons, descriptions, and a
supporting CTA panel. Keep the link model data-driven and use semantic design
tokens (bg-card, bg-muted, text-primary, text-muted-foreground,
border-border, ring-ring) so light and dark mode stay aligned.
const productSections = [
{
title: 'Platform',
links: [
{
title: 'Payroll engine',
description: 'Run compliant salary, allowance, and statutory workflows.',
href: '/products/payroll',
icon: WalletCards,
},
{
title: 'Benefits hub',
description: 'Coordinate claims, coverage, eligibility, and provider flows.',
href: '/products/benefits',
icon: ShieldCheck,
},
],
},
];
function MegaMenuLinkItem({ link }) {
const Icon = link.icon;
return (
<NavigationMenuLink asChild>
<a
className="flex min-h-20 gap-3 rounded-md p-3 hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring"
href={link.href}
>
<span className="inline-flex h-9 w-9 items-center justify-center rounded-md border border-border bg-card text-primary">
<Icon className="h-4 w-4" aria-hidden />
</span>
<span>
<span className="block text-body-sm font-semibold text-foreground">
{link.title}
</span>
<span className="block text-body-sm text-muted-foreground">
{link.description}
</span>
</span>
</a>
</NavigationMenuLink>
);
}
<NavigationMenu className="w-full max-w-screen-lg justify-start">
<NavigationMenuList className="justify-start">
<NavigationMenuItem>
<NavigationMenuTrigger>Products</NavigationMenuTrigger>
<NavigationMenuContent className="min-w-full">
<div className="grid w-screen max-w-screen-lg overflow-hidden md:grid-cols-3">
<div className="grid gap-6 p-6 md:col-span-2 md:grid-cols-2">
{productSections.map((section) => (
<section key={section.title} aria-label={section.title}>
<h3 className="px-3 text-label-sm font-semibold uppercase tracking-wide text-muted-foreground">
{section.title}
</h3>
<ul className="mt-3 grid gap-1">
{section.links.map((link) => (
<li key={link.title}>
<MegaMenuLinkItem link={link} />
</li>
))}
</ul>
</section>
))}
</div>
<aside className="border-t border-border bg-muted/40 p-6 md:border-l md:border-t-0">
<h3 className="text-title-sm font-semibold text-foreground">
Launch a governed product surface
</h3>
<p className="mt-2 text-body-sm text-muted-foreground">
Combine primitives, recipes, registry installs, and MCP guidance.
</p>
</aside>
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink className={navigationMenuTriggerStyle()} href="/docs">
Documentation
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>