# Navigation Menu (/ui/components/react/navigation-menu)



<Playground component="navigation-menu" />

## Usage [#usage]

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'
```

```tsx
<NavigationMenu aria-label="Main">
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>
        Products
        <NavigationMenuIcon />
      </NavigationMenuTrigger>
      <NavigationMenuContent>
        <ul className="grid w-50 gap-1">
          <li>
            <NavigationMenuLink href="/analytics">Analytics</NavigationMenuLink>
          </li>
          <li>
            <NavigationMenuLink href="/ui/components">Components</NavigationMenuLink>
          </li>
        </ul>
      </NavigationMenuContent>
    </NavigationMenuItem>
    <NavigationMenuItem>
      <NavigationMenuLink href="/pricing" className="w-auto">
        Pricing
      </NavigationMenuLink>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>
```

`NavigationMenu` is a compound component built on [Base UI's Navigation Menu](https://base-ui.com/react/components/navigation-menu). The root coordinates the bar and shares `variant`, `size`, `orientation`, and the trigger `icon` with every item. The single popup **morphs** — moving and resizing — between items as you hover across the bar:

* **`NavigationMenuList`** — the row (or column) of items.
* **`NavigationMenuItem`** — wraps one entry: a trigger + content, or a single link.
* **`NavigationMenuTrigger`** — the label that opens an item's panel on hover or focus.
* **`NavigationMenuIcon`** — the trigger's open/close indicator; flips while open. Override its kind per-trigger or drop it with `icon={false}` on the root.
* **`NavigationMenuContent`** — the panel for a trigger. Lay your links out inside it however you like — a list, a grid, a featured card.
* **`NavigationMenuLink`** — a link, both inside a panel and as a standalone top-level item (give it `className="w-auto"` so it sizes to its label in the bar).
* **`NavigationMenuViewport`** — the surface a panel renders into. The root renders one automatically; render your own only for [inline submenus](#nested-inline-submenus).
* **`NavigationMenuPositioner`** — the portalled, auto-positioned wrapper around the popup. Rendered automatically; pass `viewport={false}` on the root to opt out.

Reach for a `NavigationMenu` for **marketing-style site navigation** with multi-column panels and descriptions. For a single menu of actions opened from a button, use a [`Dropdown Menu`](/ui/components/react/dropdown-menu); for an application command bar (File / Edit / View), use a [`Menubar`](/ui/components/react/menubar); for a flat row of section links, use [`Navigation`](/ui/components/react/navigation).

## Examples [#examples]

### Default [#default]

A bar with two panel-opening items and one plain link. Each panel is just markup inside `NavigationMenuContent` — here a grid of `NavigationMenuLink` cards with an icon, a title, and a description. The popup morphs to fit whichever panel is open.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'
import { DeviceDesktopAnalytics2, Cube, Bolt, Book, Code, Lifebuoy } from '@appica/icons-react'

const PRODUCTS = [
  { title: 'Analytics', description: 'Track usage and conversions in real time.', Icon: DeviceDesktopAnalytics2 },
  { title: 'Components', description: 'A composable library of UI primitives.', Icon: Cube },
  { title: 'Automation', description: 'Wire up workflows without code.', Icon: Bolt },
  { title: 'Integrations', description: 'Connect the tools your team already uses.', Icon: Code },
]

const RESOURCES = [
  { title: 'Documentation', description: 'Guides and API references.', Icon: Book },
  { title: 'Support', description: 'Reach our team for help.', Icon: Lifebuoy },
]

export default function NavigationMenuDefault() {
  return (
    <NavigationMenu aria-label="Main">
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>
            Products
            <NavigationMenuIcon />
          </NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul className="grid w-96 grid-cols-2 gap-0.5">
              {PRODUCTS.map(({ title, description, Icon }) => (
                <li key={title}>
                  <NavigationMenuLink href="#!" className="h-auto flex-col items-start gap-1 whitespace-normal">
                    <span className="text-foreground-intense flex items-center gap-1.5 font-medium">
                      <Icon />
                      {title}
                    </span>
                    <span className="text-foreground-muted text-xs font-normal">{description}</span>
                  </NavigationMenuLink>
                </li>
              ))}
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>

        <NavigationMenuItem>
          <NavigationMenuTrigger>
            Resources
            <NavigationMenuIcon />
          </NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul className="w-50 gap-0.5">
              {RESOURCES.map(({ title, description, Icon }) => (
                <li key={title}>
                  <NavigationMenuLink href="#!" className="h-auto flex-col items-start gap-1 whitespace-normal">
                    <span className="text-foreground-intense flex items-center gap-1.5 font-medium">
                      <Icon />
                      {title}
                    </span>
                    <span className="text-foreground-muted text-xs font-normal">{description}</span>
                  </NavigationMenuLink>
                </li>
              ))}
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>

        <NavigationMenuItem>
          <NavigationMenuLink href="#!">Pricing</NavigationMenuLink>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  )
}
```

