Menubar
A visually persistent menu common in desktop applications.
When to Use
Use Menubar when you need to:
- Provide a persistent, always-visible menu system like desktop application chrome
- Organize a large number of actions into categorized top-level menus
- Expose keyboard shortcuts alongside their associated actions
- Offer toggleable settings via checkbox or radio items within menus
- Support hierarchical navigation with nested submenus
When Not to Use
- Single context actions - use Dropdown Menu for a standalone trigger
- Right-click actions - use Context Menu for pointer-based activation
- Page-level navigation links - use Navigation Menu for site navigation
- Tabbed content sections - use Tabs for switching between panels
Default
Full menubar with submenus, shortcuts, checkboxes, and radio items.
Simple
Basic menubar with a single menu containing items and keyboard shortcuts.
With Submenus
Menubar with nested submenus for hierarchical navigation and grouped actions.
With Checkbox Items
Menubar with checkbox items for toggling independent settings on and off.
With Radio Items
Menubar with radio items for mutually exclusive selections within a group.
UX & Design Guidelines
Visual Hierarchy
Menubar triggers use bg-background with text-foreground for a neutral baseline. Active triggers switch to bg-accent with text-accent-foreground to indicate the open menu. Order menus by frequency of use (e.g., File, Edit, View) following established desktop conventions.
Spacing & Layout
The menubar renders as a horizontal bar with gap-1 between triggers and p-1 internal padding. Menu content appears with an 8px side offset from the trigger. Use MenubarSeparator to group related items visually. Keep menu depth to two levels (main + one submenu) to avoid cognitive overload.
Responsive Behavior
Menubars are designed for desktop-style interfaces with pointer and keyboard input. On smaller screens, consider replacing the menubar with a Dropdown Menu behind a hamburger icon, or use a Sheet-based navigation for mobile layouts. Menu dropdowns automatically reposition to stay within the viewport.
Color & Contrast
The menubar container uses bg-background with a subtle border and shadow-xs. Dropdown content uses bg-popover with text-popover-foreground for clear separation from the page. Disabled items reduce opacity to 50% while maintaining readability. All interactive states meet WCAG 2.1 AA contrast requirements.
Accessibility
Keyboard Navigation
- Enter or Space — Open a menu from its trigger, or activate a menu item
- ↓ — Open the menu when focused on a trigger, or move to the next item
- ↑ — Move to the previous item in the menu
- → — Move to the next trigger in the menubar, or open a submenu
- ← — Move to the previous trigger in the menubar, or close a submenu
- Esc — Close the current menu and return focus to the trigger
Screen Reader Support
- Built on Radix UI Menubar primitive with full WAI-ARIA
menubarrole - Triggers announce their expanded/collapsed state via
aria-expanded - Checkbox items announce checked/unchecked state via
aria-checked - Radio items announce selection status within their radio group
- Disabled items are announced as unavailable via
data-disabled
Focus Management
Focus is trapped within the open menu. When a menu closes, focus returns to the corresponding trigger. The loop prop enables wrapping from the last item to the first (and vice versa) for continuous keyboard navigation. Triggers receive visible focus styling via focus:bg-accent.
Type-ahead Search
Users can type characters while a menu is open to jump to the first matching item. This enables quick navigation in long menus without scrolling or stepping through items one by one.
ARIA Attributes
{/* Menubar with proper role structure */}
<Menubar>
<MenubarMenu>
<MenubarTrigger>File</MenubarTrigger>
<MenubarContent>
<MenubarItem>New Tab</MenubarItem>
<MenubarItem disabled>New Incognito Window</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>
{/* Checkbox items announce checked/unchecked state */}
<MenubarCheckboxItem checked>
Show Toolbar
</MenubarCheckboxItem>
{/* Radio items announce selection within group */}
<MenubarRadioGroup value="work">
<MenubarRadioItem value="personal">Personal</MenubarRadioItem>
<MenubarRadioItem value="work">Work</MenubarRadioItem>
</MenubarRadioGroup>
{/* Disabled items are announced as unavailable */}
<MenubarItem disabled>
Paste
</MenubarItem>Related Components
Navigation Menu
A collection of links for navigating between pages and sections of a website.
Dropdown Menu
A single-trigger menu for actions or options, ideal for standalone controls.
Tabs
Layered sections of content displayed one at a time via tab triggers.
Context Menu
A menu triggered by right-click, displaying contextual actions at the pointer position.
API Reference
The Menubar is a compound component. Below are the props for each sub-component.
Menubar
Root container. Renders a horizontal bar that holds one or more MenubarMenu groups.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Controlled value of the currently open menu. |
| onValueChange | (value: string) => void | — | Event handler called when the open menu changes. |
| defaultValue | string | — | The value of the menu that is open by default. |
| loop | boolean | false | Whether keyboard navigation should loop from last to first and vice versa. |
| dir | "ltr" | "rtl" | "ltr" | The reading direction for proper arrow key behavior. |
| className | string | — | Additional CSS classes to apply to the menubar root. |
MenubarMenu
Wraps a single trigger and its associated content dropdown.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | A unique value that associates the menu with the menubar for controlled state. |
MenubarTrigger
The button that toggles the menu open and closed.
| Prop | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | When true, renders the child as the trigger element, merging props. |
| className | string | — | Additional CSS classes to apply to the trigger. |
MenubarContent
The dropdown container that holds menu items. Rendered in a portal for proper layering.
| Prop | Type | Default | Description |
|---|---|---|---|
| align | "start" | "center" | "end" | "start" | Alignment of the content relative to the trigger. |
| alignOffset | number | -4 | Offset in pixels from the aligned edge. |
| sideOffset | number | 8 | Distance in pixels from the trigger. |
| className | string | — | Additional CSS classes to apply to the content container. |
MenubarItem
An individual actionable item within a menu.
| Prop | Type | Default | Description |
|---|---|---|---|
| disabled | boolean | false | Prevents the item from being selected or focused. |
| inset | boolean | false | Adds left padding for visual alignment with checkbox and radio items. |
| variant | "default" | "destructive" | "default" | The visual style variant of the item. |
| onSelect | (event: Event) => void | — | Event handler called when the item is selected. |
MenubarCheckboxItem
A toggleable menu item with a checkmark indicator.
| Prop | Type | Default | Description |
|---|---|---|---|
| checked | boolean | false | Whether the checkbox item is checked. |
| onCheckedChange | (checked: boolean) => void | — | Event handler called when the checked state changes. |
| disabled | boolean | false | Prevents the item from being toggled. |
MenubarRadioGroup
Groups radio items for mutually exclusive selection.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | The value of the currently selected radio item. |
| onValueChange | (value: string) => void | — | Event handler called when the selected radio item changes. |