Context Menu
Displays a menu to the user — such as a set of actions or functions — triggered by right click or touch long-press, built on the Base UI Menu primitive.
"use client";
import {
ContextMenu,
ContextMenuCheckboxItem,
ContextMenuContent,
ContextMenuItem,
ContextMenuLabel,
ContextMenuRadioGroup,
ContextMenuRadioItem,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuTrigger,
} from "@/registry/base/ui/context-menu";
export default function ContextMenuDemo() {
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-36 w-full max-w-sm items-center justify-center rounded-md border border-dashed text-sm select-none">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-52">
<ContextMenuItem>
Back
<ContextMenuShortcut>⌘[</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem disabled>
Forward
<ContextMenuShortcut>⌘]</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Reload
<ContextMenuShortcut>⌘R</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuSub>
<ContextMenuSubTrigger inset>More tools</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Save page</ContextMenuItem>
<ContextMenuItem>Create shortcut</ContextMenuItem>
<ContextMenuItem>Developer tools</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuCheckboxItem defaultChecked>
Show bookmarks
</ContextMenuCheckboxItem>
<ContextMenuSeparator />
<ContextMenuRadioGroup defaultValue="pedro">
<ContextMenuLabel inset>People</ContextMenuLabel>
<ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem>
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenuContent>
</ContextMenu>
);
}
Installation
npx shadcn@latest add https://sevenui.dev/r/context-menu.jsonUsage
"use client";
import {
ContextMenu,
ContextMenuCheckboxItem,
ContextMenuContent,
ContextMenuItem,
ContextMenuLabel,
ContextMenuRadioGroup,
ContextMenuRadioItem,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
export default function ContextMenuDemo() {
return (
<ContextMenu>
<ContextMenuTrigger className="flex h-36 w-full max-w-sm items-center justify-center rounded-md border border-dashed text-sm select-none">
Right click here
</ContextMenuTrigger>
<ContextMenuContent className="w-52">
<ContextMenuItem>
Back
<ContextMenuShortcut>⌘[</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem disabled>
Forward
<ContextMenuShortcut>⌘]</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Reload
<ContextMenuShortcut>⌘R</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuSub>
<ContextMenuSubTrigger inset>More tools</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Save page</ContextMenuItem>
<ContextMenuItem>Create shortcut</ContextMenuItem>
<ContextMenuItem>Developer tools</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuCheckboxItem defaultChecked>
Show bookmarks
</ContextMenuCheckboxItem>
<ContextMenuSeparator />
<ContextMenuRadioGroup defaultValue="pedro">
<ContextMenuLabel inset>People</ContextMenuLabel>
<ContextMenuRadioItem value="pedro">Pedro Duarte</ContextMenuRadioItem>
<ContextMenuRadioItem value="colm">Colm Tuite</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenuContent>
</ContextMenu>
);
}
API reference
Every part imports from @base-ui/react/context-menu, which re-exports
the same Menu part objects used by
Dropdown Menu plus its own Root and
Trigger — so items share all Menu semantics: data-disabled styling,
the closeOnClick defaults, variant/inset on items, and the
checkbox/radio behavior documented there.
ContextMenu
Extends the
Base UI Context Menu
Root. Opens on right click (desktop) or touch long-press (mobile) —
there is no click-to-open trigger. Omits modal: context menus are
always modal internally.
| Prop | Type | Default |
|---|---|---|
open / defaultOpen |
boolean |
false |
onOpenChange |
(open, eventDetails) => void |
— |
onOpenChangeComplete |
fires after animations finish | — |
highlightItemOnHover |
boolean |
true |
loopFocus |
boolean — arrow keys wrap |
true |
actionsRef |
ref with imperative close()/unmount() |
— |
disabled |
boolean |
false |
orientation |
arrow-key axis | "vertical" |
Keyboard: arrow keys navigate, Enter/Space activates, Escape closes the
current level, Tab exits, and typing jumps to items by first character
(override an item’s matched text with its label prop).
ContextMenuTrigger
Renders a plain <div> — the area a user right-clicks or long-presses —
not a button. Accepts no positioning props beyond className /
render / children; exposes data-popup-open while the menu is
open.
ContextMenuContent
Pointer-anchored and automatic: it deliberately exposes no
side/align/offset props — Base UI anchors the popup to the pointer
with built-in corner offsets, and passing side explicitly would
disable that behavior.
ContextMenuItem
Renders a <div> (set nativeButton when rendering a real button via
render); disabled styling via data-disabled.
| Prop | Type | Default |
|---|---|---|
variant |
"default" | "destructive" |
"default" |
inset |
boolean — align with checkable items |
false |
closeOnClick |
boolean |
true |
disabled |
boolean |
false |
label |
string — typeahead text override |
— |
ContextMenuCheckboxItem and ContextMenuRadioGroup / ContextMenuRadioItem
Checkbox items take checked / defaultChecked /
onCheckedChange(checked, eventDetails); the radio group takes
value / defaultValue / onValueChange and each radio item a
required value. Both item kinds default closeOnClick to false
so toggling keeps the menu open; state styles via
data-checked / data-unchecked.
ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent
Identical to dropdown-menu’s submenu composition (SubmenuRoot-based,
automatic RTL-aware positioning). The sub trigger hover-opens by
default:
| Prop | Type | Default |
|---|---|---|
openOnHover |
boolean |
true |
delay |
number |
100 (ms) |
closeDelay |
number |
0 (ms) |
closeParentOnEsc |
boolean |
false |
ContextMenuGroup, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut
ContextMenuLabel must sit inside a group (Base UI wires
aria-labelledby); the separator takes an orientation (default
"horizontal"); the shortcut is a plain span.
Usage guidance
A context menu is a supplementary shortcut, not the only way to reach an action — right click and long-press are not discoverable, and some input devices and assistive technologies never trigger them. Keep a visible control (a button, toolbar action, or regular menu item) for every action also available in the context menu.