### Variants [#variants]

`variant` styles the triggers: `pill` (default) gives each a hover/active background, while `line` draws an animated underline.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'

const LINKS = ['Overview', 'Changelog', 'Roadmap', 'Releases']

function Menus() {
  return (
    <>
      <NavigationMenuItem>
        <NavigationMenuTrigger>
          Product
          <NavigationMenuIcon />
        </NavigationMenuTrigger>
        <NavigationMenuContent>
          <ul className="w-50 gap-0.5">
            {LINKS.map((label) => (
              <li key={label}>
                <NavigationMenuLink href="#!">{label}</NavigationMenuLink>
              </li>
            ))}
          </ul>
        </NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuLink href="#!">Pricing</NavigationMenuLink>
      </NavigationMenuItem>
    </>
  )
}

export default function NavigationMenuVariants() {
  return (
    <div className="flex flex-col gap-8">
      <NavigationMenu aria-label="Pill" variant="pill">
        <NavigationMenuList>
          <Menus />
        </NavigationMenuList>
      </NavigationMenu>

      <NavigationMenu aria-label="Line" variant="line">
        <NavigationMenuList>
          <Menus />
        </NavigationMenuList>
      </NavigationMenu>
    </div>
  )
}
```

### Sizes [#sizes]

`size` on the root scales the triggers, popup radius, and link padding together — `sm`, `md` (default), or `lg`.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'

const SIZES = ['sm', 'md', 'lg'] as const

const LINKS = ['Overview', 'Analytics', 'Settings']

export default function NavigationMenuSizes() {
  return (
    <div className="flex flex-wrap items-center gap-6">
      {SIZES.map((size) => (
        <NavigationMenu key={size} aria-label={size} size={size}>
          <NavigationMenuList>
            <NavigationMenuItem>
              <NavigationMenuTrigger>
                {size}
                <NavigationMenuIcon />
              </NavigationMenuTrigger>
              <NavigationMenuContent>
                <ul className="w-50 gap-0.5">
                  {LINKS.map((label) => (
                    <li key={label}>
                      <NavigationMenuLink href="#!">{label}</NavigationMenuLink>
                    </li>
                  ))}
                </ul>
              </NavigationMenuContent>
            </NavigationMenuItem>
          </NavigationMenuList>
        </NavigationMenu>
      ))}
    </div>
  )
}
```

### Indicator [#indicator]

`icon` on the root sets the open/close indicator next to every trigger: a `chevron` (default), a `caret`, or a `plus` that morphs into a minus. Set `icon={false}` to drop it, or override a single trigger by passing `icon` to its `NavigationMenuIcon`.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'

const KINDS = ['chevron', 'caret', 'plus'] as const

const LINKS = ['Dashboard', 'Reports', 'Settings']

