Menubar
An accessible horizontal menubar with menus, submenus, and selection items.
Features
- Horizontal menus
- Checkbox and radio items
- Nested submenus
- Typeahead
- Managed focus
Installation
npm install @ariaui/menubar
Examples
Horizontal menubar with nested menus plus checkbox and radio items. Arrow keys traverse items and open submenus.
Menubar
A menubar with nested menus, item variants, and keyboard navigation.
No preview output yet.
Framer Motion
A menubar with the same structure and style animated through Framer Motion and asChild composition.
No preview output yet.
Anatomy
import * as Menubar from "@ariaui/menubar";
export default function Example() {
return (
<Menubar.Root>
<Menubar.Menu>
<Menubar.Trigger />
<Menubar.Content>
<Menubar.Item />
<Menubar.Separator />
<Menubar.CheckboxItem>
<Menubar.ItemIndicator />
</Menubar.CheckboxItem>
<Menubar.RadioGroup>
<Menubar.Label />
<Menubar.RadioItem>
<Menubar.ItemIndicator />
</Menubar.RadioItem>
</Menubar.RadioGroup>
<Menubar.Group>
<Menubar.Label />
</Menubar.Group>
<Menubar.Sub>
<Menubar.SubTrigger />
<Menubar.SubContent>
<Menubar.Item />
</Menubar.SubContent>
</Menubar.Sub>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root>
);
}
API Reference
Root
Horizontal menubar container. Tracks the currently open menu and provides arrow-key navigation between triggers.
| Prop | Type | Default |
|---|---|---|
value | string | — |
defaultValue | string | — |
onValueChange | (value: string) => void | — |
loop | boolean | false |
| Attribute | Values |
|---|---|
| role | menubar |
| data-orientation | horizontal |
Trigger
Button that opens its menu on click, Enter, Space, or ArrowDown.
| Attribute | Values |
|---|---|
| [data-state] | open | closed |
| aria-haspopup | menu |
| aria-expanded | true when the menu is open |
| aria-controls | ID of the Content element |
Content
Floating panel containing menu items. Positioned relative to its Trigger and closes on outside click or Escape.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
loop | boolean | false |
| Attribute | Values |
|---|---|
| role | menu |
| [data-state] | open | closed |
| [data-side] | top | right | bottom | left |
| [data-align] | start | center | end |
Item
A selectable command inside a menu.
| Prop | Type | Default |
|---|---|---|
textValue | string | — |
onSelect | (event: Event) => void | — |
disabled | boolean | false |
| Attribute | Values |
|---|---|
| role | menuitem |
| [data-active] | true when focused/hovered |
| [data-disabled] | present when disabled |
CheckboxItem
Menu item with a toggleable checked state.
| Prop | Type | Default |
|---|---|---|
checked | boolean | — |
defaultChecked | boolean | false |
onCheckedChange | (checked: boolean) => void | — |
| Attribute | Values |
|---|---|
| role | menuitemcheckbox |
| aria-checked | true | false |
RadioGroup
Groups RadioItems so only one can be selected at a time.
| Prop | Type | Default |
|---|---|---|
value | string | — |
defaultValue | string | — |
onValueChange | (value: string) => void | — |
| Attribute | Values |
|---|---|
| role | group |
RadioItem
Selectable item inside a RadioGroup.
| Prop | Type | Default |
|---|---|---|
value* | string | — |
| Attribute | Values |
|---|---|
| role | menuitemradio |
| aria-checked | true | false |
ItemIndicator
Renders only when its parent CheckboxItem or RadioItem is checked.
Group
Groups related menu items. Associates with Label via aria-labelledby when present.
| Attribute | Values |
|---|---|
| role | group |
Label
Non-interactive label used inside a menu to describe a group of items.
Separator
Visual divider between groups of items.
| Attribute | Values |
|---|---|
| role | separator |
Sub
Container for a submenu composed of SubTrigger and SubContent.
| Prop | Type | Default |
|---|---|---|
offset | { x: number; y: number } | { x: 0, y: 0 } |
SubTrigger
Trigger that opens a submenu on hover or ArrowRight.
| Attribute | Values |
|---|---|
| [data-state] | open | closed |
| [data-active] | true when focused/hovered |
SubContent
Submenu panel containing nested items.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
loop | boolean | false |
| Attribute | Values |
|---|---|
| role | menu |
| [data-state] | open | closed |
| [data-side] | top | right | bottom | left |
| [data-align] | start | center | end |
Keyboard
| Shortcut | Action |
|---|---|
| ←/→ | Move focus between menu Triggers along the menubar. |
| Enter/Space/↓ | Open the focused menu and move focus to its first item. |
| ↑ | Open the focused menu and move focus to its last item. |
| ↓/↑ | Within an open menu, move focus to the next / previous item. |
| → | On a SubTrigger, open the submenu and move focus to its first item. |
| ← | Inside a submenu, close it and return focus to the SubTrigger. |
| Home/End | Move focus to the first / last item in the open menu. |
| Enter/Space | Activate the focused item. For CheckboxItem / RadioItem, toggles the value. |
| Esc | Close the open menu and return focus to its Trigger. |
| A-Z/0-9 | Typeahead — move focus to the next item whose text starts with the typed characters. |
Accessibility
The Menubar component implements the WAI-ARIA Menubar pattern:
Rootrenders asrole="menubar".Triggerexposesaria-haspopup="menu",aria-expanded, andaria-controls.ContentandSubContentrender asrole="menu".Item,CheckboxItem, andRadioItemexpose the correct menu item roles and checked state.- Focus moves between triggers and menu items with the keyboard, and returns to the trigger when a menu closes.
- Disabled items expose
aria-disabled="true"and cannot be activated.