Context Menu
StableActions for a specific object, opened by right-click or long-press right where the pointer is — a shortcut, never the only path.
Installation
$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/context-menu.jsonUsage
import {
ContextMenu,
ContextMenuContent,
ContextMenuGroup,
ContextMenuItem,
ContextMenuTrigger,
} from "@/components/ui/context-menu"<ContextMenu>
<ContextMenuTrigger className="rounded-xl border border-dashed p-10">
Right-click here
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuGroup>
<ContextMenuItem>Rename</ContextMenuItem>
<ContextMenuItem>Duplicate</ContextMenuItem>
</ContextMenuGroup>
</ContextMenuContent>
</ContextMenu>ContextMenuTrigger defines the area that responds to a right-click (or a long-press on touch). The menu opens at the pointer's position. Items, groups, submenus, checkbox and radio items work exactly like Dropdown Menu's.
Examples
Browser-style menu
Everything a context menu can hold: shortcuts, a disabled item, a submenu, checkbox items and a labelled radio group.
Items in a list
Give every row its own ContextMenu, so the actions always apply to the object under the pointer. The trigger picks up data-popup-open while its menu is open — use it to keep the row highlighted, so people can see what the menu acts on.
Canvas objects
Design tools, editors and maps rely on context menus for object-level commands. Keep the vocabulary identical to the app's main menus and show the same shortcuts.
Guidelines
When to use
- To speed up actions on objects people manipulate directly: files, rows, canvas layers, messages.
- In dense, pointer-first tools where visible action buttons would crowd the interface.
When not to use
- As the only way to reach an action. Right-click isn't discoverable, doesn't exist on most touch devices, and is awkward from a keyboard. Every item must also be available from a visible control — a Dropdown Menu on a
⋯button, a toolbar, or the object's detail view. - On surfaces where people expect the browser's own menu, such as text they want to copy or links they want to open in a new tab.
Mirror the visible menus
A context menu is an accelerator for commands that already exist. Use the same labels, order and shortcuts as the row's ⋯ menu or the app's menubar, so people learn the vocabulary once. Put the most frequent actions first and destructive actions last, behind a separator.
Keep it short
Context menus are read at the pointer, under time pressure. Aim for fewer than ten items in two or three groups, avoid more than one level of submenus, and never put long-form content inside.
Accessibility
Context Menu is built on the Base UI Context Menu, which follows the WAI-ARIA menu pattern once open (the APG describes menus and menubars on one page).
| Key | Behavior |
|---|---|
ShiftF10 | With focus inside the trigger area, opens the menu — the platform's keyboard equivalent of a right-click. Also the ContextMenu key on Windows keyboards. |
↓↑ | Moves focus between items; loops at the ends. |
HomeEnd | Focuses the first or last item. |
→← | Opens or closes a submenu. |
EnterSpace | Activates the focused item. |
A–Z | Typeahead to the next item starting with the typed characters. |
Esc | Closes the menu. |
- Touch. A long-press on the trigger opens the menu, so the same actions work on phones and tablets.
- Parity. Because context menus are hard to discover with assistive technology, the visible alternative isn't optional — it's what makes the actions accessible at all.
API reference
ContextMenu
The root. Accepts the Base UI ContextMenu.Root props.
ContextMenuTrigger
The area that listens for right-click and long-press. Renders a <div> with select-none; style it like any container. It receives data-popup-open while its menu is open.
ContextMenuContent
ContextMenuItem
Other parts
ContextMenuCheckboxItem, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut and ContextMenuGroup share their API with the equivalent Dropdown Menu parts.