export default function NavigationMenuIcons() {
  return (
    <div className="flex flex-wrap gap-6">
      {KINDS.map((kind) => (
        <NavigationMenu key={kind} aria-label={kind} icon={kind}>
          <NavigationMenuList>
            <NavigationMenuItem>
              <NavigationMenuTrigger>
                {kind}
                <NavigationMenuIcon />
              </NavigationMenuTrigger>
              <NavigationMenuContent>
                <ul className="w-50 gap-0.5">
                  {LINKS.map((label) => (
                    <li key={label}>
                      <NavigationMenuLink href="#!">{label}</NavigationMenuLink>
                    </li>
                  ))}
                </ul>
              </NavigationMenuContent>
            </NavigationMenuItem>
          </NavigationMenuList>
        </NavigationMenu>
      ))}
    </div>
  )
}
```

### Vertical [#vertical]

Set `orientation="vertical"` to stack the bar into a sidebar; each panel opens to the inline-end side. Give triggers `w-full justify-start` and push the indicator to the edge with `ms-auto`.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'
import { LayoutDashboard, Folder, Users } from '@appica/icons-react'

const MENUS = [
  { label: 'Dashboard', Icon: LayoutDashboard, links: ['Summary', 'Activity', 'Insights'] },
  { label: 'Projects', Icon: Folder, links: ['All projects', 'Archived', 'Templates'] },
  { label: 'Team', Icon: Users, links: ['Members', 'Roles', 'Invitations'] },
]

export default function NavigationMenuVertical() {
  return (
    <NavigationMenu aria-label="Sidebar" orientation="vertical" className="w-48">
      <NavigationMenuList>
        {MENUS.map(({ label, Icon, links }) => (
          <NavigationMenuItem key={label}>
            <NavigationMenuTrigger className="w-full justify-start">
              <Icon data-icon="start" />
              {label}
              <NavigationMenuIcon className="ms-auto" />
            </NavigationMenuTrigger>
            <NavigationMenuContent>
              <ul className="w-48 gap-0.5">
                {links.map((link) => (
                  <li key={link}>
                    <NavigationMenuLink href="#!">{link}</NavigationMenuLink>
                  </li>
                ))}
              </ul>
            </NavigationMenuContent>
          </NavigationMenuItem>
        ))}
      </NavigationMenuList>
    </NavigationMenu>
  )
}
```

### Backdrop [#backdrop]

Set `backdrop` to dim and blur the page behind the open panel — useful for a prominent mega-menu that should pull focus away from the page.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'

const PRODUCTS = [
  { title: 'Analytics', description: 'Track usage and conversions.' },
  { title: 'Components', description: 'A composable UI library.' },
  { title: 'Automation', description: 'Wire up workflows fast.' },
  { title: 'Integrations', description: 'Connect your stack.' },
]

