Context Menu
Action menu invoked via right-click on a region. Same compound shape as DropdownMenu, anchored to a target area.
Overview
ContextMenu is a power-user accelerator. Right-click is invisible to users who haven't been taught about it (most touch users; many web users today), so treat this menu as an additive shortcut, never the only path to an action. Every option shown here should also be reachable through a button, DropdownMenu, or keyboard shortcut elsewhere in the UI.
The compound mirrors DropdownMenu exactly: items, groups, separators, submenus, checkbox or radio variants, shortcuts. The only difference is the trigger: ContextMenuTrigger wraps a region, and the menu opens at the cursor position on right-click.
Preview
Installation
bash npx gremorie@latest add rx-context-menu bash pnpm dlx gremorie@latest add rx-context-menu
bash yarn dlx gremorie@latest add rx-context-menu
bash bunx --bun gremorie@latest add rx-context-menu
Usage
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger,
} from "@gremorie/rx-overlays";
export function Example() {
return (
<ContextMenu>
<ContextMenuTrigger>
<div className="flex h-32 w-full items-center justify-center rounded-lg border border-dashed text-sm text-muted-foreground">
Right-click here
</div>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem>Copy</ContextMenuItem>
<ContextMenuItem>Paste</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem>Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}Angular edition planned for Phase 5h. Star the repo to track progress.
API
<ContextMenu>
Extends Radix ContextMenu.Root. Standard controlled API (onOpenChange, modal).
<ContextMenuTrigger>
Wraps the region that should respond to right-click. By default it renders a <span>; use asChild to forward styles to a target element.
<ContextMenuContent>
Same shape as DropdownMenuContent. Wrapped in a Radix Portal. Positions itself at the cursor on open.
<ContextMenuItem>
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Adds pl-8 so the item lines up with checkbox/radio rows. |
variant | "default" | "destructive" | "default" | Switches text and icon color to the destructive token. |
disabled | boolean | false | Disables interaction; renders at 50% opacity. |
<ContextMenuCheckboxItem>, <ContextMenuRadioGroup>, <ContextMenuRadioItem>
Same semantics as their DropdownMenu counterparts. Indicators render automatically in the absolute-positioned left slot.
<ContextMenuLabel>, <ContextMenuSeparator>, <ContextMenuShortcut>
Non-interactive helpers identical to DropdownMenu.
<ContextMenuSub> + <ContextMenuSubTrigger> + <ContextMenuSubContent>
Nested submenu pattern. Sub-trigger renders an auto-positioned chevron.
<ContextMenuPortal>, <ContextMenuGroup>
Pass-throughs over the Radix primitives with data-slot attributes.
Composition
<ContextMenu>owns the open/close state.<ContextMenuTrigger>wraps the region; right-click anywhere in it opens the menu.<ContextMenuContent>mounts via Portal at the cursor position.- Inside content: same layout vocabulary as
DropdownMenu(items, groups, separators, shortcuts, submenus).
Variations
File browser actions
Right-click a file row to expose move, rename, and delete.
<ContextMenu>
<ContextMenuTrigger asChild>
<tr>
<td>Report.pdf</td>
<td>2.4 MB</td>
</tr>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem>Open</ContextMenuItem>
<ContextMenuItem>Rename</ContextMenuItem>
<ContextMenuSub>
<ContextMenuSubTrigger>Move to</ContextMenuSubTrigger>
<ContextMenuSubContent>
<ContextMenuItem>Reports</ContextMenuItem>
<ContextMenuItem>Archive</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
<ContextMenuItem variant="destructive">Delete</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>Canvas tools with shortcuts
Power-user shortcuts in a creative app. Pair every item with its keyboard equivalent.
<ContextMenuContent>
<ContextMenuItem>
Copy
<ContextMenuShortcut>⌘C</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
Paste
<ContextMenuShortcut>⌘V</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuCheckboxItem checked={snap}>Snap to grid</ContextMenuCheckboxItem>
</ContextMenuContent>Per-cell context with radio group
Toggle alignment within a table cell.
<ContextMenuContent>
<ContextMenuLabel>Align</ContextMenuLabel>
<ContextMenuSeparator />
<ContextMenuRadioGroup value={align} onValueChange={setAlign}>
<ContextMenuRadioItem value="left">Left</ContextMenuRadioItem>
<ContextMenuRadioItem value="center">Center</ContextMenuRadioItem>
<ContextMenuRadioItem value="right">Right</ContextMenuRadioItem>
</ContextMenuRadioGroup>
</ContextMenuContent>Accessibility
- Trigger: opens on right-click and on the
Menukey (Windows). Long-press is not a standard web gesture, so touch users will not see the menu by default. - Additive only: never put an action behind a context menu exclusively. Provide a visible button or
DropdownMenuequivalent. - Role:
role="menu"on content,role="menuitem"on items,role="menuitemcheckbox"androle="menuitemradio"on stateful variants. - Keyboard: arrow keys navigate;
EnterandSpaceactivate; type-ahead jumps to items starting with the typed letter;Esccloses. - Submenus:
→opens,←closes. - Focus management: focus moves into the menu on open and returns to the trigger region on close.
- Reduced motion: open/close animations honor
prefers-reduced-motion.
Related
- Dropdown Menu - same compound, triggered by a visible button.
- Popover - non-menu interactive overlay anchored to a trigger.
- Tooltip - hover hint, never a menu.