Components / Actions

ContextMenu

Secondary actions kept close to the selected object.

Install

npx shadcn@latest add https://irisui.dev/r/context-menu.json
import { ContextMenu } from "@/components/iris/context-menu/context-menu";
Registry item context-menuBrings in foundationRegistry JSON

Preview

ContextMenu

Secondary actions kept close to the selected object: right-click (or Shift+F10) on the wrapped content and a menu grows from the pointer.

When to use

  • Files, cards, rows and canvas objects that have several secondary actions (rename, duplicate, copy link, delete).
  • Power-user shortcuts that duplicate actions already available elsewhere in the UI.
  • Do not hide the only path to an action in a context menu — expose it in a visible DropdownMenu or ButtonGroup too.

Usage

import { ContextMenu } from "@/components/iris/context-menu/context-menu";

<ContextMenu
  label="File actions"
  items={[
    { id: "rename", label: "Rename", icon: <PencilIcon size={15} />, onSelect: rename },
    { id: "duplicate", label: "Duplicate", icon: <CopyIcon size={15} />, onSelect: duplicate },
    { id: "pin", label: "Pin to sidebar", checked: pinned, onSelect: togglePin },
    { id: "delete", label: "Delete document", icon: <TrashIcon size={15} />, destructive: true, onSelect: remove },
  ]}
>
  <DocumentCard document={doc} />
</ContextMenu>;

Props

Prop Type Default Description
children ReactNode — The target area (required). It is wrapped in a focusable element that listens for right-click and the menu key.
items ContextMenuItem[] — Required: { id, label, icon?, onSelect?, disabled?, destructive?, checked? }. Without an icon, checked shows a check mark.
label string "Context menu" Accessible name of the target and the menu.

Notes

  • The target gets tabIndex=0, aria-haspopup="menu" and aria-expanded. The ContextMenu key or Shift+F10 opens the menu from the keyboard.
  • Inside the menu: ArrowUp/ArrowDown, Home and End move between items, Escape closes, and selecting an item returns focus to the target.
  • The menu portals to <body>, is measured before paint and clamped 8px inside the viewport, and scales in from the pointer. Reopening at a new point fades the old menu out in place.
  • Reduced motion replaces the scale with an instant fade.