ContextMenu
A menu triggered by a right-click (or long-press on touch) that surfaces contextual actions for the element under the cursor. Built on @base-ui/react/menu with full keyboard navigation and ARIA menu role.
Anatomy
<ContextMenu> is the stateful root. ContextMenuTrigger wraps the element that should respond to right-click. ContextMenuContent renders in a portal at the cursor position. ContextMenuItem is an action row. ContextMenuLabel adds a non-interactive heading. ContextMenuSeparator draws a divider. ContextMenuShortcut displays a keyboard hint aligned to the right.
Right-click here
ContextMenuTrigger (right-click zone)ContextMenuContent (portal at cursor)
Examples
Text editor actions
Right-click for text actions
File actions
document.pdf
Design Guidelines
Do
- Mirror keyboard shortcuts. If an action has a shortcut (Cut: ⌘X), show it in the menu with
ContextMenuShortcut— it reinforces discoverability. - Surface only context-relevant actions. The menu should adapt to what the user right-clicked — a text selection menu differs from a file menu.
- Place destructive items last. Separate delete/remove actions below a
ContextMenuSeparatorso users don't trigger them accidentally.
Don't
- Don't rely on it as the only path. Context menus are hidden by default — critical actions must also be reachable via visible UI elements.
- Don't use for primary navigation. Context menus are for actions on selected content, not for moving between pages or sections.
- Don't show irrelevant items. Rendering greyed-out or disabled items for the current context adds noise — hide them instead.
Developer Reference
Accessibility
ContextMenuContenthasrole="menu"; eachContextMenuItemhasrole="menuitem".- The menu opens at the cursor position on right-click, or at the element's position on keyboard (
Shift+F10or the Menu key). - Arrow keys navigate items.
Enter/Spaceactivate.ESCcloses and returns focus to the trigger. ContextMenuTriggercan wrap any element — it adds acontextmenuevent listener without altering the element's semantics.
Usage
import {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuGroup,
ContextMenuLabel,
ContextMenuSeparator,
ContextMenuShortcut,
} from "@/components/ui/context-menu"
<ContextMenu>
<ContextMenuTrigger className="flex h-32 w-full items-center justify-center rounded-lg border border-dashed">
Right-click here
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuGroup>
<ContextMenuLabel>Actions</ContextMenuLabel>
<ContextMenuSeparator />
<ContextMenuItem>
Copy
<ContextMenuShortcut>⌘C</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Paste
<ContextMenuShortcut>⌘V</ContextMenuShortcut>
</ContextMenuItem>
</ContextMenuGroup>
<ContextMenuSeparator />
<ContextMenuItem className="text-destructive focus:text-destructive">
Delete
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>