# Context menu

> Actions where you right-click: the menu grows from the exact point, a long press opens it on touch, and Shift+F10 from the keyboard.

Custom right-click menus often forget touch and the keyboard. This one opens at the pointer on right-click, after a 500ms long press on touch (the area dims slightly while it waits), and on Shift+F10 or the menu key. It grows from the exact point, stays inside the window, and right-clicking elsewhere moves it there.

## Install

```bash
npx shadcn@latest add https://hairlineui.com/r/context-menu.json
```

Needs React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.

- npm: `lucide-react`
- Hairline UI components it needs (the CLI installs them too): `ui-interaction-motion`
- Docs and live preview: https://hairlineui.com/ui/context-menu
- Registry item (source): https://hairlineui.com/r/context-menu.json

## Usage

```tsx
import { ContextMenu } from "@/components/ui/context-menu";

<ContextMenu items={[{ id: "open", label: "Open" }, { id: "delete", label: "Delete", destructive: true, onSelect: remove }]}>
  <FileCard file={file} />
</ContextMenu>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | – | The area with the menu. |
| `items` | `MenuEntry[]` | – | Same rows as the dropdown menu. |
| `label` | `string` | `"Actions"` | Accessible name of the menu. |
| `onOpenChange` | `(open) => void` | – | Opened or closed. |

## States

- **waiting**: On touch, the area eases to 0.985 and 80% while the long press counts down.
- **open**: The menu rises from the point (320ms).
- **pick**: It closes and focus returns to the area.

## What it handles

A right-click menu that only works with a mouse leaves phones and keyboards out; this one has a way in for each.

- **Three ways in**: Right-click, long press (500ms, cancelled by movement) and Shift+F10.
- **From the point**: Grows from where you clicked; flips and shifts to fit.
- **Same rows as the dropdown**: Gliding highlight, typeahead and checkable rows.
- **Callout suppressed**: iOS doesn't show its own menu on the long press.

## Replaces

Radix ContextMenu, long-press handling, viewport collision

## Where it fits

- **File and asset grids**: Rename, move, delete on a right-click.
- **Canvas and boards**: Actions for the item under the pointer.
- **Tables**: Row actions without a "…" column.
- **Text editors**: Custom actions on a selection.

## Notes

- Placement, presence and dismissal live in floating.ts, shared by tooltip, popover, dropdown and context menus: they all flip, shift, enter and leave the same way.
- The area takes focus (tabIndex 0) so Shift+F10 can reach it.
- Reduced motion: it fades; the area doesn't dim.

License: MIT (https://hairlineui.com/license#components)
