# Menubar
A desktop-style bar of menus that stays open as you move across it.
```ehtml Example
import {
Menubar, MenubarMenu, MenubarItem, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem,
MenubarLabel, MenubarGroup, MenubarSeparator, MenubarShortcut, MenubarSub,
} from "@elements/ui/menubar";
New Tab ⌘T
New Incognito Window
Email link
Always Show Bookmarks Bar
Andy
Benoit
```
## Parts
| Part | What it is |
|---|---|
| `Menubar` | The bar (role=menubar). Owns value, the open menu's value. |
| `MenubarMenu` | One menu: renders its trigger (role=menuitem, label or the trigger slot) and, while open, its role=menu content with the default slot's items. |
| `MenubarItem` | An action row (role=menuitem). With href it renders a link. Selecting it closes the menu unless onSelect calls preventDefault() or closeOnSelect is false. |
| `MenubarCheckboxItem` | A row that toggles (role=menuitemcheckbox). checked is two-way and may be "indeterminate". |
| `MenubarRadioGroup` | Groups radio items (role=group); value is two-way and holds the checked item's value. |
| `MenubarRadioItem` | One choice in a radio group (role=menuitemradio). |
| `MenubarLabel` | A heading row. Skipped by arrow keys; names the group it sits in. |
| `MenubarGroup` | Groups items (role=group). |
| `MenubarSeparator` | A rule between groups (role=separator). |
| `MenubarShortcut` | A keyboard hint at the end of an item. |
| `MenubarSub` | A submenu: renders its trigger row (label or the trigger slot) and, while open, its own floating menu with the default slot's items. |
| `MenubarInput` | A filter row at the top of the menu: typing hides the rows that do not match. Focus stays in the input while ArrowDown and ArrowUp move the highlight; Enter chooses. |
| `MenubarClear` | A button that empties the filter input. clearButton on the input renders one in its row. |
| `MenubarEmpty` | A row shown only when the filter matches nothing. Its default slot is the message. |
## Slots
| Slot | Part | Content |
|---|---|---|
| `default` | `Menubar` | The MenubarMenu elements. |
| `trigger` | `MenubarMenu` | Rich trigger content (an icon and text); label is the plain form. |
| `default` | `MenubarMenu` | The menu's items. |
| `default` | `MenubarItem, MenubarCheckboxItem, MenubarRadioItem` | The row: text, an `` (sized from --icon-size), a Shortcut. |
| `indicator` | `MenubarCheckboxItem, MenubarRadioItem` | Replaces the check (or dot) shown while checked. Put the checked glyph in an element with class is-checked, the indeterminate one in is-indeterminate. |
| `trigger` | `MenubarSub` | Rich content for the trigger row (an icon and text); label is the plain-text form. |
| `default` | `MenubarSub` | The submenu's items. |
## Keyboard
| Keys | Action |
|---|---|
| `Tab` | Moves focus to the bar's one tab stop: the last trigger used, or the first. |
| `ArrowRight / ArrowLeft` | On a trigger: the next or previous trigger (wraps unless loop is false). Inside an open menu (not on a sub trigger): opens the next or previous menu on its first item. |
| `Enter / Space / ArrowDown` | On a trigger: opens its menu on the first item. |
| `ArrowUp` | On a trigger: opens its menu on the last item. |
| `ArrowDown / ArrowUp (vertical bar)` | On a trigger: the next or previous trigger. |
| `ArrowRight (vertical bar)` | On a trigger: opens its menu beside the bar on the first item. ArrowLeft in the menu goes back to the trigger. Flipped under rtl. |
| `A letter on a trigger` | Focuses the next trigger that starts with it. |
| `ArrowDown / ArrowUp` | Next or previous item; from the menu itself, the first or last. Wraps with loop. |
| `Home / PageUp` | First item. |
| `End / PageDown` | Last item. |
| `Enter / Space` | Chooses the item (toggles a checkbox, checks a radio) and closes the menu; on a sub trigger, opens the submenu and focuses its first item. |
| `ArrowRight (ArrowLeft in rtl)` | On a sub trigger, opens the submenu and focuses its first item. |
| `ArrowLeft (ArrowRight in rtl)` | In a submenu, closes it and focuses its trigger. |
| `A letter` | Typeahead: focuses the next enabled item that starts with the typed text. |
| `Escape` | Closes the whole menu and returns focus. |
| `Tab / Shift + Tab` | Closes the menu and moves focus on, as from the trigger. |
| `ArrowDown / ArrowUp, Enter (in a filter input)` | Move the highlight while focus stays in the input; Enter chooses the highlighted row. |
## Data attributes
| Attribute | Values | On | Description |
|---|---|---|---|
| `data-orientation` | `"horizontal" \| "vertical"` | Menubar | |
| `data-has-submenu-open` | present | Menubar | While any of its menus is open. |
| `data-state` | `"open" \| "closed"` | trigger (.menubar-trigger) | |
| `data-pressed` | present | trigger (.menubar-trigger) | While the menu a press of the trigger opened is open. |
| `data-modal` | present | bar (.menubar) | When modal. |
| `data-highlighted` | present | trigger | While focused. |
| `data-disabled` | present | trigger | |
| `data-state` | `"open" \| "closed"` | .menubar-content | |
| `data-side` | `"top" \| "right" \| "bottom" \| "left"` | .menubar-content | The side it opened on, after flipping. |
| `data-align` | `"start" \| "center" \| "end"` | .menubar-content | |
| `data-orientation` | `"vertical"` | .menubar-content, items | |
| `data-highlighted` | present | MenubarItem, MenubarCheckboxItem, MenubarRadioItem, sub trigger | The focused row, by keyboard or pointer. |
| `data-disabled` | present | items | |
| `data-variant` | `"default" \| "destructive"` | MenubarItem | |
| `data-state` | `"checked" \| "unchecked" \| "indeterminate"` | MenubarCheckboxItem, MenubarRadioItem, .menu-item-indicator | |
| `data-state` | `"open" \| "closed"` | sub trigger (.menu-sub-trigger) | |
| `data-orientation` | `"horizontal" \| "vertical"` | MenubarSeparator | |
| `hidden` | present | items, groups, separators, empty row | Set by the filter on rows that do not match. |
| `data-instant` | `"click" \| "dismiss" \| "group"` | .menubar-content, arrow, backdrop | click when the keyboard opened it, dismiss when Escape closed it, group when a menubar swapped menus; a theme may skip the animation. |
| `--positioner-width / --positioner-height` | px | .menubar-content | The content places itself, so these are its own size while open. |
| `data-highlighted` | present | MenubarInput | While the input shows focus; cleared when the keyboard highlights a row. |
| `data-starting-style, data-ending-style` | present | .menu-item-indicator | One frame as the indicator turns on; while it turns off (valued with the state it leaves) until its transitions end. |
## Accessibility
- The bar is role=menubar with aria-orientation=horizontal; each trigger is a role=menuitem button with aria-haspopup=menu, aria-expanded and aria-controls, and the menu is labelled by it.
- One tab stop for the bar (roving tabindex). Disabled triggers stay focusable with aria-disabled, as APG asks.
- Menus are not modal: the page stays usable, a press outside closes the open menu and lands where it was aimed.
- The content is role=menu, named by its trigger (aria-labelledby) unless label is set. Items are menuitem, menuitemcheckbox (aria-checked true, false or mixed) and menuitemradio; disabled rows carry aria-disabled.
- Rows take real focus (tabindex=-1, roving) and the focused row carries data-highlighted, so screen readers follow the keyboard.
- A sub trigger has aria-haspopup=menu, aria-expanded and aria-controls; its submenu sits right after it in the DOM, as APG asks.
- A label row inside a group names the group (aria-labelledby).
- Disabled rows stay focusable by keyboard (APG menus), so a screen reader user hears them; the pointer and typeahead skip them.
- The content is popover=manual in the top layer: never clipped by an overflow or transform ancestor, no portal, no z-index.
## See also
- [DropdownMenu](../dropdown-menu): A menu of actions from a button, with submenus, checkbox and radio items.
- [ContextMenu](../context-menu): A menu at the pointer on right-click or long-press.
- [NavigationMenu](../navigation-menu): Site navigation with large animated dropdown panels.