Menu
A button that opens a menu of actions, with support for submenus and horizontal menubars.
Usage
import { Menu } from "monochrome/react"
<Menu.Root>
<Menu.Trigger>Account</Menu.Trigger>
<Menu.Popover>
<Menu.Label>Settings</Menu.Label>
<Menu.Item>Profile</Menu.Item>
<Menu.Item>Preferences</Menu.Item>
<Menu.Separator />
<Menu.Item>Sign Out</Menu.Item>
</Menu.Popover>
</Menu.Root>Examples
Disabled Items
Disabled items are skipped during keyboard navigation.
<Menu.Root>
<Menu.Trigger>Actions</Menu.Trigger>
<Menu.Popover>
<Menu.Item>Edit</Menu.Item>
<Menu.Item disabled>Delete</Menu.Item>
</Menu.Popover>
</Menu.Root>Checkbox and Radio Items
Use CheckboxItem for togglable options and RadioItem for single-select groups. These items stay open after interaction so users can make multiple selections.
<Menu.Root>
<Menu.Trigger>Format</Menu.Trigger>
<Menu.Popover>
<Menu.CheckboxItem checked>Bold</Menu.CheckboxItem>
<Menu.CheckboxItem checked={false}>Italic</Menu.CheckboxItem>
<Menu.Separator />
<Menu.RadioItem checked>Small</Menu.RadioItem>
<Menu.RadioItem checked={false}>Medium</Menu.RadioItem>
<Menu.RadioItem checked={false}>Large</Menu.RadioItem>
</Menu.Popover>
</Menu.Root>Submenus
Nest a Menu.Group inside a Menu.Popover to create submenus. Toggle alignment and the safe zone debug triangle to see how pointer tracking works across menu levels.
Menubar
A horizontal bar of dropdown menus for application-style navigation. Pass the menubar prop to enable menubar mode.
import { Menu } from "monochrome/react"
<Menu.Root menubar>
<Menu.Popover>
<Menu.Group>
<Menu.Trigger>File</Menu.Trigger>
<Menu.Popover>
<Menu.Item>New File</Menu.Item>
<Menu.Item>Save</Menu.Item>
</Menu.Popover>
</Menu.Group>
<Menu.Group>
<Menu.Trigger>Edit</Menu.Trigger>
<Menu.Popover>
<Menu.Item>Undo</Menu.Item>
<Menu.Item>Redo</Menu.Item>
</Menu.Popover>
</Menu.Group>
</Menu.Popover>
</Menu.Root>Dropdown vs Menubar
| Aspect | Dropdown | Menubar |
|---|---|---|
| Structure | Menu.Root with Menu.Trigger + Menu.Popover | Menu.Root with menubar prop, Menu.Popover containing Menu.Groups |
| Activation | Click to open | Click first, then hover switches |
| Arrow Keys | Up/Down navigate items | Left/Right switch menus |
| Role | role="menu" | role="menubar" |
Accessibility
Follows the WAI-ARIA Menu Button Pattern and WAI-ARIA Menu Bar Pattern.
Keyboard
| Key | Action |
|---|---|
Enter / Space | Open menu, activate item, or toggle checkbox/radio |
Arrow Down | Move focus to next item |
Arrow Up | Move focus to previous item |
Arrow Right | Open submenu, or move to next menu (menubar) |
Arrow Left | Close submenu, or move to previous menu (menubar) |
Home | Move focus to first item |
End | Move focus to last item |
Escape | Close menu and return focus to trigger |
a - z | Cyclic typeahead, focus next item starting with that letter |
Disabled items and separators are skipped during keyboard navigation. Checkbox and radio items toggle on click or Enter/Space without closing the menu. In menubar mode, hovering over other triggers automatically switches menus after the first click.
API Reference
HTML
| Element | Attributes | Description |
|---|---|---|
| Root | id="mcr:menu:*" | Root ID (required) |
| Trigger | id="mct:menu:*" | Trigger ID (required) |
aria-controls | Menu list ID | |
aria-expanded | "true" or "false" | |
aria-haspopup="menu" | Indicates menu popup | |
| Menu list | role="menu" | Menu container |
id="mcc:menu:*" | Menu ID (required) | |
aria-labelledby | Trigger element ID | |
aria-hidden | "true" or "false" | |
popover="manual" | Popover behavior | |
| Menu item | role="menuitem" | Menu item |
tabindex="-1" | Focus managed programmatically | |
aria-disabled="true" | For disabled items | |
| Checkbox item | role="menuitemcheckbox" | Togglable menu item |
aria-checked | "true" or "false" | |
| Radio item | role="menuitemradio" | Single-select menu item |
aria-checked | "true" or "false" | |
| Separator | role="separator" | Visual divider between groups |
| Label | role="presentation" | Non-interactive section title |
| Menubar | role="menubar" | Horizontal menu structure |
Trigger tabindex | 0 for first, -1 for others |
React
All components accept className for styling.
Menu.Root
The root container.
| Prop | Type | Default | Description |
|---|---|---|---|
menubar | boolean | false | Enable menubar mode for horizontal menu bars |
Menu.Trigger
The button that opens the dropdown.
Menu.Popover
The container for menu items. Uses the Popover API. In menubar mode, renders as a <ul role="menubar">.
Menu.Item
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Whether the item is disabled (renders as <span>) |
href | string | — | URL for link items (renders as <a>) |
Menu.CheckboxItem
A togglable menu item. Clicking toggles aria-checked between "true" and "false". The menu stays open after interaction.
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | false | Whether the item is checked |
disabled | boolean | false | Whether the item is disabled (renders as <span>) |
Menu.RadioItem
A single-select menu item. Clicking checks the item and unchecks others in the same implicit group. The menu stays open after interaction. Radio groups are determined by DOM position. Consecutive radio items form a group, separated by non-radio items (separators, labels, regular items).
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | false | Whether the item is checked |
disabled | boolean | false | Whether the item is disabled (renders as <span>) |
Menu.Separator
A visual divider between menu item groups. Skipped during keyboard navigation.
Menu.Label
A non-interactive section title within a menu. Renders as <li role="presentation">. Skipped during keyboard navigation.
Menu.Group
Container for nested submenus. Contains a Menu.Trigger and Menu.Popover.