Context Menu
Context menus open on right-click or long press, anchored to the pointer rather than to a button. Built on Base UI Context Menu, which shares its parts with Menu, so rows, groups, submenus and separators are the same components the Dropdown Menu uses, re-exported under ContextMenu* names.
Because it has no visible trigger, a context menu is a shortcut, never the only route to an action. Every item in it must also be reachable from a button, a row-actions dropdown, or a keyboard shortcut.
Examples
Right-click an area
Usage
ContextMenuTrigger renders a div around the region that should respond to right-click. Pass asChild to make an element you already have the trigger instead. The element keeps its own click behavior, so a link still navigates on left-click.
<ContextMenu>
<ContextMenuTrigger asChild>
<Link href="/">
<Wordmark height={17} />
</Link>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuLabel>Rogo wordmark</ContextMenuLabel>
<ContextMenuItem prefix={<IconArrowInbox />} onClick={downloadSvg}>
Download SVG
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem asChild>
<Link href="/brand/assets">All brand assets</Link>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>Rows carry the same API as the dropdown's: prefix, suffix, selected, actionType="destructive", tooltip, and submenus via ContextMenuSub. See Dropdown Menu for the full row anatomy.
Props
ContextMenu
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Controls the open state. |
defaultOpen | boolean | false | Open state on mount when uncontrolled. |
onOpenChange | (open: boolean) => void | - | Called when the menu opens or closes. |
ContextMenuTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render the single child as the trigger instead of wrapping it. |
ContextMenuContent
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top" | "bottom" | "inline-start" | "inline-end" | "inline-end" | Side of the pointer the popup opens toward. |
sideOffset | number | 2 | Gap from the pointer, in px. |
align | "start" | "center" | "end" | "start" | Alignment along the side axis. |
collisionPadding | number | 8 | Minimum gap kept from the viewport edge. |
container | HTMLElement | null | - | Portal target. Defaults to the document body. |
Other subcomponents
Aliases of the dropdown's rows, so both menus stay identical: ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuGroup, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent.
Guidelines
Do
- Keep the menu short. A context menu is for the handful of actions that belong to that one object
- Mirror every action somewhere visible, since right-click is undiscoverable on its own
- Label the object at the top when the trigger is small, so the menu says what it acts on
- Put destructive actions last, behind a separator
Don't
- Don't use a context menu as the only way to reach an action
- Don't attach one to a whole page or panel. Scope it to a specific object
- Don't replace the browser's native menu on text or links unless you offer more than it does