Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

ContextMenu

The right-click sibling of DropdownMenu — a Radix-backed cursor-anchored menu with leading icons, Kbd shortcut hints, checkbox/radio rows, nested submenus, and a danger ramp for destructive items, composed via statics.

Import

import { Eye, Pin, Tag, Trash2 } from "@roger-emerson/ploxum-icons";
import { ContextMenu } from "@roger-emerson/ploxum-primitives";

Usage

<ContextMenu>
  <ContextMenu.Trigger asChild>
    <div className="venue-zone">Gate 4 — right-click for actions</div>
  </ContextMenu.Trigger>
  <ContextMenu.Content width={208}>
    <ContextMenu.Label>Gate 4</ContextMenu.Label>
    <ContextMenu.Item icon={<Eye size={14} strokeWidth={1.5} />} onSelect={focus} shortcut="⌘[">
      Focus zone
    </ContextMenu.Item>
    <ContextMenu.Item icon={<Tag size={14} strokeWidth={1.5} />} onSelect={tag}>
      Add tag…
    </ContextMenu.Item>
    <ContextMenu.Separator />
    <ContextMenu.CheckboxItem checked={pinned} onCheckedChange={setPinned}>
      Pin to overlay
    </ContextMenu.CheckboxItem>
    <ContextMenu.Separator />
    <ContextMenu.Item destructive icon={<Trash2 size={14} strokeWidth={1.5} />} onSelect={remove}>
      Remove zone
    </ContextMenu.Item>
  </ContextMenu.Content>
</ContextMenu>

Props

ContextMenu (root)

PropTypeDefaultDescription
onOpenChange(open: boolean) => voidOpen-state callback. The menu opens on right-click — there is no controlled open.
childrenReactNodeTrigger + Content.

ContextMenu.Trigger

Radix ContextMenu.Trigger passthrough — use asChild to wrap the surface that should respond to right-click (a map zone, table row, card, etc.). The whole trigger area is the hit target.

ContextMenu.Content

PropTypeDefaultDescription
widthnumberFixed width in px. Defaults to content-sized with a 180px floor.
classNamestringMerged onto the panel.

Positions at the cursor, not relative to the trigger — so there are no align / sideOffset props. Also accepts the remaining Radix ContextMenu.Content props (collisionPadding, onCloseAutoFocus, …).

ContextMenu.Item

PropTypeDefaultDescription
onSelect(event: Event) => voidFires on selection (click or Enter).
iconReactNodeLeading icon. Inherits the item's text color, including danger on destructive items.
shortcutstringKeyboard shortcut hint, rendered right-aligned in a Kbd.
destructivebooleanRenders the item in the danger ramp. Always pair with icon.
disabledbooleanDims the item and removes it from pointer/keyboard flow.
classNamestringMerged onto the item.

ContextMenu.CheckboxItem

PropTypeDefaultDescription
checkedbooleanChecked state — controlled when paired with onCheckedChange.
onCheckedChange(checked: boolean) => voidFires on toggle.
onSelect(event: Event) => voidFires on selection, before the toggle resolves.
disabledbooleanDims the row and removes it from pointer/keyboard flow.
classNamestringMerged onto the row.
childrenReactNodeRow label. Amber check indicator renders in the leading gutter.

ContextMenu.RadioGroup

PropTypeDefaultDescription
valuestringSelected item value (controlled with onValueChange).
onValueChange(value: string) => voidFires when the selection changes.
childrenReactNodeRadioItems, optionally with a Label.

ContextMenu.RadioItem

PropTypeDefaultDescription
valuestringRequired. Identifies the item within its RadioGroup.
disabledbooleanDims the row and removes it from pointer/keyboard flow.
classNamestringMerged onto the row.
childrenReactNodeRow label. Amber dot indicator renders in the leading gutter.

ContextMenu.Sub / ContextMenu.SubContent

ContextMenu.Sub is the Radix Sub passthrough wrapping a nested branch. ContextMenu.SubContent mirrors ContextMenu.Content — it takes the same width, className, and remaining Radix SubContent props.

ContextMenu.SubTrigger

PropTypeDefaultDescription
iconReactNodeLeading icon. Inherits the item's text color.
disabledbooleanDims the row and removes it from flow.
classNamestringMerged onto the row.
childrenReactNodeRow label. A trailing chevron is appended automatically.

ContextMenu.Separator / ContextMenu.Label

Both take only className (Label also takes children). Label renders the uppercase tertiary group heading.

ContextMenu.Shortcut / ContextMenu.Group

ContextMenu.Shortcut renders a right-aligned Kbd for hand-composed rows (prefer the Item shortcut prop for standard items). ContextMenu.Group is the Radix Group passthrough for grouping related items under one Label for assistive tech.

Design rules

  • Destructive items must pair destructive with an icon — the danger state reads by shape as well as color, never hue alone.
  • shortcut is a hint chip only; the menu does not bind the key. Register the actual handler where the command lives (usually the CommandPalette's action map).
  • The panel animates a 200ms fade/scale on the cubic-bezier(0.25, 1, 0.5, 1) ease — within the motion budget, no spring. Don't extend it. SubContent shares the same motion.
  • ContextMenu shares DropdownMenu's overlay treatment — same overlay surface, border, and shadow — so the two menus read as one family.
  • ContextMenu is a menu: focus moves into it on open and returns to the trigger on close. For non-modal anchored surfaces that must not trap focus, use Popover (heuristic 9).

Storybook

Open ContextMenu in Storybook ↗