# ContextMenu

> The menu of actions on one thing that opens at the pointer on right-click, or on press and hold on a touch screen.

Source: https://raft-design.botiverse.build/components/context-menu. Generated from the current release; where it differs from what you remember, this page is right.

A context menu is the menu of actions on one thing that opens where people right-click on desktop, or where they press and hold on a touch screen. It is the same menu that the thing's ⋯ button opens as a [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md): the same items, in the same order.

```tsx
import {
  Button,
  ContextMenu,
  ContextMenuItem,
  ContextMenuPopup,
  ContextMenuSeparator,
  ContextMenuShortcut,
} from "@botiverse/raft-ui";
import { Archive, ChevronRight, Copy, MoonStar, Pin, Trash } from "lucide-react";

export function ContextMenuComposition() {
  return (
    <ContextMenu>
      <ContextMenuPopup className="flex w-56 min-w-56 flex-col">
        <ContextMenuItem>
          <Pin />
          <span className="min-w-0 flex-1 truncate">Pin thread</span>
        </ContextMenuItem>
        <ContextMenuItem>
          <Copy />
          <span className="min-w-0 flex-1 truncate">Copy link</span>
          <ContextMenuShortcut>⌘C</ContextMenuShortcut>
        </ContextMenuItem>
        <ContextMenuItem>
          <MoonStar />
          <span className="min-w-0 flex-1 truncate">Move to</span>
          <ChevronRight className="ml-auto" />
        </ContextMenuItem>
        <ContextMenuSeparator />
        <ContextMenuItem>
          <Archive />
          <span className="min-w-0 flex-1 truncate">Archive</span>
        </ContextMenuItem>
        <ContextMenuItem>
          <Trash />
          <span className="min-w-0 flex-1 truncate">Delete</span>
          <ContextMenuShortcut>⌫</ContextMenuShortcut>
        </ContextMenuItem>
      </ContextMenuPopup>
    </ContextMenu>
  );
}
```

## When to use

