Context Menu
A menu that appears at the pointer on right click or long press. The popup has no stroke. Highlighted rows show the accent dot, and checked marks use the accent. Items are Regular and group labels are Light.
Usage guidelines
- Use context menus as an enhancement: Don’t make a context menu the only way to perform actions. Users may not discover or be able to open a context menu, especially on touch devices or with assistive technology. Always provide visible controls for the actions that are available in the context menu.
Anatomy
<UiContextMenuRoot>
<UiContextMenuTrigger />
<UiContextMenuPortal>
<UiContextMenuBackdrop />
<UiContextMenuPositioner>
<UiContextMenuPopup>
<UiContextMenuArrow />
<UiContextMenuItem />
<UiContextMenuLinkItem href="/" />
<UiContextMenuSeparator />
<UiContextMenuSubmenuRoot>
<UiContextMenuSubmenuTrigger />
</UiContextMenuSubmenuRoot>
<UiContextMenuGroup>
<UiContextMenuGroupLabel />
</UiContextMenuGroup>
<UiContextMenuRadioGroup>
<UiContextMenuRadioItem value="a">
<UiContextMenuRadioItemIndicator />
</UiContextMenuRadioItem>
</UiContextMenuRadioGroup>
<UiContextMenuCheckboxItem>
<UiContextMenuCheckboxItemIndicator />
</UiContextMenuCheckboxItem>
</UiContextMenuPopup>
</UiContextMenuPositioner>
</UiContextMenuPortal>
</UiContextMenuRoot>
Examples
Menu displays additional demos, many of which apply to the context menu as well.
Using with Menu
A context menu should supplement a primary way to perform the same actions. This image card exposes actions through a visible menu button and reuses them in the context menu for right-click and long-press users.
Station Hofplein
<div class="card">
<UiContextMenuRoot>
<UiContextMenuTrigger><!-- image --></UiContextMenuTrigger>
<UiContextMenuPortal><!-- shared items --></UiContextMenuPortal>
</UiContextMenuRoot>
<UiMenuRoot>
<UiMenuTrigger aria-label="Image actions"><!-- ⋮ --></UiMenuTrigger>
<UiMenuPortal><!-- shared items --></UiMenuPortal>
</UiMenuRoot>
</div>
Nested menu
To create a submenu, put UiContextMenuSubmenuRoot inside the parent popup. UiContextMenuSubmenuTrigger is the item that opens the nested menu. Hover or ArrowRight opens it to the right; ArrowLeft closes it.
<UiContextMenuPopup>
<UiContextMenuItem>Add to Library</UiContextMenuItem>
<UiContextMenuSubmenuRoot>
<UiContextMenuSubmenuTrigger>Add to Playlist</UiContextMenuSubmenuTrigger>
<UiContextMenuPortal>
<UiContextMenuPositioner :align-offset="-4" :side-offset="-4">
<UiContextMenuPopup>
<UiContextMenuItem>Get Up!</UiContextMenuItem>
<UiContextMenuItem>New playlist…</UiContextMenuItem>
</UiContextMenuPopup>
</UiContextMenuPositioner>
</UiContextMenuPortal>
</UiContextMenuSubmenuRoot>
</UiContextMenuPopup>
API reference
Root
Creates a context menu activated by right click or long press. Doesn’t render its own HTML element.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | false | Uncontrolled initial open. |
open | boolean | — | Controlled open (v-model:open). |
disabled | boolean | false | Ignore interaction. |
highlightItemOnHover | boolean | true | Highlight items on pointer move. |
loopFocus | boolean | true | Arrow keys wrap at the ends of the list. |
| Event | Type | Description |
|---|---|---|
@update:open | (open: boolean) => void | Menu opened or closed. |
Trigger
Area that opens the menu on right click or long press. Renders a <div>.
| Attribute | Description |
|---|---|
data-popup-open | Present when the menu is open. |
data-pressed | Present when the menu is open or a long-press is held. |
data-disabled | Present when disabled. |
Portal
Teleports to body while the menu is present.
| Prop | Type | Default | Description |
|---|---|---|---|
hidden | boolean | — | Skip rendering even while present. |
| Attribute | Description |
|---|---|
data-open | Present when open. |
data-closed | Present while present but not open. |
data-starting-style | Present while animating in. |
data-ending-style | Present while animating out. |
Backdrop
Optional overlay behind the menu. Pointer-events none in this port.
Positioner
Pins the popup to the pointer, or to the submenu trigger when nested. Sets --transform-origin.
| Prop | Type | Default | Description |
|---|---|---|---|
sideOffset | number | 0 / -4 nested | Gap from the anchor. |
alignOffset | number | 0 | Shift along the trigger for nested menus. |
Popup
Menu surface (role="menu"). Enter and leave use data-starting-style / data-ending-style (scale 0.98, 100ms). No animation library. No drop-shadow. Arrow keys, Enter, and Escape.
| Attribute | Description |
|---|---|
data-open | Present when open. |
data-closed | Present when closed. |
data-starting-style | Present while animating in. |
data-ending-style | Present while animating out. |
Arrow
Optional arrow. Hidden in the default styles.
Item
One action. Renders role="menuitem". data-highlighted shows the accent dot.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Ignore presses. Sets data-disabled. |
closeOnClick | boolean | true | Close the menu when clicked. |
label | string | — | Override for typeahead. |
| Attribute | Description |
|---|---|
data-highlighted | Present when highlighted. |
data-disabled | Present when disabled. |
LinkItem
Menu item that renders an <a>.
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | — | Link destination. |
disabled | boolean | false | Ignore presses. |
closeOnClick | boolean | true | Close the menu when clicked. |
Group
Section of items. Renders role="group".
GroupLabel
Heading for a group.
Separator
Visual divider. Renders role="separator".
SubmenuRoot
Owns a nested menu. Opens to the right of its trigger.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | false | Uncontrolled initial open. |
disabled | boolean | false | Ignore interaction. |
sideOffset | number | -4 | Gap from the parent item. |
SubmenuTrigger
Item that opens the nested menu. Renders role="menuitem" with aria-haspopup="menu". Hover or ArrowRight opens.
| Attribute | Description |
|---|---|
data-popup-open | Present when the submenu is open. |
data-highlighted | Present when highlighted. |
RadioGroup
Groups radio items. value / defaultValue / @update:value.
RadioItem
role="menuitemradio". Stays open on click by default.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Value selected when this item is chosen. |
disabled | boolean | false | Ignore presses. |
closeOnClick | boolean | false | Close the menu when clicked. |
RadioItemIndicator
Check mark for a selected radio item.
CheckboxItem
role="menuitemcheckbox". Toggles checked. Stays open on click by default.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultChecked | boolean | false | Uncontrolled initial tick. |
checked | boolean | — | Controlled tick (v-model:checked). |
disabled | boolean | false | Ignore presses. |
closeOnClick | boolean | false | Close the menu when clicked. |
CheckboxItemIndicator
Check mark while the checkbox item is ticked.