export default function NavigationMenuBackdrop() {
  return (
    <NavigationMenu aria-label="Main" backdrop>
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>
            Products
            <NavigationMenuIcon />
          </NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul className="grid w-94 grid-cols-2 gap-0.5">
              {PRODUCTS.map(({ title, description }) => (
                <li key={title}>
                  <NavigationMenuLink href="#!" className="h-auto flex-col items-start gap-1 whitespace-normal">
                    <span className="text-foreground-intense font-medium">{title}</span>
                    <span className="text-foreground-muted text-xs font-normal">{description}</span>
                  </NavigationMenuLink>
                </li>
              ))}
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuLink href="#!">Pricing</NavigationMenuLink>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  )
}
```

### Nested submenus [#nested-submenus]

Open a deeper level in its **own panel** by nesting a second `NavigationMenu` (set `orientation="vertical"`) inside a `NavigationMenuContent`. The nested menu renders its own portalled popup, opening to the side of the parent panel — just like a submenu.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
} from '@appica/ui-react/navigation-menu'

const COMPANY = [
  { title: 'About', description: 'Our mission and the team behind it.' },
  { title: 'Careers', description: 'Open roles across the company.' },
  { title: 'Blog', description: 'Product news and engineering notes.' },
]

const HANDBOOK = [
  { title: 'Getting started', description: 'Set up your workspace.' },
  { title: 'Principles', description: 'How we make decisions.' },
  { title: 'Remote work', description: 'Working across time zones.' },
]

export default function NavigationMenuNestedSubmenus() {
  return (
    <NavigationMenu aria-label="Main">
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>
            Company
            <NavigationMenuIcon />
          </NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul className="w-58 gap-0.5">
              {COMPANY.map(({ title, description }) => (
                <li key={title}>
                  <NavigationMenuLink href="#!" className="h-auto flex-col items-start gap-1 whitespace-normal">
                    <span className="text-foreground-intense font-medium">{title}</span>
                    <span className="text-foreground-muted text-xs font-normal">{description}</span>
                  </NavigationMenuLink>
                </li>
              ))}
              <li>
                <NavigationMenu orientation="vertical">
                  <NavigationMenuList className="w-full">
                    <NavigationMenuItem className="w-full">
                      <NavigationMenuTrigger className="h-auto w-full whitespace-normal">
                        <span className="flex min-w-0 flex-1 flex-col items-start gap-0.5">
                          <span className="text-foreground-intense font-medium">Handbook</span>
                          <span className="text-foreground-muted text-xs font-normal">
                            How the team works, day to day.
                          </span>
                        </span>
                        <NavigationMenuIcon />
                      </NavigationMenuTrigger>
                      <NavigationMenuContent>
                        <ul className="w-50 gap-0.5">
                          {HANDBOOK.map(({ title, description }) => (
                            <li key={title}>
                              <NavigationMenuLink
                                href="#!"
                                className="h-auto flex-col items-start gap-1 whitespace-normal"
                              >
                                <span className="text-foreground-intense font-medium">{title}</span>
                                <span className="text-foreground-muted text-xs font-normal">{description}</span>
                              </NavigationMenuLink>
                            </li>
                          ))}
                        </ul>
                      </NavigationMenuContent>
                    </NavigationMenuItem>
                  </NavigationMenuList>
                </NavigationMenu>
              </li>
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>

        <NavigationMenuItem>
          <NavigationMenuLink href="#!">Pricing</NavigationMenuLink>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  )
}
```

### Nested inline submenus [#nested-inline-submenus]

To switch panels **within the same popup** — a sidebar of categories beside a detail pane — nest a `NavigationMenu` with `viewport={false}` and render your own `NavigationMenuViewport` next to its list. Use `defaultValue` to open one category on mount, and give each `NavigationMenuItem` a `value` so the list can drive the shared viewport.

