Manual UI Templates ContextMenu

ContextMenu

elements man ui/templates/context-menu

A menu at the pointer on right-click or long-press.

Example
import { ContextMenu, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuLabel, ContextMenuGroup, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, } from "@elements/ui/context-menu"; <ContextMenu> <div slot="trigger" class="drop-zone">Right click here</div> <ContextMenuItem onSelect={back}>Back <ContextMenuShortcut>⌘[</ContextMenuShortcut></ContextMenuItem> <ContextMenuItem disabled>Forward <ContextMenuShortcut>⌘]</ContextMenuShortcut></ContextMenuItem> <ContextMenuSub label="More Tools"> <ContextMenuItem>Save Page As...</ContextMenuItem> </ContextMenuSub> <ContextMenuSeparator /> <ContextMenuCheckboxItem checked={view.bookmarks}>Show Bookmarks</ContextMenuCheckboxItem> <ContextMenuRadioGroup value={view.person}> <ContextMenuLabel inset>People</ContextMenuLabel> <ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem> <ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem> </ContextMenuRadioGroup> </ContextMenu>

Parts

Part What it is
ContextMenu The root: the trigger slot is the area that opens it; while open, the floating role=menu content at the pointer with the default slot's items.
ContextMenuItem An action row (role=menuitem). With href it renders a link. Selecting it closes the menu unless onSelect calls preventDefault() or closeOnSelect is false.
ContextMenuCheckboxItem A row that toggles (role=menuitemcheckbox). checked is two-way and may be "indeterminate".
ContextMenuRadioGroup Groups radio items (role=group); value is two-way and holds the checked item's value.
ContextMenuRadioItem One choice in a radio group (role=menuitemradio).
ContextMenuLabel A heading row. Skipped by arrow keys; names the group it sits in.
ContextMenuGroup Groups items (role=group).
ContextMenuSeparator A rule between groups (role=separator).
ContextMenuShortcut A keyboard hint at the end of an item.
ContextMenuSub A submenu: renders its trigger row (label or the trigger slot) and, while open, its own floating menu with the default slot's items.
ContextMenuInput A filter row at the top of the menu: typing hides the rows that do not match. Focus stays in the input while ArrowDown and ArrowUp move the highlight; Enter chooses.
ContextMenuClear A button that empties the filter input. clearButton on the input renders one in its row.
ContextMenuEmpty A row shown only when the filter matches nothing. Its default slot is the message.

Slots

Slot Part Content
trigger ContextMenu The area: any element. It gets data-state; right-click, the context menu key and a long press inside it open the menu.
default ContextMenu The menu's items, labels, groups, separators and submenus.
default ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem The row: text, an <Icon> (sized from --icon-size), a Shortcut.
indicator ContextMenuCheckboxItem, ContextMenuRadioItem Replaces the check (or dot) shown while checked. Put the checked glyph in an element with class is-checked, the indeterminate one in is-indeterminate.
trigger ContextMenuSub Rich content for the trigger row (an icon and text); label is the plain-text form.
default ContextMenuSub The submenu's items.

Keyboard

Keys Action
Shift + F10 / ContextMenu key On something focused inside the area: opens the menu at it.
ArrowDown / ArrowUp Next or previous item; from the menu itself, the first or last. Wraps with loop.
Home / PageUp First item.
End / PageDown Last item.
Enter / Space Chooses the item (toggles a checkbox, checks a radio) and closes the menu; on a sub trigger, opens the submenu and focuses its first item.
ArrowRight (ArrowLeft in rtl) On a sub trigger, opens the submenu and focuses its first item.
ArrowLeft (ArrowRight in rtl) In a submenu, closes it and focuses its trigger.
A letter Typeahead: focuses the next enabled item that starts with the typed text.
Escape Closes the whole menu and returns focus.
Tab / Shift + Tab Closes the menu and moves focus on, as from the trigger.
ArrowDown / ArrowUp, Enter (in a filter input) Move the highlight while focus stays in the input; Enter chooses the highlighted row.

Data attributes

Attribute Values On Description
data-state "open" | "closed" trigger (the area)
data-pressed present trigger (the area) While the menu a right-click or long-press opened is open.
--anchor-width / --anchor-height 0px .context-menu The anchor is the press point, a zero-size box.
data-state, data-starting-style, data-ending-style "open" | "closed" .menu-backdrop With backdrop; follows the content.
data-disabled present trigger (the area) While disabled.
data-state "open" | "closed" .context-menu (content)
data-side "top" | "right" | "bottom" | "left" .context-menu (content) The side it opened on, after flipping.
data-align "start" | "center" | "end" .context-menu (content)
data-orientation "vertical" .context-menu (content), items
data-highlighted present ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, sub trigger The focused row, by keyboard or pointer.
data-disabled present items
data-variant "default" | "destructive" ContextMenuItem
data-state "checked" | "unchecked" | "indeterminate" ContextMenuCheckboxItem, ContextMenuRadioItem, .menu-item-indicator
data-state "open" | "closed" sub trigger (.menu-sub-trigger)
data-orientation "horizontal" | "vertical" ContextMenuSeparator
hidden present items, groups, separators, empty row Set by the filter on rows that do not match.
data-instant "click" | "dismiss" | "group" .context-menu (content), arrow, backdrop click when the keyboard opened it, dismiss when Escape closed it, group when a menubar swapped menus; a theme may skip the animation.
--positioner-width / --positioner-height px .context-menu (content) The content places itself, so these are its own size while open.
data-highlighted present ContextMenuInput While the input shows focus; cleared when the keyboard highlights a row.
data-starting-style, data-ending-style present .menu-item-indicator One frame as the indicator turns on; while it turns off (valued with the state it leaves) until its transitions end.

Accessibility

  • The menu opens at the pointer with focus on the menu; from the keyboard (Shift+F10 or the context menu key) it opens at the focused element. On close, focus goes back to what had it before.
  • A right-click inside the area while the menu is open moves the menu there; a right-click elsewhere closes it without taking focus back.
  • Long press on touch opens it (iOS fires no contextmenu event); moving more than a few pixels cancels, so scrolling still works.
  • The content is role=menu, named by its trigger (aria-labelledby) unless label is set. Items are menuitem, menuitemcheckbox (aria-checked true, false or mixed) and menuitemradio; disabled rows carry aria-disabled.
  • Rows take real focus (tabindex=-1, roving) and the focused row carries data-highlighted, so screen readers follow the keyboard.
  • A sub trigger has aria-haspopup=menu, aria-expanded and aria-controls; its submenu sits right after it in the DOM, as APG asks.
  • A label row inside a group names the group (aria-labelledby).
  • Disabled rows stay focusable by keyboard (APG menus), so a screen reader user hears them; the pointer and typeahead skip them.
  • The content is popover=manual in the top layer: never clipped by an overflow or transform ancestor, no portal, no z-index.

See also