Navigation Menu
Top-level nav with menus.
Usage
Compose Root > List > Item > (Trigger + Content) or a bare Link. Root renders a <nav> landmark, so give it an aria-label.
Marking the current page
Set active on the Link for the page the user is on. Bits then reports aria-current="page", which is the difference between "this looks
highlighted" and "this is announced as where you are". Styling it without that tells sighted
users and nobody else.
Links stay real anchors throughout, so middle-click and open-in-new-tab keep working.
The optional Viewport
Add a Viewport after the List and every Content panel renders inside one shared container — so switching menus
resizes a single surface instead of swapping two boxes. Bits publishes the measured size as --bits-navigation-menu-viewport-width and -height, which is what the transition animates.
Omit it and each panel positions itself against its own trigger. Both are valid; the Viewport just looks calmer when panels differ in size.
Props
NavigationMenu.Root
| Prop | Type | Default |
|---|---|---|
value Which menu is open, by its Item value. Bindable. | string | '' |
class Extra classes merged onto the root. | string | — |
child bits-ui | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children bits-ui | Snippet<[]> | undefined | — |
delayDuration bits-ui The amount of time in ms from when the mouse enters a trigger until the content opens. | number | undefined | 200 |
dir bits-ui The reading direction of the content. | Direction | undefined | "ltr" |
id bits-ui | string | undefined | — |
onValueChange bits-ui The callback to call when a menu item is selected. | OnChangeFn<string> | undefined | — |
orientation bits-ui The orientation of the menu. | Orientation | undefined | — |
ref bits-ui | HTMLElement | null | undefined | — |
skipDelayDuration bits-ui The amount of time in ms that a user has to enter another trigger without incurring a delay again. | number | undefined | 300 |
NavigationMenu.List
| Prop | Type | Default |
|---|---|---|
class Extra classes merged onto the list. | string | — |
child bits-ui | Snippet<[{ wrapperProps: Record<string, unknown>; } & { props: Record<string, unknown>; }] | … | — |
children bits-ui | Snippet<[]> | undefined | — |
id bits-ui | string | undefined | — |
ref bits-ui | HTMLElement | null | undefined | — |
NavigationMenu.Trigger
| Prop | Type | Default |
|---|---|---|
class Extra classes merged onto the trigger. | string | — |
child bits-ui | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children bits-ui | Snippet<[]> | undefined | — |
disabled bits-ui Whether the trigger is disabled. | boolean | null | undefined | false |
id bits-ui | string | undefined | — |
ref bits-ui | HTMLElement | null | undefined | — |
NavigationMenu.Link
| Prop | Type | Default |
|---|---|---|
class Extra classes merged onto the link. | string | — |
active bits-ui Whether the link is the current active page | boolean | undefined | — |
child bits-ui | Snippet<[{ props: Record<string, unknown>; }]> | undefined | — |
children bits-ui | Snippet<[]> | undefined | — |
href html | string | null | undefined | — |
id bits-ui | string | undefined | — |
onSelect bits-ui A callback fired when the link is clicked. Default behavior can be prevented with `event.preventDefault()` | ((e: Event) => void) | undefined | — |
ref bits-ui | HTMLElement | null | undefined | — |
NavigationMenu.Link
List, Trigger, Content and Viewport take class plus their native attributes. Item, Sub and Indicator are re-exported from Bits unchanged.