ContextMenu
A menu of actions opened at the pointer with a right-click, or with the ContextMenu key / Shift+F10 on a focused element. It shares DropdownMenu's items, keyboard model and styles.
Last action: nothing yet
import { Button, ContextMenu } from "@meridui/react";
export function Example() {
const [pinned, setPinned] = useState(false);
return (
<ContextMenu.Root label="File actions">
<ContextMenu.Trigger className="file-area">
<Button variant="ghost">quarterly-report.pdf</Button>
<span>Right-click here, or focus the file and press Shift+F10</span>
</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Item trailing="↵" onSelect={() => open()}>Open</ContextMenu.Item>
<ContextMenu.Item onSelect={() => rename()}>Rename</ContextMenu.Item>
<ContextMenu.Item disabled>Move to…</ContextMenu.Item>
<ContextMenu.CheckboxItem checked={pinned} onCheckedChange={setPinned}>Pinned</ContextMenu.CheckboxItem>
<ContextMenu.Separator />
<ContextMenu.Item onSelect={() => remove()}>Delete</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu.Root>
);
}Import
import { ContextMenu } from "@meridui/react";Anatomy
<ContextMenu.Root>
<ContextMenu.Trigger />
<ContextMenu.Content>
<ContextMenu.Label />
<ContextMenu.Group>
<ContextMenu.Item />
<ContextMenu.CheckboxItem />
</ContextMenu.Group>
<ContextMenu.Separator />
</ContextMenu.Content>
</ContextMenu.Root>- Root holds the open state and the menu's accessible name (
label). - Trigger is the area that listens for
contextmenu. It is a<div>(or your element withasChild) and is not focusable itself: put focusable content inside so keyboard users can open the menu with the ContextMenu key or Shift+F10. - Content and the items are the ones from DropdownMenu, so everything you know there applies.
Examples
Positioning
The menu opens at the pointer. When opened from the keyboard there is no pointer position, so it opens below the focused element. It flips and shifts to stay in the viewport.
Keeping the browser menu
Set disabled on the Trigger to let the browser's own context menu show, for example inside a text field.
API reference
Root
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | – | Controlled open state. |
defaultOpen | boolean | false | Initial open state when uncontrolled. |
onOpenChange | (open: boolean) => void | – | Called when the open state should change. |
label | string | "Context menu" | Accessible name of the menu. |
children | ReactNode | – | Trigger and Content. |
Trigger
Accepts every <div> attribute.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render the single child element as the right-click area. |
disabled | boolean | false | Let the browser's own context menu show instead. |
ref | Ref<HTMLDivElement> | – | Forwarded ref to the area element. |
Content, Item, CheckboxItem, Group, Label, Separator
Same props as their DropdownMenu counterparts. Content defaults to placement="bottom-start" and sideOffset={2} against the pointer.
Styling
ContextMenu reuses the menu classes (.mrd-menu, .mrd-menu__item, …) listed on the DropdownMenu page. The trigger area has .mrd-context-menu__trigger (unless asChild) and data-disabled when disabled.
Accessibility
Follows the WAI-ARIA Menu pattern. The menu is named by label, focus moves to the first item on open and returns to the element that had it on Escape or selection.
| Key | Action |
|---|---|
| ShiftF10 | On a focused element inside the trigger: open the menu. |
| ContextMenu | Same as Shift+F10. |
| ArrowDown | Next item, wrapping. |
| ArrowUp | Previous item, wrapping. |
| Home | First item. |
| End | Last item. |
| Enter | Activate the item. |
| Space | Activate the item. |
| A–Z | Typeahead to the next item starting with the typed text. |
| Escape | Close and return focus. |
Guidelines
Do
Use a context menu as a shortcut for actions that are also reachable elsewhere (a toolbar, a row menu).
Avoid
Hide actions only behind a right-click. Touch users and many keyboard users never find them.
Related
- DropdownMenu: the same menu opened from a button.
- Toolbar: visible controls for the same actions.