| Situation                                                                 | Use                                                 |
| ------------------------------------------------------------------------- | --------------------------------------------------- |
| Right-click or press and hold on a message, a channel, a task or an agent | ContextMenu                                         |
| The same actions, from a visible button                                   | [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md)   |
| Acting on something on a phone                                            | ContextMenu on press and hold, never a bottom sheet |
| A value submitted with a form                                             | [Select](https://raft-design.botiverse.build/components/select.md)                       |

Which overlay fits which job is in [Choosing a component](https://raft-design.botiverse.build/components.md#overlays).

## Anatomy

ContextMenu has the same parts as DropdownMenu, with the `ContextMenu` prefix: `ContextMenuItem`, `ContextMenuItemLabel`, `ContextMenuShortcut`, `ContextMenuRadioGroup`, `ContextMenuRadioItem`, `ContextMenuCheckboxItem`, `ContextMenuLabel`, `ContextMenuSeparator`, `ContextMenuSubmenu`, `ContextMenuSubmenuTrigger`, `ContextMenuFooter`, `ContextMenuPortal` and `ContextMenuPopup`. They look and behave as described in [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md#anatomy). It has no item count part.

- `ContextMenu`: the root. Required.
- `ContextMenuTrigger`: the area that opens the menu: the message, the row, the card. Required.
- `ContextMenuContent`: the menu, portaled and opened at the pointer. Required.

## States

The highlight, the current value and disabled items are the same as in [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md#states).

## Behavior

- The menu opens at the pointer, or at the finger after press and hold, with its top-left corner there.
- When it would cross the window edge, it shifts to stay at least 8px inside the window instead of flipping.
- It stays where it opened while the page behind it scrolls.
- Choosing an action closes the menu; Esc and a click outside close it too.
- An item is as tall as its content, with constant padding, as in a [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md#behavior) ([Forms](https://raft-design.botiverse.build/patterns/forms.md#option-height)).

## Content

The item labels follow [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md#content): Title Case, and the same words as the dialog an item opens.

## Accessibility

- ContextMenu wraps the Base UI ContextMenu. It provides the `menu` role, the item roles, arrow keys, typeahead and Esc.
- Name the menu after the thing it acts on with `aria-label` on `ContextMenuContent` ("Message from Wug").
- Right-click and press and hold are not available from the keyboard. Offer every action of a context menu from a visible control as well, usually the ⋯ [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md).

## Rules

- Build the context menu and the ⋯ menu from one list of items, so they never drift apart.
- Use the same menu on desktop and on a phone. Don't build a separate phone sheet for the same actions.
- Follow the rules of [DropdownMenu](https://raft-design.botiverse.build/components/dropdown-menu.md#rules): no color on destructive items, and the quick reactions first in the message menu.

## API

### ContextMenu

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `actionsRef` | `RefObject<MenuRootActions \| null>` |  | A ref to imperative actions. - `unmount`: Manually unmounts the menu. Call this after any externally controlled closing animation finishes. - `close`: When specified, the menu can be closed imperatively. |
| `children` | `ReactNode` |  |  |
| `closeParentOnEsc` | `boolean` |  | Deprecated. |
| `defaultOpen` | `boolean` | `false` | Whether the menu is initially open. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `highlightItemOnHover` | `boolean` | `true` | Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state. |
| `loopFocus` | `boolean` | `true` | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
| `onOpenChange` | `(open: boolean, eventDetails: BaseContextMenu.Root.ChangeEventDetails) => void` |  | Event handler called when the menu is opened or closed. |
| `onOpenChangeComplete` | `(open: boolean) => void` |  | Event handler called after any animations complete when the menu is opened or closed. |
| `open` | `boolean` |  | Whether the menu is currently open. |
| `orientation` | `MenuRootOrientation` | `'vertical'` | The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. |

### ContextMenuCheckboxItem

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `checked` | `boolean` |  | Whether the checkbox item is currently ticked. |
| `closeOnClick` | `boolean` | `false` | Whether to close the menu when the item is clicked. |
| `defaultChecked` | `boolean` | `false` | Whether the checkbox item is initially ticked. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `id` | `string` |  |  |
| `label` | `string` |  | Overrides the text label to use when the item is matched during keyboard text navigation. |
| `nativeButton` | `boolean` | `false` | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button. |
| `onCheckedChange` | `(checked: boolean, eventDetails: BaseContextMenu.CheckboxItem.ChangeEventDetails) => void` |  | Event handler called when the checkbox item is ticked or unticked. |
| `onClick` | `(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void` |  | The click handler for the menu item. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuCheckboxItemIndicator

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `keepMounted` | `boolean` | `false` | Whether to keep the HTML element in the DOM when the checkbox item is not checked. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuContent

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `portalProps` | `ContextMenuPortalProps` |  |  |
| `align` | `Align` | `"start"` | How to align the popup relative to the specified side. |
| `alignOffset` | `number \| OffsetFunction` | `0` | Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. |
| `anchor` | `Element \| VirtualElement \| RefObject<Element \| null> \| (() => Element \| VirtualElement \| null)` |  | An element to position the popup against. By default, root context menus are positioned at the pointer, and submenus are positioned against their trigger. |
| `arrowPadding` | `number` |  | Minimum distance to maintain between the arrow and the edges of the popup. |
| `children` | `ReactNode` |  |  |
| `collisionAvoidance` | `CollisionAvoidance` | `CONTENT_COLLISION_AVOIDANCE` | Determines how to handle collisions when positioning the popup. |
| `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | An element or a rectangle that delimits the area that the popup is confined to. |
| `collisionPadding` | `Padding` | `8` | Additional space to maintain from the edge of the collision boundary. |
| `disableAnchorTracking` | `boolean` | `false` | Whether to disable the popup from tracking any layout shift of its positioning anchor. |
| `finalFocus` | `boolean \| RefObject<HTMLElement \| null> \| ((closeType: InteractionType) => boolean \| HTMLElement \| null \| void)` |  | Determines the element to focus when the menu is closed. |
| `id` | `string` |  |  |
| `positionMethod` | `"fixed" \| "absolute"` | `"fixed"` | Deprecated. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |
| `side` | `Side` | `"right"` | Which side of the anchor element to align the popup against. May automatically change to avoid collisions. |
| `sideOffset` | `number \| OffsetFunction` | `0` | Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. |
| `sticky` | `boolean` | `false` | Whether to maintain the popup in the viewport after the anchor element was scrolled out of view. |

Also takes the attributes of its element.

### ContextMenuFooter

Also takes the attributes of its element.

### ContextMenuItem

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `closeOnClick` | `boolean` | `true` | Whether to close the menu when the item is clicked. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `id` | `string` |  |  |
| `label` | `string` |  | Overrides the text label to use when the item is matched during keyboard text navigation. |
| `nativeButton` | `boolean` | `false` | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button. |
| `onClick` | `(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void` |  | The click handler for the menu item. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuItemLabel

Also takes the attributes of its element.

### ContextMenuLabel

Also takes the attributes of its element.

### ContextMenuPopup

Also takes the attributes of its element.

### ContextMenuPortal

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `container` | `HTMLElement \| ShadowRoot \| RefObject<HTMLElement \| ShadowRoot \| null>` |  | A parent element to render the portal element into. |
| `keepMounted` | `boolean` | `false` | Whether to keep the portal mounted in the DOM while the popup is hidden. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuRadioGroup

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` |  | The content of the component. |
| `defaultValue` | `any` |  | The uncontrolled value of the radio item that should be initially selected. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `onValueChange` | `(value: any, eventDetails: BaseContextMenu.RadioGroup.ChangeEventDetails) => void` |  | Function called when the selected value changes. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |
| `value` | `any` |  | The controlled value of the radio item that should be currently selected. |

Also takes the attributes of its element.

### ContextMenuRadioItem

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `closeOnClick` | `boolean` | `false` | Whether to close the menu when the item is clicked. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `id` | `string` |  |  |
| `label` | `string` |  | Overrides the text label to use when the item is matched during keyboard text navigation. |
| `nativeButton` | `boolean` | `false` | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button. |
| `onClick` | `(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void` |  | The click handler for the menu item. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |
| `value` (required) | `any` |  | Value of the radio item. This is the value that will be set in the MenuRadioGroup when the item is selected. |

Also takes the attributes of its element.

### ContextMenuRadioItemIndicator

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `keepMounted` | `boolean` | `false` | Whether to keep the HTML element in the DOM when the radio item is inactive. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuSeparator

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `orientation` | `Orientation` | `'horizontal'` | The orientation of the separator. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuShortcut

Also takes the attributes of its element.

### ContextMenuSubmenu

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `actionsRef` | `RefObject<MenuRootActions \| null>` |  | A ref to imperative actions. - `unmount`: Manually unmounts the menu. Call this after any externally controlled closing animation finishes. - `close`: When specified, the menu can be closed imperatively. |
| `children` | `ReactNode` |  | The content of the submenu. |
| `closeParentOnEsc` | `boolean` | `false` | When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. |
| `defaultOpen` | `boolean` | `false` | Whether the menu is initially open. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `highlightItemOnHover` | `boolean` | `true` | Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state. |
| `loopFocus` | `boolean` | `true` | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
| `onOpenChange` | `(open: boolean, eventDetails: BaseContextMenu.SubmenuRoot.ChangeEventDetails) => void` |  | Event handler called when the menu is opened or closed. |
| `onOpenChangeComplete` | `(open: boolean) => void` |  | Event handler called after any animations complete when the menu is opened or closed. |
| `open` | `boolean` |  | Whether the menu is currently open. |
| `orientation` | `MenuRootOrientation` | `'vertical'` | The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. |

### ContextMenuSubmenuTrigger

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `closeDelay` | `number` | `0` | How long to wait before closing the menu that was opened on hover. Specified in milliseconds. |
| `delay` | `number` | `100` | How long to wait before the menu may be opened on hover. Specified in milliseconds. |
| `disabled` | `boolean` | `false` | Whether the component should ignore user interaction. |
| `id` | `string` |  |  |
| `label` | `string` |  | Overrides the text label to use when the item is matched during keyboard text navigation. |
| `nativeButton` | `boolean` | `false` | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button. |
| `onClick` | `(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void` |  |  |
| `openOnHover` | `boolean` | `true` | Whether the menu should also open when the trigger is hovered. |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

### ContextMenuTrigger

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `render` | `ReactElement \| ((props, state) => ReactElement)` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |

Also takes the attributes of its element.

## Changes

- 0.1.0 (Added): Extended `Lightbox` with thumbnail strip and related chrome parts; added `ComboboxTriggerCount` and `ContextMenuPopup`.
- 0.0.20 (Added): Added `ContextMenuItemLabel`, `ContextMenuFooter`, `DropdownMenuItemLabel`, and `DropdownMenuFooter` for truncatable menu labels and structured footer content.
