Context Menu
A menu of actions that opens at the pointer on right click or long press.
Rows take variant for their look — neutral (the default) and danger for a destructive action.
Show codeHide code
Installation
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
} from "@makeplane/propel/components/context-menu";Usage
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger,
} from "@makeplane/propel/components/context-menu";
import { Icon } from "@makeplane/propel/components/icon";
import { Shortcut } from "@makeplane/propel/components/shortcut";
import { ClipboardPaste, Copy, Scissors, Trash2 } from "lucide-react";
const triggerClass =
"flex h-32 w-72 items-center justify-center rounded-lg border-sm border-dashed border-subtle text-body-xs-regular text-tertiary select-none";
export default function BasicDemo() {
return (
<ContextMenu>
<ContextMenuTrigger render={<div className={triggerClass} />}>
Right-click here
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem
icon={<Icon icon={Scissors} />}
aria-keyshortcuts="Meta+X"
trailing={<Shortcut keys="⌘X" />}
label="Cut"
/>
<ContextMenuItem
icon={<Icon icon={Copy} />}
aria-keyshortcuts="Meta+C"
trailing={<Shortcut keys="⌘C" />}
label="Copy"
/>
<ContextMenuItem
icon={<Icon icon={ClipboardPaste} />}
aria-keyshortcuts="Meta+V"
trailing={<Shortcut keys="⌘V" />}
label="Paste"
/>
<ContextMenuSeparator />
<ContextMenuItem variant="danger" icon={<Icon icon={Trash2} />} label="Delete" />
</ContextMenuContent>
</ContextMenu>
);
}Examples
Submenu
Nest a ContextMenuSubmenu to reveal more destinations beside the parent menu.
Show codeHide code
Link items
ContextMenuLinkItem renders a real anchor, so a row can navigate while keeping menu-item behavior.
Pass external for outbound links (target="_blank", rel="noreferrer noopener", trailing arrow).
Show codeHide code
Selection rows
ContextMenuCheckboxItem toggles independently; ContextMenuRadioItem rows wrapped in a
ContextMenuRadioGroup share one value. Both pass closeOnClick={false} so the menu stays open
while you adjust the options.
Show codeHide code
Single select
A selected row shows a leading check; forwarding closeOnClick={false} moves the check without dismissing the menu. Pass selected on every row of a single-select list so unselected rows keep the leading gutter.
Show codeHide code
API Reference
ContextMenu
Root of the context menu: holds the open state and the pointer position the menu anchors to, and renders no element of its own. Wrap a `ContextMenuTrigger` and a `ContextMenuContent` in it; the menu opens on right click or long press anywhere inside the trigger.
ContextMenuTrigger
The behavior surface that opens the menu on right click or long press — Base UI applies no styling of its own, so give it a look by grafting it onto your own element via `render`: ```tsx <ContextMenuTrigger render={<MyCanvasArea />}>Right-click here</ContextMenuTrigger>; ``` Maps 1:1 to `ContextMenu.Trigger`.
ContextMenuContent
The root context-menu surface: Base UI's portal and positioner wrapped around an elevated, scrollable `OverlayPanel` holding the flat `role="menu"` popup. Anchors to the pointer and sizes itself like a dropdown. Rows (`ContextMenuItem`, `ContextMenuSeparator`, …) are its children. A submenu's own surface is `ContextMenuSubmenuContent`, not this part.
ContextMenuItem
The ready-made menu row: grafts Base UI's `Item` behavior onto the styled `ContextMenuItem` and composes its region parts — a leading single-select check, an optional leading icon, the label, and optional trailing content.
ContextMenuCheckboxItem
The ready-made toggleable context-menu row: grafts Base UI's `CheckboxItem` behavior onto the styled row and bakes a kept-mounted tick indicator, so `checked` / `defaultChecked` / `onCheckedChange` forward straight to Base UI and the tick reads state from context.
ContextMenuRadioGroup
Wraps `ContextMenuRadioItem`s sharing one `value` — Base UI's radio-group state, no chrome.
ContextMenuRadioItem
The ready-made single-select context-menu row: grafts Base UI's `RadioItem` behavior onto the styled row and bakes a kept-mounted radio dot. Wrap rows in a `ContextMenuRadioGroup` carrying `value`/`onValueChange`; the dot reads the selected state from context.
ContextMenuLinkItem
The ready-made navigational menu row: grafts Base UI's `LinkItem` behavior onto the styled `ContextMenuLinkItem` and composes its region parts — a leading icon, the label, and optional trailing content.
ContextMenuGroup
Groups related rows; provide `aria-label`/`aria-labelledby` when the group needs a name.
ContextMenuSeparator
Ready-made divider between groups of items: Base UI's `ContextMenu.Separator` behavior (the `separator` role) grafted onto the styled thin rule.
ContextMenuSubmenu
Groups all parts of a nested submenu — its `ContextMenuSubmenuTrigger` row and the `ContextMenuSubmenuContent` that opens beside it. Holds the submenu's own open state and renders no element of its own.
ContextMenuSubmenuTrigger
The ready-made submenu trigger: grafts Base UI's `SubmenuTrigger` behavior onto the styled `ContextMenuSubmenuTrigger` and composes its region parts — a leading icon, the label, optional trailing content, and the caret that points toward the submenu.