# NavigationMenu

> Site or product navigation with optional flyout panels of links, using the disclosure pattern.

Category: Navigation · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/navigation-menu

Use NavigationMenu for the primary navigation of a website or product, such as the Binds marketing header. Panels are revealed by disclosure buttons and contain ordinary links, which is the correct semantic for navigation; role="menu" is reserved for application commands (see DropdownMenu and Menubar). A vertical orientation expands panels inline for sidebars and mobile drawers.

## Import

```tsx
import { NavigationMenu, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Site header

```tsx
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from '@bindshq/stance-react';

export function Basic() {
  return (
    <NavigationMenu aria-label="Main">
      <NavigationMenuItem>
        <NavigationMenuLink href="#home" active>
          Home
        </NavigationMenuLink>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Products</NavigationMenuTrigger>
        <NavigationMenuContent>
          <NavigationMenuLink href="#esignify">eSignify</NavigationMenuLink>
          <NavigationMenuLink href="#stance">Stance</NavigationMenuLink>
        </NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuTrigger>Company</NavigationMenuTrigger>
        <NavigationMenuContent>
          <NavigationMenuLink href="#about">About Binds</NavigationMenuLink>
          <NavigationMenuLink href="#privacy">Privacy</NavigationMenuLink>
          <NavigationMenuLink href="#terms">Terms</NavigationMenuLink>
        </NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuLink href="#contact">Contact</NavigationMenuLink>
      </NavigationMenuItem>
    </NavigationMenu>
  );
}
```

### Rich panel

Links can carry an icon and a description.

```tsx
import { Icon, NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from '@bindshq/stance-react';

export function RichPanel() {
  return (
    <NavigationMenu aria-label="Products">
      <NavigationMenuItem>
        <NavigationMenuTrigger>Products</NavigationMenuTrigger>
        <NavigationMenuContent>
          <NavigationMenuLink
            href="#esignify"
            icon={<Icon name="mail" />}
            description="Consistent email signatures for every employee."
          >
            eSignify
          </NavigationMenuLink>
          <NavigationMenuLink
            href="#stance"
            icon={<Icon name="layout-grid" />}
            description="The open-source Binds design system."
          >
            Stance
          </NavigationMenuLink>
          <NavigationMenuLink
            href="#integrations"
            icon={<Icon name="zap" />}
            description="Microsoft 365 and Exchange deployment."
          >
            Integrations
          </NavigationMenuLink>
        </NavigationMenuContent>
      </NavigationMenuItem>
      <NavigationMenuItem>
        <NavigationMenuLink href="#pricing">Pricing</NavigationMenuLink>
      </NavigationMenuItem>
    </NavigationMenu>
  );
}
```

### Vertical (sidebar)

Panels expand inline and do not open on hover.

```tsx
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger } from '@bindshq/stance-react';

export function Vertical() {
  return (
    <div style={{ width: 240 }}>
      <NavigationMenu aria-label="Dashboard" orientation="vertical" defaultValue="templates">
        <NavigationMenuItem>
          <NavigationMenuLink href="#dashboard">Dashboard</NavigationMenuLink>
        </NavigationMenuItem>
        <NavigationMenuItem value="templates">
          <NavigationMenuTrigger>Templates</NavigationMenuTrigger>
          <NavigationMenuContent>
            <NavigationMenuLink href="#my-templates" active>
              My templates
            </NavigationMenuLink>
            <NavigationMenuLink href="#gallery">Gallery</NavigationMenuLink>
          </NavigationMenuContent>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuLink href="#users">Organisation users</NavigationMenuLink>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuLink href="#settings">Settings</NavigationMenuLink>
        </NavigationMenuItem>
      </NavigationMenu>
    </div>
  );
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| NavigationMenu | `aria-label` | `string` | None | Name of the navigation landmark, e.g. “Main”. Required when a page has more than one nav. |
| NavigationMenu | `value / defaultValue` | `string \| null` | None | The open panel (controlled or initial). |
| NavigationMenu | `onValueChange` | `(value: string \| null) => void` | None | Called when a panel opens or closes. |
| NavigationMenu | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Vertical expands panels inline. |
| NavigationMenu | `openOnHover` | `boolean` | `true (horizontal)` | Open panels on mouse hover after a short delay. |
| NavigationMenuItem | `value` | `string` | None | Identifier for the item’s panel. Generated by default. |
| NavigationMenuTrigger | `...props` | `ButtonHTMLAttributes` | None | Disclosure button with aria-expanded and aria-controls. |
| NavigationMenuContent | `forceMount` | `boolean` | `true` | Keep the panel in the DOM while hidden so its links stay indexable. |
| NavigationMenuLink | `active` | `boolean` | `false` | Marks the current page with aria-current="page". |
| NavigationMenuLink | `description` | `ReactNode` | None | Secondary line in rich panels. |
| NavigationMenuLink | `icon` | `ReactNode` | None | Leading visual in rich panels. |
| NavigationMenuLink | `asChild` | `boolean` | `false` | Render your router’s link component. |

## Accessibility

- Renders a nav landmark containing a list, so screen readers announce the number of entries.
- Triggers are buttons with aria-expanded and aria-controls (WAI-ARIA disclosure navigation), not menus.
- The current page link carries aria-current="page".
- Escape closes the open panel and returns focus to its trigger; moving focus out of the navigation closes it.
- Hover opening is a convenience only; every panel opens by click and keyboard as well.

## Keyboard

| Keys | Action |
| --- | --- |
| `Tab` | Move through triggers and links in order. |
| `ArrowLeft` `ArrowRight` | Move between top-level entries (ArrowUp/ArrowDown when vertical). |
| `Home` `End` | First or last top-level entry. |
| `Enter` `Space` | Toggle a panel. |
| `ArrowDown` | On a trigger: open its panel and focus the first link. |
| `ArrowUp` `ArrowDown` | Inside a panel: move between its links. |
| `Escape` | Close the panel and return to its trigger. |

## Guidelines

**Do**

- Keep top-level labels to one or two words.
- Mark the current section with active.

**Don’t**

- Put actions (buttons that change data) in navigation panels.
- Use DropdownMenu for site navigation.

## Related

- https://stanceui.com/components/sidebar
- https://stanceui.com/components/breadcrumbs
- https://stanceui.com/components/tabs
- https://stanceui.com/components/menubar
