Menu
A standalone menu list with selection state and keyboard navigation.
Basic usage
Basic usage
Default selection
Default selection (value echo)
Disabled items
Disabled items
Nested submenu
Menu items with children show an expand arrow (›); clicking or hovering expands the submenu, which is rendered indented; press ArrowRight to enter and ArrowLeft to go back.
Nested submenu
Horizontal navigation
With mode="horizontal" the items are laid out in a row as a top navigation bar; first-level submenus pop down while second-level and deeper submenus still pop to the right.
Horizontal navigation (top bar style)
Collapsed state
collapsed (vertical only) narrows the menu to show only icons; hovering or clicking an icon item pops its submenu out to the right, still a full menu.
Collapsed (icons only)
Groups
Menu items with type: "group" render as a section with a group title (small text, secondary color, not clickable); the group's children are laid out flat on the same level and may mix in submenus and dividers.
Groups
With icons
icon uses icon names from @oas-ui/icons (iconRegistry) and renders an inline SVG to the left of the text.
With icons
Divider
type: "divider" renders a thin divider line that is not clickable and not part of keyboard navigation.
Divider
Dark menu
theme="dark" applies dark tokens locally (dark background + light text) to the menu, independent of the global theme; when unset, it follows the global theme.
Dark menu
Selection event
Selection event
Multi-select (checkbox)
Leaf items with kind: "checkbox" render as square checkboxes (role="menuitemcheckbox", distinct from the radio ✓); the checked set is written to value as a JSON array, and after a click oas-select carries checked in its detail (the state after this click).
Multi-select (checkbox)
Destructive items
danger: true applies red semantics (--oas-color-danger) for destructive actions such as delete or sign out; the red background deepens on hover / keyboard highlight.
Destructive items (danger)
Link items (href)
href renders the item as an <a> (anchor semantics: middle-click / right-click in a new window, SEO friendly); target / rel are passed through as-is. Clicking still fires oas-select and writes the selected state. The example links use target="_blank" so they open in a new tab and you stay on this page.
Link items (href)
Long menu scrolling
max-height caps the visible height of the menu (a plain number is treated as px); overflowing items scroll inside the menu — handy for long lists.
Long menu scrolling (max-height)
Typeahead
With the menu focused, typing a character jumps to the item whose label matches (character buffer with a 500ms idle reset; prefix match first, falls back to substring). The example labels include English so you can type: press c to jump to Copy, then u (combined cu) to jump to Cut.
Typeahead
Inline sidebar navigation
With mode="inline" submenus expand in place (no flyout) — the mainstream sidebar navigation form; expanding / collapsing animates the height, and multi-level nesting is supported.
Inline expand
Controlled expansion
expanded (JSON array) is a controlled attribute: setting / updating it from outside specifies which submenus are open. Every expand / collapse fires oas-expand-change (detail: { expanded, value, isExpanded }); in the controlled pattern the host writes the state back to expanded.
Controlled expanded
Keep open on select
Flyout modes (vertical / horizontal) collapse expanded submenus after a leaf is selected by default (expansion is temporary); close-on-select="false" keeps them open — handy for picking several items in a row. mode="inline" side navigation keeps submenus open by default (users need to see their section); close-on-select="true" changes that to collapse. kind="checkbox" items never collapse on toggle.
Keep open on select (close-on-select)
vertical + close-on-select="false": the submenu stays open after picking a leaf
inline + close-on-select="true": the parent collapses after picking a leaf
Accordion
accordion (with mode="inline") makes sibling submenus mutually exclusive: expanding one automatically collapses the other open siblings.
Accordion (inline + accordion)
Horizontal overflow
With mode="horizontal", when the container is too narrow the overflowing items are automatically folded into a trailing "···" submenu — the nav bar never wraps or truncates.
Horizontal overflow
API
Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
accordion | Accordion mutual exclusion (inline mode: only one sibling submenu open at a time) | boolean | — |
close-on-select | Whether expanded submenus collapse after a leaf item is selected. Defaults by mode: inline side navigation keeps them open, flyout modes collapse; checkbox items never collapse on toggle | string | — |
collapsed | Collapsed state (vertical only): icons only, submenus pop to the right | — | — |
expanded | Controlled expanded set (JSON array string; which submenus are open in inline mode); internally managed when uncontrolled | string | — |
items | Menu items JSON (supports disabled / loading, icon, children submenus) | string | [] |
max-height | Max height of a long menu; scrolls internally beyond it (number gets px appended) | string | — |
mode | Layout mode: vertical menu / horizontal top bar | — | — |
theme | Local theme: dark uses dark tokens (independent of the global theme) | — | — |
value | Current selected value. Plain string means global single-select (no group, legacy-compatible); JSON object string (e.g. {"sort":"name","view":"list"}) scopes per group id — the value of a type:"group" item is the group id, picking inside a group only updates that group | string | — |
Events
| Event | Description |
|---|---|
oas-expand-change | Submenu expand state changed, detail: { expanded: string[], value, isExpanded } (fired both controlled and uncontrolled) |
oas-select | Select an item, detail: { value, kind? }. kind only appears for action items (kind: "action") as "action"; radio items omit detail.kind |
MenuItem fields:
| Field | Description | Type |
|---|---|---|
label | Menu item text | string |
value | Selection value | string |
type | Item type: item (default) / group (group title) / divider | string |
kind | Leaf semantics: radio (default, checkable) / action (action item, no checkmark, doesn't write back value on click) | string |
icon | Icon name (a key of @oas-ui/icons iconRegistry) | string |
disabled | Disables the item | boolean |
children | Submenu items array with the same shape as the parent (nested recursively) | MenuItem[] |
children is an optional submenu items array; items with children expand their submenu on click/hover, and the selected state only lands on leaf items. group children are laid out flat on the same level; group titles are not clickable and skipped in keyboard navigation; divider items are not clickable and skipped in keyboard navigation.
Keyboard navigation: arrow keys move (auto-skipping group titles and dividers), Enter selects (items with submenus enter via Enter/ArrowRight), Home / End jump, ArrowLeft returns to the parent; role="menu" + menuitemradio (submenu parents are menuitem), the selected item shows a check mark.