Menubar
The File, Edit, View row of a desktop-style app. One tab stop, arrow keys across the menus, and once one is open the next opens on hover. The menus are Dropdown Menu's panels, so both read as one object.
Installation#
Usage#
import {
Menubar,
MenubarMenu,
MenubarTrigger,
MenubarContent,
MenubarItem,
MenubarShortcut,
} from "@/components/ui/menubar"
export function Example() {
return (
<Menubar>
<MenubarMenu>
<MenubarTrigger>File</MenubarTrigger>
<MenubarContent>
<MenubarItem>
New document <MenubarShortcut>⌘N</MenubarShortcut>
</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>
)
}Anatomy#
import {
Menubar,
MenubarMenu,
MenubarTrigger,
MenubarContent,
MenubarItem,
MenubarCheckboxItem,
MenubarRadioGroup,
MenubarRadioItem,
MenubarLabel,
MenubarSeparator,
MenubarShortcut,
MenubarSub,
MenubarSubTrigger,
MenubarSubContent,
} from "@/components/ui/menubar"
<Menubar>
<MenubarMenu>
<MenubarTrigger />
<MenubarContent>
<MenubarLabel />
<MenubarItem>
<MenubarShortcut />
</MenubarItem>
<MenubarCheckboxItem />
<MenubarRadioGroup>
<MenubarRadioItem />
</MenubarRadioGroup>
<MenubarSeparator />
<MenubarSub>
<MenubarSubTrigger />
<MenubarSubContent>…</MenubarSubContent>
</MenubarSub>
</MenubarContent>
</MenubarMenu>
</Menubar>Variants#
outline (the default) is the Toolbar's band: a 12px radius around 4px of padding and 8px triggers, so the corners nest concentrically, with an inset edge that takes no layout. plain drops the band for an app header that already owns one. Either way the open menu lights its trigger, so the bar always shows which menu you are in.
Checkbox, radio and switch rows#
The rows are Dropdown Menu's: a checked row or the chosen radio carries the ink check on the right, on the same 12px edge line as the shortcuts. variant="switch" on a checkbox row draws a mini Switch there instead, for a setting that applies the moment it flips, and keeps the menu open so several can be flipped in a row.
Density#
The menus follow the density around the bar: 36px rows when comfortable, 32px when compact. React context crosses the portal the menus open in, so one DensityProvider around the bar sets every menu in it. The edge inset and the corners stay put at either density.
Keyboard#
The whole bar is one tab stop. Left and Right move between menus, Down or Enter opens one, and once a menu is open, Left and Right (or the pointer) open its neighbours instead, the way an application menu behaves. Escape closes the menu and puts focus back on its trigger. Shortcuts are display only: bind the keys yourself.
API reference#
Menubar
The bar, role="menubar", over Radix Menubar.Root, and forwards its props. Every part accepts className, merged last.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "outline" | "plain" | "outline" | outline is the concentric band with an inset edge; plain drops it for a header that owns one. |
| value | string | - | The open menu's value, controlled. |
| defaultValue | string | - | The menu open on first render, uncontrolled. |
| onValueChange | (value: string) => void | - | Called when a menu opens or closes (an empty string when none is open). |
| loop | boolean | true | Arrow keys wrap from the last trigger to the first. |
| dir | "ltr" | "rtl" | - | Reading direction for arrow-key navigation. |
MenubarMenu
One menu: wraps its trigger and content. Radix Menubar.Menu, re-exported as is.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | - | Identifies the menu for the bar's value. Generated when omitted. |
MenubarTrigger
The button that opens its menu; it lights while the menu is open. Forwards Radix Menubar.Trigger props.
| Data attribute | Description |
|---|---|
| data-state | open while its menu is open, otherwise closed. |
| data-highlighted | Present while the trigger has keyboard focus. |
| data-disabled | Present when disabled. |
MenubarContent
The menu panel, portalled to the body and built from Dropdown Menu's recipe. Forwards Radix Menubar.Content props.
| Prop | Type | Default | Description |
|---|---|---|---|
| align | "start" | "center" | "end" | "start" | Alignment against the trigger. |
| alignOffset | number | -2 | Puts the rows' text on the trigger's text line. |
| sideOffset | number | 8 | Gap from the trigger, clearing the band's padding. |
| collisionPadding | number | 8 | Keeps the panel off the viewport edge. |
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
| Data attribute | Description |
|---|---|
| data-state | open or closed, for the enter and exit animation. |
| data-side | The side the panel landed on after collision handling. |
| data-align | The resolved alignment. |
| CSS variable | Description |
|---|---|
| --radix-menubar-content-transform-origin | The point the panel scales from, set by Radix. |
| --radix-menubar-content-available-height | Room between the trigger and the viewport edge. |
MenubarItem
A command row. Forwards Radix Menubar.Item props (onSelect, disabled, textValue).
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "destructive" | "default" | destructive turns the whole row red, icon included. |
| inset | boolean | false | Indents the text to line up with icon-bearing rows. |
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
| Data attribute | Description |
|---|---|
| data-highlighted | Present while the row is highlighted by pointer or keyboard. |
| data-disabled | Present when disabled. |
| data-inset | Present when inset. |
MenubarCheckboxItem
A toggle row. Forwards Radix Menubar.CheckboxItem props (checked, onCheckedChange).
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "check" | "switch" | "check" | check is the ink check; switch is a mini Switch, for a setting that applies the moment it flips. |
| closeOnSelect | boolean | - | Closes the menu on toggle. Defaults to true for check and false for switch. |
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
| Data attribute | Description |
|---|---|
| data-state | checked, unchecked or indeterminate. |
| data-highlighted | Present while the row is highlighted. |
| data-disabled | Present when disabled. |
MenubarRadioGroup
Groups radio rows. Radix Menubar.RadioGroup, re-exported as is.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | - | The checked row's value. |
| onValueChange | (value: string) => void | - | Called when another row is picked. |
MenubarRadioItem
One exclusive choice inside a MenubarRadioGroup, sharing the checkbox row's ink check. Forwards Radix Menubar.RadioItem props.
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | string | - | The value the group reports. |
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
| Data attribute | Description |
|---|---|
| data-state | checked or unchecked. |
| data-highlighted | Present while the row is highlighted. |
MenubarLabel
A non-interactive heading over a run of rows. Forwards Radix Menubar.Label props.
| Prop | Type | Default | Description |
|---|---|---|---|
| inset | boolean | false | Indents the text to line up with icon-bearing rows. |
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
MenubarSeparator
A hairline between groups of rows. Forwards Radix Menubar.Separator props.
| Prop | Type | Default | Description |
|---|---|---|---|
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
MenubarShortcut
The row's shortcut, a small Kbd chip on the right edge. Display only: bind the keys yourself. Forwards Kbd props.
MenubarGroup
Groups related rows for assistive tech. Radix Menubar.Group, re-exported as is.
MenubarSub
A nested menu: wraps a sub-trigger and its panel. Radix Menubar.Sub, re-exported as is.
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | - | Controlled open state. |
| defaultOpen | boolean | - | Open on first render, uncontrolled. |
| onOpenChange | (open: boolean) => void | - | Called when the submenu opens or closes. |
MenubarSubTrigger
The row that opens a submenu, with a trailing caret. Forwards Radix Menubar.SubTrigger props.
| Prop | Type | Default | Description |
|---|---|---|---|
| inset | boolean | false | Indents the text to line up with icon-bearing rows. |
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
| Data attribute | Description |
|---|---|
| data-state | open while its submenu is open, otherwise closed. |
| data-highlighted | Present while the row is highlighted. |
MenubarSubContent
The submenu panel, portalled to the body. Forwards Radix Menubar.SubContent props.
| Prop | Type | Default | Description |
|---|---|---|---|
| density | "comfortable" | "compact" | - | Row height (36 or 32px). Inherits the nearest DensityProvider when unset. |
| Data attribute | Description |
|---|---|
| data-state | open or closed. |
| data-side | The side the panel landed on. |
MenubarPortal
Radix Menubar.Portal, re-exported for custom panels. MenubarContent and MenubarSubContent already portal themselves.