Navigation menu
Small words open a panel of large names, the scale contrast of a poster; or a contents page with one name set as the headline; or the names opened into the line itself.
Report an issue with Navigation menuExample
Rest
Pointed at
Lead, open
Inline, open
Inline, open, right to left
Install
Run it in a project that has the shadcn CLI set up. It brings the 0nlyType base along.
npx shadcn@latest add https:// thedirectors.agency/ ui/ r/navigation-menu.jsonUsage
"use client"import {NavigationMenu,NavigationMenuContent,NavigationMenuItem,NavigationMenuLink,NavigationMenuList,NavigationMenuTrigger,type NavigationMenuProps,} from "@/components/ui/navigation-menu"const menu = {Work: [["Identity", "Names, marks, and the rules that keep them"],["Websites", "Built to be read slowly and used for years"],["Motion", "Titles, idents and things that move once"],],Studio: [["People", "Six of us, in Stockholm and Lisbon"],["Process", "How a project runs, week by week"],["Journal", "Notes on type, space and slowness"],],}type Menu = Pick<NavigationMenuProps, "variant" | "value"> & { label: string; force?: string }function Studio({ variant, value, label, force }: Menu) {return (<NavigationMenu aria-label={label} variant={variant} value={value}><NavigationMenuList>{Object.entries(menu).map(([word, names], i) => (<NavigationMenuItem key={word} value={word.toLowerCase()}><NavigationMenuTrigger data-force={i === 0 ? force : undefined}>{word}</NavigationMenuTrigger><NavigationMenuContent>{names.map(([name, line]) => (<NavigationMenuLink key={name} href={`#${name.toLowerCase()}`}>{name}<small>{line}</small></NavigationMenuLink>))}</NavigationMenuContent></NavigationMenuItem>))}<NavigationMenuItem><NavigationMenuLink href="#contact">Contact</NavigationMenuLink></NavigationMenuItem></NavigationMenuList></NavigationMenu>)}export default function Example() {return (<div className="grid w-full gap-12"><div className="grid content-start gap-3" style={{ minHeight: "17rem" }}><span className="ot-label">Names</span><Studio label="Studio" /></div><div className="grid content-start gap-3" style={{ minHeight: "19rem" }}><span className="ot-label">Lead</span><Studio label="Studio, as contents" variant="lead" /></div><div className="grid content-start gap-3"><span className="ot-label">Inline, press a word</span><Studio label="Studio, in a line" variant="inline" /></div></div>)}Contract
- Underneath: Radix NavigationMenu.
- Anatomy:
<nav class="ot-navmenu">of small trigger buttons (aria-expanded,aria-controls) and.ot-navmenu-panelpanels of large links. - Small words open a panel of large names, the scale contrast of a poster. The panel's rule draws across, the names arrive in turn, and the trigger's arrow turns. It opens on pointing (after a short wait) or pressing, and closes on leaving.
varianton the root (data-variant):names(the default),leadorinline.- lead: a magazine's contents page, and WOVE's "03 Ambient". The names stand small (
mp, graphite) in a narrow column; the one pointed at or focused (the first, at first) is inked there and set beside the column as the headline atff200, its<small>line under it in graphite. The headline is an aria-hidden copy (.ot-navmenu-lead); the links keep their own names. Below 40rem the headline stands down and the names keep their lines. - inline: "Healthy habits → for creatives", one line of thought. The trigger's arrow is → (← right to left). A press, never a passing pointer, opens the names into the line after the word, larger (
mf200) on the same baseline; the words after it make room, and the other words step back to pencil. The<small>lines stay for screen readers only. Below 40rem the names drop tompand may wrap. - Keyboard: Enter or Space toggles a panel; Escape closes it and returns focus to its trigger. Tab moves from an open trigger into its names. Without a
dir, the menu takes the direction of the page around it as it mounts, so it mirrors on a right-to-left page. It reads it once, at mount, as the menus do: a page that changesdirafterwards passesdiritself, or remounts the menu.
Props
| Prop | Type | Default | What it does |
|---|---|---|---|
NavigationMenu variant | "names" | "lead" | "inline" | "names" | names: a panel of large names hung under the menu. lead: the names small in a narrow column, and the one you point at or focus (the first, at first) set beside them as the headline with its <small> line; below 40rem the names keep their lines instead. inline: a press (not a passing pointer) opens the names into the line after the word, larger, on one baseline; the words after make room and the others step back to pencil. |
NavigationMenu dir | "ltr" | "rtl" | Left out, the menu takes the direction of the page around it as it mounts, so on a right-to-left page its words run from the right and the arrow keys follow. | |
NavigationMenuTrigger | button | A small word. Its ↓ turns over while the panel is open. Opens on pointing after a short wait, or on Enter and Space. | |
NavigationMenuContent | div | The panel, hung under the whole menu. Its children are NavigationMenuLinks, each a large name with an optional <small> line. Its rule draws across and the names arrive in turn. | |
NavigationMenuLink | a | Inside a panel, a large name. Directly in an item, a small word like a trigger. asChild renders your own link. | |
delayDuration / skipDelayDuration | number | Radix's pointer waits, on NavigationMenu. |
Craft
Where its move comes from
| Component | Reference | Move |
|---|---|---|
| Navigation menu | POINT / SPECTRA | Small words open large names |
| Lead navigation menu | WOVE; a magazine's contents page | The name you point at stands as the headline beside the list |
| Inline navigation menu | "Healthy habits → for creatives" | The names open into the line of thought |
How it moves
| Component | Articulation | What moves |
|---|---|---|
| Navigation menu | Arpeggio | The rule draws across; the names arrive; the arrow turns |
| Lead navigation menu | Step up | The name you point at steps up into the headline |
| Inline navigation menu | Opening | The line opens after the word and the words after it make room; the arrow inks and leans toward the names |