# Navigation menu

Host: Radix UI. Path: keyframes. Preset: `fade`. Built against [radix-ui 1.6.7](https://www.npmjs.com/package/radix-ui/v/1.6.7).

A navigation menu is a bar plus one shared viewport that the open panel renders into, which is why it needs more markup than the other hosts. It is also the one real name collision: Radix writes its own data-motion on Content, so easeful guards against its four values and leaves the component alone unless you opt in. Author props spread last, so an explicit value still wins.

The page this file mirrors mounts the component twice, once with the attribute and once without, so the only difference between the two is the library.

Upstream documentation: [Radix UI documentation](https://www.radix-ui.com/primitives/docs/components/navigation-menu)

The same component in other hosts: [Base UI](/base-ui/navigation-menu.md).

## Where the attribute goes

The parts this demo composes, and the value each one carries. Everything inside an animated part is that part's content, so the tree stops there.

```text
NavigationMenu.Root
  NavigationMenu.List
    NavigationMenu.Item
      NavigationMenu.Trigger
      NavigationMenu.Content
  NavigationMenu.Viewport  data-motion="fade"
```

## How the match works

| Step | Value |
| --- | --- |
| host writes | `data-motion="from-start" \| "to-end", written by Radix itself` |
| easeful matches | `[data-motion]:where(:not([data-motion^="from-"], [data-motion^="to-"]))` |
| what runs | `nothing, unless you set the attribute yourself` |
| you write | `<NavigationMenu.Content data-motion="fade" />` |

## Every value that works here

Every value the manifest allows on this host, single presets and the pairs that compose. The first is what this component ships with. Both stages are the same component, so anything that changes between them is the attribute.

| Value | Link |
| --- | --- |
| `fade` | the default |
| `scale-fade` | [scale-fade](/radix/navigation-menu#motion=scale-fade) |
| `slide-up` | [slide-up](/radix/navigation-menu#motion=slide-up) |
| `fade slide-up` | [fade slide-up](/radix/navigation-menu#motion=fade%20slide-up) |
| `scale-fade slide-up` | [scale-fade slide-up](/radix/navigation-menu#motion=scale-fade%20slide-up) |

## Source

`apps/docs/components/demos/radix/navigation-menu.tsx`

```tsx
"use client"

import { NavigationMenu } from "radix-ui"
import type { DemoProps } from "@/components/demos/props"

/* A navigation menu is a bar plus a shared viewport, not a stack of loose
 * panels. The Viewport is what the open Content renders into, and Radix reports
 * its size through two custom properties so the box can resize between items.
 * Radix also writes its own data-motion on Content, which is the collision this
 * page exists to show. */
export function RadixNavigationMenu({ motion }: DemoProps) {
  return (
    <NavigationMenu.Root className="navmenu">
      <NavigationMenu.List className="navmenu__list">
        <NavigationMenu.Item>
          <NavigationMenu.Trigger className="tab">Products</NavigationMenu.Trigger>
          <NavigationMenu.Content className="navmenu__content">
            <a className="navmenu__link" href="#products">
              Motion presets
            </a>
            <a className="navmenu__link" href="#products">
              Host adapters
            </a>
            <a className="navmenu__link" href="#products">
              Generated types
            </a>
          </NavigationMenu.Content>
        </NavigationMenu.Item>
        <NavigationMenu.Item>
          <NavigationMenu.Trigger className="tab">Company</NavigationMenu.Trigger>
          <NavigationMenu.Content className="navmenu__content">
            <a className="navmenu__link" href="#company">
              About
            </a>
            <a className="navmenu__link" href="#company">
              Changelog
            </a>
          </NavigationMenu.Content>
        </NavigationMenu.Item>
      </NavigationMenu.List>
      <div className="navmenu__viewport-wrap">
        <NavigationMenu.Viewport className="navmenu__viewport" data-motion={motion} />
      </div>
    </NavigationMenu.Root>
  )
}
```
