Composite
Menubar Requires JS
Horizontal menu bar with sub-menus. For desktop-style apps with a top-level File / Edit / View structure.
About
Overview
Use a Menubar when your app has more global commands than fit in a button row, and the desktop-app metaphor (File menu, Edit menu) makes sense — IDEs, design tools, document editors.
Live
Demo
Click a top-level menu to open it, then use ← / → to glide between menus and ↑ / ↓ inside one. Esc closes.
<ren-menubar>
<div class="ren-menubar" role="menubar" aria-label="Document">
<button type="button" class="ren-menubar-trigger" aria-haspopup="menu" aria-expanded="false">File</button>
<div class="ren-menubar-menu" role="menu" aria-label="File" hidden>
<button type="button" class="ren-menubar-item" role="menuitem">New file<span class="ren-menubar-shortcut">⌘N</span></button>
<div class="ren-menubar-separator" role="separator"></div>
<button type="button" class="ren-menubar-item" role="menuitem">Save<span class="ren-menubar-shortcut">⌘S</span></button>
</div>
<button type="button" class="ren-menubar-trigger" aria-haspopup="menu" aria-expanded="false">Edit</button>
<div class="ren-menubar-menu" role="menu" aria-label="Edit" hidden>
<button type="button" class="ren-menubar-item" role="menuitem">Undo<span class="ren-menubar-shortcut">⌘Z</span></button>
</div>
</div>
</ren-menubar>
Reference
API
The pattern is a fixed three-level shape: <ren-menubar> wraps a <div class="ren-menubar" role="menubar">; inside it every top-level menu is a .ren-menubar-trigger button followed immediately by its sibling .ren-menubar-menu panel. The component pairs each trigger with trigger.nextElementSibling, so a button without the .ren-menubar-trigger class is not a menu at all — it will never open.
| Class | Effect |
|---|---|
.ren-menubar | The bar itself, on a <div role="menubar"> inside the custom element. |
.ren-menubar-trigger | A top-level menu button. The component manages its aria-expanded. |
.ren-menubar-menu | The dropdown panel, a sibling right after its trigger. Toggled via the hidden attribute. |
.ren-menubar-item | One command inside a panel. Always a <button>, never an <a>. |
.ren-menubar-checkbox / -radio | Stateful items. Pair with role="menuitemcheckbox|menuitemradio" and aria-checked; the check / dot is drawn by ::before. |
.ren-menubar-submenu | An item that owns a nested .ren-menubar-menu child. The chevron is drawn by ::after. |
.ren-menubar-separator / -shortcut / -label | Divider, trailing shortcut text, and non-interactive group heading. |
Events
| Event | Detail |
|---|---|
ren-menubar-select | An item was activated. { item, value, checked }. |
Inclusive by default
Accessibility
- Wrapper has
role="menubar"+ descriptivearia-label; each panel is arole="menu"with its own label. - Triggers expose
aria-haspopupand anaria-expandedthat the component flips as menus open and close. - Arrow keys navigate horizontally between top-level menus, vertically inside an open one; Home / End jump to the first / last item and typeahead matches by character.
- Esc closes the open menu and returns focus to its trigger.