# ContextMenu A menu at the pointer on right-click or long-press. ```ehtml Example import { ContextMenu, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuLabel, ContextMenuGroup, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, } from "@elements/ui/context-menu";
Right click here
Back ⌘[ Forward ⌘] Save Page As... Show Bookmarks People Pedro Duarte Colm Tuite
``` ## 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 `` (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 - [DropdownMenu](../dropdown-menu): A menu of actions from a button, with submenus, checkbox and radio items. - [Menubar](../menubar): A desktop-style bar of menus that stays open as you move across it. - [NavigationMenu](../navigation-menu): Site navigation with large animated dropdown panels.