Menu

<o-menu> is a radial menu, flat or nested. Branches open in place or as rings around their parent.

Each sector is an interactive <o-arc> with its label drawn along the arc. Click a branch to open it; the middle becomes a back button.

Attributes

AttributeDefaultWhat it does
items[]Items: [{ label, value?, icon?, color?, children? }], nested as deep as you like. value defaults to the label.
expanddrilldrill replaces the ring with the open branch. concentric keeps the parent and fans the children out around it.
palettemonomono draws slate sectors that turn accent on hover and focus. color gives each item its own color. Before 2.0 this was theme, and theme="color" still works.
themedark, light or glass, like every component (Shared options). It combines with color: theme="color light".
accent#3da9fcHighlight color of the mono theme.
labelMENUText in the middle.
label-color#f8fafcColor of the sector labels.
range / from360 / autoArc span and start angle. A partial menu centers its gap at the bottom.
thickness3.6Ring thickness in lanes.
gap1.2Space between sectors, in percent of the widget width.
size280pxWidth of the widget.
valuePicks the leaf with this value. It is also the default a form reset returns to.
nameField name: with it, the menu submits the picked value with the form. See Forms.
requiredoffThe form does not submit until a leaf is picked.
disabledoffDimmed, ignores pointer and keys, and is not submitted.

icon takes an emoji, text, or a small inline SVG. SVG is cleaned down to basic shapes: scripts, links, event handlers and external resources are dropped. An item with an icon shows the icon instead of the curved label and keeps the label as its accessible name. Labels are always text, never HTML.

Properties and events

NameWhat it does
selectA leaf was chosen. event.detail has value, label, item and path, the indexes from the root.
navigateThe open branch changed. event.detail has path and depth.
input, changeFire with every pick, after select, like a <select>. Same detail.
valueThe value of the last selected leaf. Setting it picks the leaf with that value (or none with null) and fires no event.
form, labels, validity, checkValidity()As on a native input.
pathIndexes of the open branches, [] at the root.
selectedIndexIndex of the selected leaf in the visible level, or -1.
back()Closes the innermost open branch.
reset()Goes back to the root.

Styling

PropertyDefaultWhat it does
--ok-menu-accent#3da9fcHighlight of the mono theme and the focus glow. Falls back to --ok-accent.
--ok-menu-slate#2b333fSector color of the mono theme.
--ok-menu-text#f8fafcLabels and the middle text.
--ok-menu-hubdark slateBackground of the middle.
--ok-menu-hub-hoverlighter slateBackground of the middle when it is a back button.
--ok-font-size5cqminLabel size, as a share of the widget.

More examples

Concentric branches

Open Media: its children fan out over its slice, and the root ring moves inward to make room.

A colored half menu

SVG icons and a custom accent

Accessibility

The menu has role="menu" and each sector role="menuitem"; branches add aria-haspopup and aria-expanded, and the selected leaf gets aria-current. Tab enters the menu once and leaves it on the next Tab. Arrow keys move around the visible items, Home and End jump to the first and last, Enter and Space activate, Escape and Backspace go back one level. Opening a branch moves focus to its first child; going back returns it to the branch.

The menu is called by its label; set aria-label to name it otherwise.