Navigation Menu
Navigation Menu provides Runtime-backed navigation disclosure, focus management, and floating content positioning.
---import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle,} from "@/components/starwind/navigation-menu";import AlertCircle from "@tabler/icons/outline/alert-circle.svg";import CircleCheck from "@tabler/icons/outline/circle-check.svg";import CircleDashed from "@tabler/icons/outline/circle-dashed.svg";
const components = [ { title: "Alert Dialog", href: "/docs/components/alert-dialog/", description: "A modal dialog that interrupts the user with important content and expects a response.", }, { title: "Hover Card", href: "/docs/components/hover-card/", description: "For sighted users to preview content available behind a link.", }, { title: "Progress", href: "/docs/components/progress/", description: "Displays an indicator showing the completion progress of a task.", }, { title: "Scroll Area", href: "/docs/components/scroll-area/", description: "Augments native scroll functionality for custom, cross-browser styling.", }, { title: "Tabs", href: "/docs/components/tabs/", description: "A set of layered sections of content displayed one at a time.", }, { title: "Tooltip", href: "/docs/components/tooltip/", description: "A popup that provides information when an element is focused or hovered.", },];---
<NavigationMenu size="md" aria-label="Documentation navigation"> <NavigationMenuList> <NavigationMenuItem value="getting-started"> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul class="w-108"> <li> <NavigationMenuLink href="/docs/getting-started/introduction/"> <div class="flex flex-col gap-1.5"> <div class="leading-none font-medium">Introduction</div> <div class="text-muted-foreground line-clamp-2"> Reusable components built with Tailwind CSS. </div> </div> </NavigationMenuLink> </li> <li> <NavigationMenuLink href="/docs/getting-started/installation/"> <div class="flex flex-col gap-1.5"> <div class="leading-none font-medium">Installation</div> <div class="text-muted-foreground line-clamp-2"> How to install dependencies and structure your app. </div> </div> </NavigationMenuLink> </li> <li> <NavigationMenuLink href="/docs/getting-started/theming/"> <div class="flex flex-col gap-1.5"> <div class="leading-none font-medium">Theming</div> <div class="text-muted-foreground line-clamp-2"> Customize colors, typography, and design tokens. </div> </div> </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="components" class="hidden md:flex"> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[500px] gap-2 md:w-[600px] md:grid-cols-2 lg:w-[700px]"> {components.map((component) => ( <li> <NavigationMenuLink href={component.href}> <div class="flex flex-col gap-1.5"> <div class="leading-none font-medium">{component.title}</div> <div class="text-muted-foreground line-clamp-2"> {component.description} </div> </div> </NavigationMenuLink> </li> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="status"> <NavigationMenuTrigger>With icon</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[240px]"> <li> <NavigationMenuLink href="#backlog" class="flex-row items-center gap-2"> <AlertCircle />Backlog </NavigationMenuLink> <NavigationMenuLink href="#to-do" class="flex-row items-center gap-2"> <CircleDashed />To Do </NavigationMenuLink> <NavigationMenuLink href="#done" class="flex-row items-center gap-2"> <CircleCheck />Done </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs/" class={navigationMenuTriggerStyle()}> Docs </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList></NavigationMenu>import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle,} from "@/components/starwind/navigation-menu";import { IconAlertCircle as AlertCircle, IconCircleCheck as CircleCheck, IconCircleDashed as CircleDashed,} from "@tabler/icons-react";
const components = [ { title: "Alert Dialog", href: "/docs/components/alert-dialog/", description: "A modal dialog that interrupts the user with important content and expects a response.", }, { title: "Hover Card", href: "/docs/components/hover-card/", description: "For sighted users to preview content available behind a link.", }, { title: "Progress", href: "/docs/components/progress/", description: "Displays an indicator showing the completion progress of a task.", }, { title: "Scroll Area", href: "/docs/components/scroll-area/", description: "Augments native scroll functionality for custom, cross-browser styling.", }, { title: "Tabs", href: "/docs/components/tabs/", description: "A set of layered sections of content displayed one at a time.", }, { title: "Tooltip", href: "/docs/components/tooltip/", description: "A popup that provides information when an element is focused or hovered.", },];
export function Example() { return ( <> <NavigationMenu size="md" aria-label="Documentation navigation"> <NavigationMenuList> <NavigationMenuItem value="getting-started"> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul className="w-108"> <li> <NavigationMenuLink href="/docs/getting-started/introduction/"> <div className="flex flex-col gap-1.5"> <div className="leading-none font-medium">Introduction</div> <div className="text-muted-foreground line-clamp-2"> Reusable components built with Tailwind CSS. </div> </div> </NavigationMenuLink> </li> <li> <NavigationMenuLink href="/docs/getting-started/installation/"> <div className="flex flex-col gap-1.5"> <div className="leading-none font-medium">Installation</div> <div className="text-muted-foreground line-clamp-2"> How to install dependencies and structure your app. </div> </div> </NavigationMenuLink> </li> <li> <NavigationMenuLink href="/docs/getting-started/theming/"> <div className="flex flex-col gap-1.5"> <div className="leading-none font-medium">Theming</div> <div className="text-muted-foreground line-clamp-2"> Customize colors, typography, and design tokens. </div> </div> </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="components" className="hidden md:flex"> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[500px] gap-2 md:w-[600px] md:grid-cols-2 lg:w-[700px]"> {components.map((component) => ( <li key={`${component.href}-${component.title}`}> <NavigationMenuLink href={component.href}> <div className="flex flex-col gap-1.5"> <div className="leading-none font-medium">{component.title}</div> <div className="text-muted-foreground line-clamp-2"> {component.description} </div> </div> </NavigationMenuLink> </li> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="status"> <NavigationMenuTrigger>With icon</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[240px]"> <li> <NavigationMenuLink href="#backlog" className="flex-row items-center gap-2"> <AlertCircle />Backlog </NavigationMenuLink> <NavigationMenuLink href="#to-do" className="flex-row items-center gap-2"> <CircleDashed />To Do </NavigationMenuLink> <NavigationMenuLink href="#done" className="flex-row items-center gap-2"> <CircleCheck />Done </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs/" className={navigationMenuTriggerStyle()}> Docs </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu> </> );}Installation
pnpx starwind@latest add navigation-menunpx starwind@latest add navigation-menuyarn dlx starwind@latest add navigation-menuUsage
---import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger,} from "@/components/starwind/navigation-menu";---import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger,} from "@/components/starwind/navigation-menu";<NavigationMenu> <NavigationMenuList> <NavigationMenuItem value="item-one"> <NavigationMenuTrigger>Item One</NavigationMenuTrigger> <NavigationMenuContent> <NavigationMenuLink href="/docs/">Link</NavigationMenuLink> </NavigationMenuContent> </NavigationMenuItem> </NavigationMenuList></NavigationMenu>import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger } from "@/components/starwind/navigation-menu";
export function Example() { return ( <> <NavigationMenu> <NavigationMenuList> <NavigationMenuItem value="item-one"> <NavigationMenuTrigger>Item One</NavigationMenuTrigger> <NavigationMenuContent> <NavigationMenuLink href="/docs/">Link</NavigationMenuLink> </NavigationMenuContent> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu> </> );}Sizes
NavigationMenu defaults to size="md". Set size once to keep native triggers, List spacing, trigger-style Links, and portaled content aligned. Use contentSize only when the shared popup should intentionally use a different size.
---import AlertCircle from "@tabler/icons/outline/alert-circle.svg";import CircleCheck from "@tabler/icons/outline/circle-check.svg";import CircleDashed from "@tabler/icons/outline/circle-dashed.svg";import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle,} from "@/components/starwind/navigation-menu";
const componentLinks = [ { title: "Alert Dialog", href: "/docs/components/alert-dialog/", description: "A modal dialog that asks for a response.", }, { title: "Hover Card", href: "/docs/components/hover-card/", description: "Preview content available behind a link.", },];---
<div class="grid gap-6"> <div class="space-y-3"> <div class="text-muted-foreground text-sm font-medium">Small (sm)</div> <NavigationMenu size="sm" aria-label="Small documentation navigation"> <NavigationMenuList> <NavigationMenuItem value="small-getting-started"> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul class="w-96"> <li> <NavigationMenuLink href="/docs/getting-started/introduction/"> <div class="flex flex-col gap-1 text-sm"> <div class="leading-none font-medium">Introduction</div> <div class="text-muted-foreground line-clamp-2"> Reusable components built with Tailwind CSS. </div> </div> </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="small-components" class="hidden md:flex"> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[400px] gap-2 md:w-[500px] md:grid-cols-2 lg:w-[600px]"> {componentLinks.map((component) => ( <li> <NavigationMenuLink href={component.href}> <div class="flex flex-col gap-1 text-sm"> <div class="leading-none font-medium">{component.title}</div> <div class="text-muted-foreground line-clamp-2"> {component.description} </div> </div> </NavigationMenuLink> </li> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="small-status"> <NavigationMenuTrigger>With icon</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[200px]"> <li> <NavigationMenuLink href="#small-backlog" class="flex-row items-center gap-2"> <AlertCircle />Backlog </NavigationMenuLink> <NavigationMenuLink href="#small-to-do" class="flex-row items-center gap-2"> <CircleDashed />To Do </NavigationMenuLink> <NavigationMenuLink href="#small-done" class="flex-row items-center gap-2"> <CircleCheck />Done </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs/" class={navigationMenuTriggerStyle()}> Docs </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu> </div>
<div class="space-y-3"> <div class="text-muted-foreground text-sm font-medium">Medium (md)</div> <NavigationMenu size="md" aria-label="Medium documentation navigation"> <NavigationMenuList> <NavigationMenuItem value="medium-getting-started"> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul class="w-108"> <li> <NavigationMenuLink href="/docs/getting-started/introduction/"> <div class="flex flex-col gap-1.5"> <div class="leading-none font-medium">Introduction</div> <div class="text-muted-foreground line-clamp-2"> Reusable components built with Tailwind CSS. </div> </div> </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="medium-components" class="hidden md:flex"> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[500px] gap-2 md:w-[600px] md:grid-cols-2 lg:w-[700px]"> {componentLinks.map((component) => ( <li> <NavigationMenuLink href={component.href}> <div class="flex flex-col gap-1.5"> <div class="leading-none font-medium">{component.title}</div> <div class="text-muted-foreground line-clamp-2"> {component.description} </div> </div> </NavigationMenuLink> </li> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="medium-status"> <NavigationMenuTrigger>With icon</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[240px]"> <li> <NavigationMenuLink href="#medium-backlog" class="flex-row items-center gap-2"> <AlertCircle />Backlog </NavigationMenuLink> <NavigationMenuLink href="#medium-to-do" class="flex-row items-center gap-2"> <CircleDashed />To Do </NavigationMenuLink> <NavigationMenuLink href="#medium-done" class="flex-row items-center gap-2"> <CircleCheck />Done </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs/" class={navigationMenuTriggerStyle()}> Docs </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu> </div></div>import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, navigationMenuTriggerStyle,} from "@/components/starwind/navigation-menu";import { IconAlertCircle, IconCircleCheck, IconCircleDashed } from "@tabler/icons-react";
const componentLinks = [ { title: "Alert Dialog", href: "/docs/components/alert-dialog/", description: "A modal dialog that asks for a response.", }, { title: "Hover Card", href: "/docs/components/hover-card/", description: "Preview content available behind a link.", },];
export function Example() { return ( <div className="grid gap-6"> <div className="space-y-3"> <div className="text-muted-foreground text-sm font-medium">Small (sm)</div> <NavigationMenu size="sm" aria-label="Small documentation navigation"> <NavigationMenuList> <NavigationMenuItem value="small-getting-started"> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul className="w-96"> <li> <NavigationMenuLink href="/docs/getting-started/introduction/"> <div className="flex flex-col gap-1 text-sm"> <div className="leading-none font-medium">Introduction</div> <div className="text-muted-foreground line-clamp-2"> Reusable components built with Tailwind CSS. </div> </div> </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="small-components" className="hidden md:flex"> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[400px] gap-2 md:w-[500px] md:grid-cols-2 lg:w-[600px]"> {componentLinks.map((component) => ( <li key={component.href}> <NavigationMenuLink href={component.href}> <div className="flex flex-col gap-1 text-sm"> <div className="leading-none font-medium">{component.title}</div> <div className="text-muted-foreground line-clamp-2"> {component.description} </div> </div> </NavigationMenuLink> </li> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="small-status"> <NavigationMenuTrigger>With icon</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[200px]"> <li> <NavigationMenuLink href="#small-backlog" className="flex-row items-center gap-2"> <IconAlertCircle />Backlog </NavigationMenuLink> <NavigationMenuLink href="#small-to-do" className="flex-row items-center gap-2"> <IconCircleDashed />To Do </NavigationMenuLink> <NavigationMenuLink href="#small-done" className="flex-row items-center gap-2"> <IconCircleCheck />Done </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs/" className={navigationMenuTriggerStyle()}> Docs </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu> </div>
<div className="space-y-3"> <div className="text-muted-foreground text-sm font-medium">Medium (md)</div> <NavigationMenu size="md" aria-label="Medium documentation navigation"> <NavigationMenuList> <NavigationMenuItem value="medium-getting-started"> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul className="w-108"> <li> <NavigationMenuLink href="/docs/getting-started/introduction/"> <div className="flex flex-col gap-1.5"> <div className="leading-none font-medium">Introduction</div> <div className="text-muted-foreground line-clamp-2"> Reusable components built with Tailwind CSS. </div> </div> </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="medium-components" className="hidden md:flex"> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[500px] gap-2 md:w-[600px] md:grid-cols-2 lg:w-[700px]"> {componentLinks.map((component) => ( <li key={component.href}> <NavigationMenuLink href={component.href}> <div className="flex flex-col gap-1.5"> <div className="leading-none font-medium">{component.title}</div> <div className="text-muted-foreground line-clamp-2"> {component.description} </div> </div> </NavigationMenuLink> </li> ))} </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem value="medium-status"> <NavigationMenuTrigger>With icon</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[240px]"> <li> <NavigationMenuLink href="#medium-backlog" className="flex-row items-center gap-2"> <IconAlertCircle />Backlog </NavigationMenuLink> <NavigationMenuLink href="#medium-to-do" className="flex-row items-center gap-2"> <IconCircleDashed />To Do </NavigationMenuLink> <NavigationMenuLink href="#medium-done" className="flex-row items-center gap-2"> <IconCircleCheck />Done </NavigationMenuLink> </li> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs/" className={navigationMenuTriggerStyle()}> Docs </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu> </div> </div> );}Custom triggers
Native NavigationMenuTrigger elements merge ordinary class customization through their full recipe. With asChild, the child instead owns its complete appearance and markup; Navigation Menu adds behavior, accessibility/state attributes, and the Trigger’s consumer-provided class.
Composition
Use the following composition to build a NavigationMenu:
NavigationMenu├── NavigationMenuList│ ├── NavigationMenuItem│ │ ├── NavigationMenuTrigger│ │ └── NavigationMenuContent│ │ ├── NavigationMenuLink│ │ └── NavigationMenuLink│ └── NavigationMenuItem│ └── NavigationMenuLink└── NavigationMenuIndicatorAPI Reference
Styled Component API
These props are added or materially changed by the installed styled component. Standard HTML attributes remain available through the inherited interfaces noted below. Expand a prop to see named type definitions and framework-specific imports. Follow the Primitive and Runtime links for lower-level behavior props.
Navigation Menu
Inherits nav attributes. Omits `defaultValue`, `onChange`, and `value`.
Contains the following additional props:
"start" | "center" | "end" "start"
- Description
- Aligns the component within its available axis.
- Classification
- Wrapper prop
number 0
- Description
- Offsets the component from its selected alignment in pixels.
- Classification
- Wrapper prop
boolean true
- Description
- Repositions floating content to keep it inside the collision boundary.
- Classification
- Wrapper prop
number 8
- Description
- Sets the minimum space retained around a collision boundary.
- Classification
- Wrapper prop
"sm" | "md" size
- Description
- Sets the independently portaled popup content size and defaults to the resolved Navigation Menu size.
- Classification
- Wrapper prop
"top" | "right" | "bottom" | "left" "bottom"
- Description
- Selects the preferred side for floating content.
- Classification
- Wrapper prop
number 8
- Description
- Sets the distance in pixels between floating content and its anchor.
- Classification
- Wrapper prop
"sm" | "md" "md"
- Description
- Sets the visual size of native styled triggers, List spacing, indicators, and top-level Links using navigationMenuTriggerStyle().
- Classification
- Wrapper prop
Navigation Menu Item
Inherits li attributes.
Contains the following additional props:
string —
- Description
- Controls or identifies the component value.
- Classification
- Wrapper prop
Navigation Menu Trigger
Inherits button attributes.
Contains the following additional props:
boolean false
- Description
- Delegates markup and complete visual ownership to the child while retaining Navigation Menu behavior and accessibility wiring.
- Classification
- Primitive override
- Primitive prop
- navigation-menu.Trigger.asChild
number —
- Description
- Sets the delay in milliseconds before closing.
- Classification
- Primitive override
- Primitive prop
- navigation-menu.Trigger.closeDelay
string —
- Description
- Adds classes to the component's generated icon.
- Classification
- Wrapper prop
number —
- Description
- Sets the delay in milliseconds before opening.
- Classification
- Primitive override
- Primitive prop
- navigation-menu.Trigger.openDelay
boolean true
- Description
- Shows the component's generated icon.
- Classification
- Wrapper prop
Navigation Menu Positioner
Inherits div attributes.
Contains the following additional props:
number 8
- Description
- Sets the distance in pixels between floating content and its anchor.
- Classification
- Primitive override
- Primitive prop
- navigation-menu.Positioner.sideOffset
"sm" | "md" "md"
- Description
- Sets the popup content size when rendering NavigationMenuPositioner directly.
- Classification
- Wrapper prop
Primitive And Runtime API
Use these references when you need the lower-level behavior APIs behind Navigation Menu.
Primitive API
Runtime API
- Navigation Menu primitive
createNavigationMenufrom@starwind-ui/runtime/navigation-menu
Changelog
v1.1.1
- Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.
v1.1.0
- Added root
smandmdsizing plus independentcontentSizecontrol for the shared portaled popup. OmittedcontentSizefollows the resolved rootsize. - Corrected styled
NavigationMenuTrigger asChildownership: the composed child now keeps its own complete appearance and markup. Style and size the child directly, and add any desired icon inside it; Navigation Menu still supplies behavior and accessibility wiring.
v1.0.0
- Added the Runtime-backed Navigation Menu with keyboard navigation and shared viewport behavior.
- See the Navigation Menu Primitive for the underlying unstyled anatomy and behavior API.