```tsx
import {
  NavigationMenu,
  NavigationMenuList,
  NavigationMenuItem,
  NavigationMenuTrigger,
  NavigationMenuIcon,
  NavigationMenuContent,
  NavigationMenuLink,
  NavigationMenuViewport,
} from '@appica/ui-react/navigation-menu'

const AUDIENCES = [
  {
    value: 'developers',
    label: 'Developers',
    hint: 'Build and ship faster',
    title: 'For developers',
    description: 'APIs, SDKs, and primitives to integrate in minutes.',
    links: [
      { title: 'API reference', description: 'Every endpoint, documented.' },
      { title: 'SDKs', description: 'First-party libraries for your stack.' },
      { title: 'Examples', description: 'Copy-paste starting points.' },
    ],
  },
  {
    value: 'designers',
    label: 'Designers',
    hint: 'Design with the system',
    title: 'For designers',
    description: 'Tokens, kits, and guidelines that match the code.',
    links: [
      { title: 'Figma kit', description: 'Components mapped to production.' },
      { title: 'Design tokens', description: 'One source of truth for theming.' },
      { title: 'Guidelines', description: 'Patterns and accessibility notes.' },
    ],
  },
  {
    value: 'teams',
    label: 'Teams',
    hint: 'Scale across the org',
    title: 'For teams',
    description: 'Roles, governance, and shared workspaces.',
    links: [
      { title: 'Permissions', description: 'Granular role-based access.' },
      { title: 'Audit log', description: 'Track every change.' },
      { title: 'SSO', description: 'Single sign-on for everyone.' },
    ],
  },
]

const cardClass = 'h-auto flex-col items-start gap-0.5 whitespace-normal'

export default function NavigationMenuNestedInline() {
  return (
    <NavigationMenu aria-label="Main">
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>
            Product
            <NavigationMenuIcon />
          </NavigationMenuTrigger>
          <NavigationMenuContent className="p-0">
            <NavigationMenu orientation="vertical" defaultValue="developers" viewport={false}>
              <div className="grid w-125 grid-cols-[13rem_minmax(0,1fr)]">
                <NavigationMenuList className="border-border w-full flex-col items-stretch gap-1 border-e p-2">
                  {AUDIENCES.map((menu) => (
                    <NavigationMenuItem key={menu.value} value={menu.value} className="w-full">
                      <NavigationMenuTrigger className={`w-full ${cardClass}`}>
                        <span className="text-foreground-intense font-medium">{menu.label}</span>
                        <span className="text-foreground-muted text-xs font-normal">{menu.hint}</span>
                      </NavigationMenuTrigger>
                      <NavigationMenuContent className="p-0">
                        <div className="flex flex-col gap-3 p-2">
                          <div className="px-3 pt-1">
                            <h4 className="text-foreground-intense m-0 font-semibold">{menu.title}</h4>
                            <p className="text-foreground-muted m-0 mt-0.5 text-sm">{menu.description}</p>
                          </div>
                          <ul className="grid gap-1">
                            {menu.links.map((link) => (
                              <li key={link.title}>
                                <NavigationMenuLink href="#!" className={cardClass}>
                                  <span className="text-foreground-emphasis font-medium">{link.title}</span>
                                  <span className="text-foreground-muted text-xs font-normal">{link.description}</span>
                                </NavigationMenuLink>
                              </li>
                            ))}
                          </ul>
                        </div>
                      </NavigationMenuContent>
                    </NavigationMenuItem>
                  ))}
                </NavigationMenuList>
                <NavigationMenuViewport className="min-h-60" />
              </div>
            </NavigationMenu>
          </NavigationMenuContent>
        </NavigationMenuItem>

        <NavigationMenuItem>
          <NavigationMenuLink href="#!">Pricing</NavigationMenuLink>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  )
}
```

## RTL [#rtl]

Every Appica UI component supports right-to-left layouts out of the box. Set the `dir` attribute on a container (commonly your `<html>` element) so CSS logical properties resolve correctly, and wrap your tree in `DirectionProvider` so direction-aware behavior — roving focus along the bar, popup placement, and the morph direction — follows the same direction.

```tsx
import { DirectionProvider } from '@appica/ui-react/providers/direction-provider'

export default function RootLayout({ children }) {
  return (
    <html lang="ar" dir="rtl">
      <body>
        <DirectionProvider dir="rtl">{children}</DirectionProvider>
      </body>
    </html>
  )
}
```

The bar lays out from the right, arrow-key focus reverses, the panel anchors from the trigger's leading edge, and a vertical menu's panels open toward the inline-start side. For setup details and caveats, see the [RTL guide](/ui/docs/react/rtl).

