rc-menubar
Menubar coordinator for rc-menu-button children with roving tabindex and submenu handoff, following the WAI-ARIA Menubar pattern.
- Package
@rcarls/rc-menubar- Element
<rc-menubar>- Native dependency
- Consumer supplies menu buttons and menus
- State model
- Roving focus and submenu state
- Main events
- None
- Related
- Usage rulesTheme previews
Installation
- npm
- Yarn
- pnpm
npm install @rcarls/rc-webcomponents@next
yarn add @rcarls/rc-webcomponents@next
pnpm add @rcarls/rc-webcomponents@next
import '@rcarls/rc-webcomponents/rc-menubar/define';
Usage
Place rc-menu-button elements as direct children, and name the menubar with label.
<rc-menubar label="Application menu">
<rc-menu-button>
<button slot="trigger">File</button>
<rc-menu label="File">
<button>New</button>
<button>Open…</button>
</rc-menu>
</rc-menu-button>
<rc-menu-button>
<button slot="trigger">Edit</button>
<rc-menu label="Edit">
<button>Undo</button>
<button>Redo</button>
</rc-menu>
</rc-menu-button>
</rc-menubar>
Live demo
Accessibility
The host has role="menubar", aria-orientation, and an aria-label from label. The
triggers share one tab stop through a roving tabindex, and each opens its rc-menu.
| Key | Action |
|---|---|
| Right Arrow (horizontal), Down Arrow (vertical) | Focuses the next trigger, wrapping; if a menu is open, opens the next menu instead. |
| Left Arrow (horizontal), Up Arrow (vertical) | Focuses the previous trigger, wrapping; if a menu is open, opens the previous menu. |
| Home, End | Focuses the first or last trigger. |
| Escape | Closes the open menu and keeps focus on its trigger. |
| Tab | Leaves the menubar. |
Left and Right swap in right-to-left text. Inside an open menu, the rc-menu keyboard behavior
applies. See the WAI-ARIA Menubar pattern.
Theming
The default demo mode shows the component without a package theme. Use the shared preview controls on this page to compare inherited, light, and dark color schemes or to apply the optional Material theme only inside the demo frames.
rc-menubar owns the menubar surface and maps --rc-menubar-item-* variables
onto each child rc-menu-button trigger. This keeps top-level menubar items flat
while standalone menu buttons can keep their own button-like defaults.
Localization
Built-in text follows the element's own lang, else <html lang>. Override it with
messages, or register it for every instance under rc-menubar: label. See
Localization.
API
Properties
| Property | Markup | Type | Default | Description |
|---|---|---|---|---|
messages | JS property only | Partial<RCMenubarMessages> | undefined | Not specified | Built-in text overrides; unset keys fall back to registered text, then English. |
label | label | string | undefined | Not specified | Accessible label for the `role="menubar"` element. Defaults to the `label` message. |
orientation | orientation | 'horizontal' | 'vertical' | 'horizontal' | Orientation of the menubar, controls which arrow keys move between items. |
$items | JS property only | HTMLElement[] | Not specified | All slotted trigger elements in DOM order. |
$menuButtons | JS property only | RCMenuButton[] | Not specified | All slotted `rc-menu-button` children in DOM order. |
$firstItem | JS property only | HTMLElement | undefined | Not specified | First trigger element in the menubar. |
$lastItem | JS property only | HTMLElement | undefined | Not specified | Last trigger element in the menubar. |
$nextItem | JS property only | HTMLElement | undefined | Not specified | Trigger after `_$lastFocused`, wrapping around to the first. |
$previousItem | JS property only | HTMLElement | undefined | Not specified | Trigger before `_$lastFocused`, wrapping around to the last. |
Methods
| Method | Description |
|---|---|
focusItem($item?: HTMLElement | null) | Moves focus to a trigger element. |
closeActiveMenu() | Closes the currently open child menu without returning focus to its trigger. |
Slots
| Name | Description |
|---|---|
default | Takes rc-menu-button elements to display in the menubar |
CSS Custom Properties
| Property | Default | Description |
|---|---|---|
--rc-menubar-gap | var(--rc-control-gap) | Gap between menu buttons |
--rc-menubar-padding-inline | var(--rc-control-padding-inline) | Inline-axis padding |
--rc-menubar-padding-block | var(--rc-control-padding-block) | Block-axis padding |
--rc-menubar-border | var(--rc-border) | Root container border |
--rc-menubar-radius | var(--rc-control-radius) | Root container border radius |
--rc-menubar-background | Canvas | Root container background |
--rc-menubar-color | CanvasText | Root container text color |
--rc-menubar-item-block-size | 2.25em | Minimum block size for child menu-button triggers |
--rc-menubar-item-padding-block | 0.25em | Child trigger block-axis padding |
--rc-menubar-item-padding-inline | 0.75em | Child trigger inline-axis padding |
--rc-menubar-item-gap | var(--rc-item-gap) | Gap between flex children inside child triggers |
--rc-menubar-item-border | 1px solid transparent | Child trigger border |
--rc-menubar-item-radius | var(--rc-control-radius) | Child trigger border radius |
--rc-menubar-item-background | transparent | Child trigger background |
--rc-menubar-item-color | inherit | Child trigger text color |
--rc-menubar-item-transition | Not specified | CSS transition applied to child triggers |
--rc-menubar-item-hover-background | color-mix(in srgb, Highlight 8%, transparent) | Child trigger hover background |
--rc-menubar-item-hover-color | inherit | Child trigger hover text color |
--rc-menubar-item-hover-border-color | transparent | Child trigger hover border color |
--rc-menubar-item-open-background | color-mix(in srgb, Highlight 12%, transparent) | Child trigger background when its menu is open |
--rc-menubar-item-open-color | inherit | Child trigger text color when its menu is open |
--rc-menubar-item-open-border-color | transparent | Child trigger border color when its menu is open |
CSS Parts
| Part | Description |
|---|---|
root | The root container element |