Skip to main content
Gremorie

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

Right-click here

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>

PropTypeDefaultDescription
insetbooleanfalseAdds pl-8 so the item lines up with checkbox/radio rows.
variant"default" | "destructive""default"Switches text and icon color to the destructive token.
disabledbooleanfalseDisables 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

  1. <ContextMenu> owns the open/close state.
  2. <ContextMenuTrigger> wraps the region; right-click anywhere in it opens the menu.
  3. <ContextMenuContent> mounts via Portal at the cursor position.
  4. 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 Menu key (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 DropdownMenu equivalent.
  • Role: role="menu" on content, role="menuitem" on items, role="menuitemcheckbox" and role="menuitemradio" on stateful variants.
  • Keyboard: arrow keys navigate; Enter and Space activate; type-ahead jumps to items starting with the typed letter; Esc closes.
  • 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.
  • Dropdown Menu - same compound, triggered by a visible button.
  • Popover - non-menu interactive overlay anchored to a trigger.
  • Tooltip - hover hint, never a menu.

On this page