<Callout type="note" title="Scoped RTL needs the direction on the positioner">
  The popup portals to `<body>`, so its `start`/`end` alignment mirrors from the **document** direction (read from CSS,
  not from `DirectionProvider`) — automatic when `<html dir="rtl">`. If you instead scope RTL to a subtree of an LTR page,
  set `dir="rtl"` on the `NavigationMenu` root so the morphing panel still mirrors. See
  [Floating popups in a scoped RTL region](/ui/docs/react/rtl#floating-popups-in-a-scoped-rtl-region).
</Callout>

<RtlPreview component="navigation-menu" />

## API reference [#api-reference]

`NavigationMenu` wraps [Base UI's Navigation Menu](https://base-ui.com/react/components/navigation-menu). Each part forwards every remaining prop to the matching Base UI primitive, so anything it accepts works here — the tables below list the Appica additions and the most common props. See the Base UI docs for the complete API.

### NavigationMenu [#navigationmenu]

The root. Coordinates the bar, owns the open state, and shares styling with every item.

| Prop            | <ColMinWidth width="210">Type</ColMinWidth>          | Default        | <ColMinWidth width="220">Description</ColMinWidth>                            |
| --------------- | ---------------------------------------------------- | -------------- | ----------------------------------------------------------------------------- |
| `variant`       | <Code>'pill' \| 'line'</Code>                        | `'pill'`       | Trigger appearance — hover/active pill, or an animated underline.             |
| `size`          | <Code>'sm' \| 'md' \| 'lg'</Code>                    | `'md'`         | Scales triggers, popup radius, and link padding.                              |
| `orientation`   | <Code>'horizontal' \| 'vertical'</Code>              | `'horizontal'` | Lay the bar out as a row or a column.                                         |
| `icon`          | <Code>'chevron' \| 'caret' \| 'plus' \| false</Code> | `'chevron'`    | The open/close indicator shown by each `NavigationMenuIcon`.                  |
| `morph`         | `boolean`                                            | `true`         | Animate the popup's size and position between items.                          |
| `backdrop`      | `boolean`                                            | `false`        | Render a dimmed, blurred backdrop behind the open panel.                      |
| `viewport`      | `boolean`                                            | `true`         | Auto-render the portalled positioner + popup. Set `false` to render your own. |
| `sideOffset`    | `number`                                             | `6`            | Gap between the trigger and the auto-rendered popup.                          |
| `value`         | `any`                                                | —              | Controlled open item. Pair with `onValueChange`.                              |
| `defaultValue`  | `any`                                                | —              | Uncontrolled initial open item.                                               |
| `onValueChange` | <Code>(value, eventDetails) => void</Code>           | —              | Fires when the open item changes.                                             |
| `delay`         | `number`                                             | `50`           | Hover-open delay in ms.                                                       |
| `closeDelay`    | `number`                                             | `50`           | Hover-close delay in ms.                                                      |
| `className`     | `string`                                             | —              | Extra classes on the bar, merged via `tailwind-merge`.                        |

### NavigationMenuList [#navigationmenulist]

The row (or column) of items.

| Prop        | Type        | Default | Description                                 |
| ----------- | ----------- | ------- | ------------------------------------------- |
| `children`  | `ReactNode` | —       | The `NavigationMenuItem`s.                  |
| `className` | `string`    | —       | Extra classes, merged via `tailwind-merge`. |

### NavigationMenuItem [#navigationmenuitem]

Wraps one entry — a trigger with content, or a single link.

| Prop        | <ColMinWidth width="160">Type</ColMinWidth> | Default | Description                                                    |
| ----------- | ------------------------------------------- | ------- | -------------------------------------------------------------- |
| `value`     | `any`                                       | —       | Identifies the item — required when driving an inline submenu. |
| `children`  | `ReactNode`                                 | —       | A trigger + content pair, or a `NavigationMenuLink`.           |
| `className` | `string`                                    | —       | Extra classes, merged via `tailwind-merge`.                    |

### NavigationMenuTrigger [#navigationmenutrigger]

The label that opens an item's panel. Inherits the root's `variant`, `size`, and `orientation`.

| Prop        | Type      | Default | Description                                                |
| ----------- | --------- | ------- | ---------------------------------------------------------- |
| `disabled`  | `boolean` | `false` | Disable just this item.                                    |
| `className` | `string`  | —       | Extra classes on the trigger, merged via `tailwind-merge`. |

### NavigationMenuIcon [#navigationmenuicon]

The trigger's open/close indicator. Reads the root's `icon` kind; flips or morphs while the panel is open.

| Prop        | <ColMinWidth width="200">Type</ColMinWidth>          | Default | Description                                 |
| ----------- | ---------------------------------------------------- | ------- | ------------------------------------------- |
| `icon`      | <Code>'chevron' \| 'caret' \| 'plus' \| false</Code> | root    | Override the indicator for this trigger.    |
| `className` | `string`                                             | —       | Extra classes, merged via `tailwind-merge`. |

### NavigationMenuContent [#navigationmenucontent]

The panel for a trigger. Renders into the active viewport; lay your links out inside it freely.

| Prop        | Type        | Default | Description                                 |
| ----------- | ----------- | ------- | ------------------------------------------- |
| `children`  | `ReactNode` | —       | The panel's contents (lists, grids, cards). |
| `className` | `string`    | —       | Extra classes, merged via `tailwind-merge`. |

### NavigationMenuLink [#navigationmenulink]

A link — inside a panel or as a standalone bar item. Renders an `<a>`; use `render` to project it onto a router link. Forwards every native anchor prop (`href`, `target`, `rel`, …).

| Prop        | <ColMinWidth width="220">Type</ColMinWidth>                 | Default | Description                                        |
| ----------- | ----------------------------------------------------------- | ------- | -------------------------------------------------- |
| `href`      | `string`                                                    | —       | Navigation target.                                 |
| `active`    | `boolean`                                                   | `false` | Mark the link as the current page.                 |
| `render`    | <Code>ReactElement \| (props, state) => ReactElement</Code> | —       | Render as your own element (e.g. a router `Link`). |
| `className` | `string`                                                    | —       | Extra classes, merged via `tailwind-merge`.        |

### NavigationMenuPositioner [#navigationmenupositioner]

The portalled, auto-positioned wrapper around the popup. Rendered automatically unless `viewport={false}`; render it yourself only for a fully custom popup.

| Prop               | <ColMinWidth width="200">Type</ColMinWidth>         | Default             | Description                                                  |
| ------------------ | --------------------------------------------------- | ------------------- | ------------------------------------------------------------ |
| `side`             | <Code>'top' \| 'right' \| 'bottom' \| 'left'</Code> | bottom / inline-end | Preferred side to open on (vertical defaults to inline-end). |
| `sideOffset`       | `number`                                            | `6`                 | Gap between the trigger and the popup.                       |
| `align`            | <Code>'start' \| 'center' \| 'end'</Code>           | `'start'`           | Alignment along that side.                                   |
| `alignOffset`      | `number`                                            | —                   | Shift along the alignment axis.                              |
| `collisionPadding` | `number`                                            | —                   | Minimum gap kept from the viewport edge.                     |
| `container`        | <Code>HTMLElement \| ref \| null</Code>             | —                   | Portal target for the popup.                                 |

### NavigationMenuViewport [#navigationmenuviewport]

The surface a panel renders into. The root renders one inside its popup automatically; render your own (with `viewport={false}`) only for an inline submenu.

| Prop        | Type     | Default | Description                                 |
| ----------- | -------- | ------- | ------------------------------------------- |
| `className` | `string` | —       | Extra classes, merged via `tailwind-merge`. |

## Accessibility [#accessibility]

* The bar renders a navigation landmark — give the root an `aria-label`. Triggers carry `aria-expanded` and own their panel via `aria-controls`.
* **↑/↓/←/→** move focus along the bar and into the open panel; **Enter / Space** open an item; **Escape** closes the panel back to its trigger; **Tab** moves through the panel's links.
* Panels open on hover *and* on keyboard focus, so the menu is reachable without a pointer.
* `disabled` triggers are skipped by keyboard navigation.
* The morph, panel, and backdrop transitions are all skipped when the user prefers reduced motion.
