<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# NavigationMenu

A row of links where some open a panel of further links, each with a line of description: the navigation of a site with more pages than fit in a bar. Panels open on hover or click, move between each other without closing, and close on Escape, on an outside press and when a link is chosen. The current page is marked `aria-current="page"` and a bar at the start edge, distinct from hover and press highlights. Built on Base UI's Navigation Menu.

```tsx
import { NavigationMenu } from "@/components/ouro/navigation-menu/navigation-menu";
```

## Example

```tsx
<NavigationMenu
  label="Main"
  items={[
    {
      label: "Recipes",
      links: [
        { label: "Browse", href: "/recipes", description: "Everything you have saved." },
        { label: "Import", href: "/recipes/import", description: "Bring one in from a link." },
      ],
    },
    { label: "Pricing", href: "/pricing" },
  ]}
  currentPath={pathname}
/>
```

## Usage

Use `Menu` for actions rather than pages, and `Sidebar` for a column of links.

## Use instead when

- Use `Navbar` instead when every item is a plain link; it also collapses into a drawer on a phone, which this row does not.

## Props

Type: `NavigationMenuProps`.

| Prop | Type | Description |
| --- | --- | --- |
| `className` | `string` | Layout only: margins, grid placement (`ms-4`). Appearance classes warn in development. |
| `currentPath` | `string` | The path of the page being shown, from your router (`useLocation().pathname`, or `usePathname()` in Next.js). The link to that path, or else the longest link above it, gets `aria-current="page"`, in the row or in a panel. |
| `items` (required) | `readonly NavigationMenuItem[]` | The row's items, in order: links, and buttons that open a panel of links. |
| `label` (required) | `string` | Names the navigation for screen readers ("Main"). It is not shown. |
| `ref` | `Ref<HTMLElement>` | Reaches the rendered element. |

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `children`: Not rendered. The menu is data: `items={[{ label: "Recipes", links: [...] }, { label: "Pricing", href: "/pricing" }]}`.
- `links`: Not a prop. Ouro UI uses `items`; a panel's links go in an item's `links`.
- `orientation`: Not a prop. The menu is a row; for a column of links use `Sidebar`.
- `pathname`: Not a prop. Ouro UI uses `currentPath`: `<NavigationMenu currentPath={pathname}>`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`).

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `NavigationMenuItem`

One item of a NavigationMenu: a link (`href`), or a button that opens a panel (`links`, `content`).

```ts
type NavigationMenuItem = NavigationMenuLinkItem | NavigationMenuPanelItem;
```

### `NavigationMenuLink`

One link inside a NavigationMenu panel.

```ts
interface NavigationMenuLink {
  /** The link's text: "Browse". */
  label: string;
  /** Where it goes. Internal paths go through `OuroProvider`'s `linkComponent` (your router's link). */
  href: string;
  /**
   * A line under the label that says what is there: "Everything you have saved."
   */
  description?: string | undefined;
  /** Marks this link as the current page, when the menu's `currentPath` cannot tell. */
  current?: boolean | undefined;
}
```

### `NavigationMenuLinkItem`

A NavigationMenu item that is a link to a page.

```ts
interface NavigationMenuLinkItem {
  /** The link's text: "Pricing". */
  label: string;
  /** Where it goes. Internal paths go through `OuroProvider`'s `linkComponent` (your router's link). */
  href: string;
  /** Marks this link as the current page, when the menu's `currentPath` cannot tell. */
  current?: boolean | undefined;
  /** Not with `href`. An item is a link (`href`) or a panel (`links`, `content`). */
  links?: never;
  /** Not with `href`. An item is a link (`href`) or a panel (`links`, `content`). */
  content?: never;
}
```

### `NavigationMenuPanelItem`

A NavigationMenu item that opens a panel: a list of `links`, with any `content` at its start, such as a featured `Card` beside a two-column grid of links. A panel needs one of the two.

```ts
type NavigationMenuPanelItem = NavigationMenuPanelBase &
  (
    | {
        /**
         * The links in the panel, each with an optional `description`.
         */
        links: readonly NavigationMenuLink[];
        /**
         * Anything else in the panel, before its links (above them on a phone): a featured
         * `Card`, an image, a line of text. A link in it closes the panel when it is followed.
         */
        content?: ReactNode;
      }
    | {
        links?: undefined;
        /**
         * The panel's content, when it has no list of links. A link in it closes the panel when it is followed.
         */
        content: ReactNode;
      }
  );
```
