Menubar
Manual until a YAML contract lands in
monochrome/spec/components/.
Horizontal strip of menu triggers (File / Edit / View style). Builds on the same core as Menu: each trigger/popover pair uses mct:menu: / mcc:menu:, arrow keys move between triggers, and an open menu follows the cursor across the bar.
Differences from a standalone Menu:
- Container
role="menubar" - Roving tabindex: exactly one trigger has
tabindex="0", every other triggertabindex="-1"(one Tab stop for the bar) - Triggers use
role="menuitem" - Wrappers expose
Menubar.*(Menu item helpers are re-exported). Authors mark the Tab-stop menu withfirst(React/Vue)
Composition
Root (ul role="menubar")
Menu (li role="none")
Trigger (role="menuitem")
Popover (ul role="menu" popover="manual")
Item | CheckboxItem | RadioItem | Label | Separator | GroupUsage
HTML
<ul role="menubar">
<li role="none">
<button type="button" role="menuitem" id="mct:menu:file" aria-controls="mcc:menu:file" aria-expanded="false" aria-haspopup="menu" tabindex="0">
File
</button>
<ul role="menu" id="mcc:menu:file" aria-labelledby="mct:menu:file" aria-hidden="true" popover="manual">
<li role="none"><button type="button" role="menuitem" tabindex="-1">New File</button></li>
<li role="none"><button type="button" role="menuitem" tabindex="-1">Open...</button></li>
<li role="none"><button type="button" role="menuitem" tabindex="-1">Save</button></li>
</ul>
</li>
<li role="none">
<button type="button" role="menuitem" id="mct:menu:edit" aria-controls="mcc:menu:edit" aria-expanded="false" aria-haspopup="menu" tabindex="-1">
Edit
</button>
<ul role="menu" id="mcc:menu:edit" aria-labelledby="mct:menu:edit" aria-hidden="true" popover="manual">
<li role="none"><button type="button" role="menuitem" tabindex="-1">Undo</button></li>
<li role="none"><button type="button" role="menuitem" tabindex="-1">Redo</button></li>
</ul>
</li>
</ul>React
import { Menubar } from "@monochrome-ui/react"
<Menubar.Root>
<Menubar.Menu first>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Popover>
<Menubar.Item>New File</Menubar.Item>
<Menubar.Item>Open...</Menubar.Item>
<Menubar.Item>Save</Menubar.Item>
</Menubar.Popover>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Edit</Menubar.Trigger>
<Menubar.Popover>
<Menubar.Item>Undo</Menubar.Item>
<Menubar.Item>Redo</Menubar.Item>
</Menubar.Popover>
</Menubar.Menu>
</Menubar.Root>Vue
<script setup lang="ts">
import { Menubar } from "@monochrome-ui/vue"
</script>
<template>
<Menubar.Root>
<Menubar.Menu first>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Popover>
<Menubar.Item>New File</Menubar.Item>
<Menubar.Item>Open...</Menubar.Item>
<Menubar.Item>Save</Menubar.Item>
</Menubar.Popover>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Edit</Menubar.Trigger>
<Menubar.Popover>
<Menubar.Item>Undo</Menubar.Item>
<Menubar.Item>Redo</Menubar.Item>
</Menubar.Popover>
</Menubar.Menu>
</Menubar.Root>
</template>Parts
Root
Required. Element: ul with role="menubar". Children: Menu (and optional top-level items after the menu marked first).
Menu
Required per top-level entry. Element: li role="none". Provides slot context for Trigger + Popover.
| Kind | Name | Type | Default | Description |
|---|---|---|---|---|
| prop | first |
boolean |
false |
When true, this menu's Trigger gets tabindex="0" (the bar's Tab stop). Exactly one top-level Menu should set first. Submenus use Group (never first). HTML authors set tabindex on the trigger by hand instead. |
Trigger / Popover
Same id and ARIA contract as Menu (mct:menu:<id> / mcc:menu:<id>, aria-haspopup="menu", popover="manual"), with role="menuitem" on the trigger and roving tabindex.
| Kind | Name | Type | Default | Description |
|---|---|---|---|---|
| prop | disabled |
boolean |
false |
On Trigger; emits aria-disabled. |
Group
Submenu inside a popover: wraps its own Trigger + Popover pair (li role="none", new id). Same pattern as Menu.Group.
Item, CheckboxItem, RadioItem, Label, Separator
Same behavior and markup as Menu. React/Vue re-export Menu helpers as Menubar.Item, etc.
Notes
- Ids: Same
mct:menu/mcc:menuscheme as Menu (not a separate prefix). - Hover across bar: With a menu open, moving to another menubar trigger opens that menu (chord switching).
- Submenus: Nest via Group; ArrowRight opens, ArrowLeft closes. Safety triangle applies as in Menu.
- Selection items: CheckboxItem / RadioItem / Label / Separator work exactly as in Menu.
Keyboard
| Key | Context | Behavior |
|---|---|---|
| Tab | Bar | Lands on the tabindex="0" trigger only |
| ArrowLeft / ArrowRight | Trigger or open menu | Move between menubar triggers; if a menu was open, open the destination menu |
| ArrowDown / ArrowUp | Closed trigger | Open menu; focus first / last item |
| ArrowDown / ArrowUp | Inside menu | Roving among items |
| ArrowRight | Submenu trigger | Open submenu |
| ArrowLeft | Inside submenu | Close submenu |
| Home / End | Inside menu | First / last item |
| a-z | Inside menu | Typeahead |
| Escape | Open | Close topmost layer |
| Tab | Open menu | Close all menus |