# Context Menu

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import {
  ContextMenu,
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuShortcut,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";
---

<ContextMenu>
  <ContextMenuTrigger class="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
    <span class="hidden pointer-fine:inline-block">Right click here</span>
    <span class="hidden pointer-coarse:inline-block">Long press here</span>
  </ContextMenuTrigger>
  <ContextMenuContent class="w-48">
    <ContextMenuGroup>
      <ContextMenuItem>
        Back
        <ContextMenuShortcut>⌘[</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuItem disabled>
        Forward
        <ContextMenuShortcut>⌘]</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuItem>
        Reload
        <ContextMenuShortcut>⌘R</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuSub>
        <ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
        <ContextMenuSubContent class="w-44">
          <ContextMenuGroup>
            <ContextMenuItem>Save Page...</ContextMenuItem>
            <ContextMenuItem>Create Shortcut...</ContextMenuItem>
            <ContextMenuItem>Name Window...</ContextMenuItem>
          </ContextMenuGroup>
          <ContextMenuSeparator />
          <ContextMenuGroup>
            <ContextMenuItem>Developer Tools</ContextMenuItem>
          </ContextMenuGroup>
          <ContextMenuSeparator />
          <ContextMenuGroup>
            <ContextMenuItem class="text-destructive data-highlighted:text-destructive focus:text-destructive">Delete</ContextMenuItem>
          </ContextMenuGroup>
        </ContextMenuSubContent>
      </ContextMenuSub>
    </ContextMenuGroup>
    <ContextMenuSeparator />
    <ContextMenuGroup>
      <ContextMenuCheckboxItem defaultChecked>Show Bookmarks</ContextMenuCheckboxItem>
      <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
    </ContextMenuGroup>
  </ContextMenuContent>
</ContextMenu>
```
  </div>
  <div slot="react">
```tsx
import {
  ContextMenu,
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuShortcut,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";

export function Example() {
  return (
    <ContextMenu>
      <ContextMenuTrigger className="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
        <span className="hidden pointer-fine:inline-block">Right click here</span>
        <span className="hidden pointer-coarse:inline-block">Long press here</span>
      </ContextMenuTrigger>
      <ContextMenuContent className="w-48">
        <ContextMenuGroup>
          <ContextMenuItem>
            Back
            <ContextMenuShortcut>⌘[</ContextMenuShortcut>
          </ContextMenuItem>
          <ContextMenuItem disabled>
            Forward
            <ContextMenuShortcut>⌘]</ContextMenuShortcut>
          </ContextMenuItem>
          <ContextMenuItem>
            Reload
            <ContextMenuShortcut>⌘R</ContextMenuShortcut>
          </ContextMenuItem>
          <ContextMenuSub>
            <ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
            <ContextMenuSubContent className="w-44">
              <ContextMenuGroup>
                <ContextMenuItem>Save Page...</ContextMenuItem>
                <ContextMenuItem>Create Shortcut...</ContextMenuItem>
                <ContextMenuItem>Name Window...</ContextMenuItem>
              </ContextMenuGroup>
              <ContextMenuSeparator />
              <ContextMenuGroup>
                <ContextMenuItem>Developer Tools</ContextMenuItem>
              </ContextMenuGroup>
              <ContextMenuSeparator />
              <ContextMenuGroup>
                <ContextMenuItem className="text-destructive data-highlighted:text-destructive focus:text-destructive">Delete</ContextMenuItem>
              </ContextMenuGroup>
            </ContextMenuSubContent>
          </ContextMenuSub>
        </ContextMenuGroup>
        <ContextMenuSeparator />
        <ContextMenuGroup>
          <ContextMenuCheckboxItem defaultChecked>Show Bookmarks</ContextMenuCheckboxItem>
          <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
        </ContextMenuGroup>
      </ContextMenuContent>
    </ContextMenu>
  );
}
```
  </div>
</FrameworkCodeSwitcher>

> **Info:** Destructive actions are styled from Runtime item states instead of a legacy variant. The checkbox uses `defaultChecked` so Runtime can own its later toggles rather than receiving an immutable `checked` value.

## Installation

```bash
npx starwind@latest add context-menu
```

## Usage

### Basic

A simple context menu with a few actions.

```astro
---
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";
---

<ContextMenu>
  <ContextMenuTrigger class="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
    <span class="hidden pointer-fine:inline-block">Right click here</span>
    <span class="hidden pointer-coarse:inline-block">Long press here</span>
  </ContextMenuTrigger>
  <ContextMenuContent>
    <ContextMenuGroup>
      <ContextMenuItem>Back</ContextMenuItem>
      <ContextMenuItem disabled>Forward</ContextMenuItem>
      <ContextMenuItem>Reload</ContextMenuItem>
    </ContextMenuGroup>
  </ContextMenuContent>
</ContextMenu>
```

### Submenu

Use `ContextMenuSub`, `ContextMenuSubTrigger`, and `ContextMenuSubContent` to nest secondary actions.

```astro
---
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuShortcut,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";
---

<ContextMenu>
  <ContextMenuTrigger class="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
    <span class="hidden pointer-fine:inline-block">Right click here</span>
    <span class="hidden pointer-coarse:inline-block">Long press here</span>
  </ContextMenuTrigger>
  <ContextMenuContent class="w-48">
    <ContextMenuGroup>
      <ContextMenuItem>
        Copy
        <ContextMenuShortcut>⌘C</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuItem>
        Cut
        <ContextMenuShortcut>⌘X</ContextMenuShortcut>
      </ContextMenuItem>
    </ContextMenuGroup>
    <ContextMenuSub>
      <ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
      <ContextMenuSubContent class="w-44">
        <ContextMenuGroup>
          <ContextMenuItem>Save Page...</ContextMenuItem>
          <ContextMenuItem>Create Shortcut...</ContextMenuItem>
          <ContextMenuItem>Name Window...</ContextMenuItem>
        </ContextMenuGroup>
        <ContextMenuSeparator />
        <ContextMenuGroup>
          <ContextMenuItem>Developer Tools</ContextMenuItem>
        </ContextMenuGroup>
        <ContextMenuSeparator />
        <ContextMenuGroup>
          <ContextMenuItem class="text-destructive data-highlighted:text-destructive focus:text-destructive">Delete</ContextMenuItem>
        </ContextMenuGroup>
      </ContextMenuSubContent>
    </ContextMenuSub>
  </ContextMenuContent>
</ContextMenu>
```

> **Info:** Nested context menus now use the dedicated Runtime submenu anatomy; destructive actions are styled from the item state instead of a removed item variant.

### Shortcuts

Add `ContextMenuShortcut` to show keyboard hints.

```astro
---
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuShortcut,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";
---

<ContextMenu>
  <ContextMenuTrigger class="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
    <span class="hidden pointer-fine:inline-block">Right click here</span>
    <span class="hidden pointer-coarse:inline-block">Long press here</span>
  </ContextMenuTrigger>
  <ContextMenuContent>
    <ContextMenuGroup>
      <ContextMenuItem>
        Back
        <ContextMenuShortcut>⌘[</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuItem disabled>
        Forward
        <ContextMenuShortcut>⌘]</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuItem>
        Reload
        <ContextMenuShortcut>⌘R</ContextMenuShortcut>
      </ContextMenuItem>
    </ContextMenuGroup>
    <ContextMenuSeparator />
    <ContextMenuGroup>
      <ContextMenuItem>
        Save
        <ContextMenuShortcut>⌘S</ContextMenuShortcut>
      </ContextMenuItem>
      <ContextMenuItem>
        Save As...
        <ContextMenuShortcut>⇧⌘S</ContextMenuShortcut>
      </ContextMenuItem>
    </ContextMenuGroup>
  </ContextMenuContent>
</ContextMenu>
```

### With Icons

Combine icons with labels for quick scanning.

```astro
---
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";
import Copy from "@tabler/icons/outline/copy.svg";
import Edit from "@tabler/icons/outline/edit.svg";
import Trash from "@tabler/icons/outline/trash.svg";
---

<ContextMenu>
  <ContextMenuTrigger class="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
    <span class="hidden pointer-fine:inline-block">Right click here</span>
    <span class="hidden pointer-coarse:inline-block">Long press here</span>
  </ContextMenuTrigger>
  <ContextMenuContent>
    <ContextMenuGroup>
      <ContextMenuItem>
        <Copy />
        Copy
      </ContextMenuItem>
      <ContextMenuItem>
        <Edit />
        Rename
      </ContextMenuItem>
    </ContextMenuGroup>
    <ContextMenuSeparator />
    <ContextMenuGroup>
      <ContextMenuItem class="text-destructive data-highlighted:text-destructive focus:text-destructive">
        <Trash />
        Delete
      </ContextMenuItem>
    </ContextMenuGroup>
  </ContextMenuContent>
</ContextMenu>
```

> **Info:** Runtime context-menu items no longer provide a destructive variant, so the example styles that action directly while preserving highlighted and focus states.

### Checkboxes

Use `ContextMenuCheckboxItem` for toggle actions.

```astro
---
import {
  ContextMenu,
  ContextMenuCheckboxItem,
  ContextMenuContent,
  ContextMenuGroup,
  ContextMenuTrigger,
} from "@/components/starwind/context-menu";
---

<ContextMenu>
  <ContextMenuTrigger class="flex aspect-video w-full min-w-40 max-w-xs items-center justify-center rounded-xl border border-dashed text-sm">
    <span class="hidden pointer-fine:inline-block">Right click here</span>
    <span class="hidden pointer-coarse:inline-block">Long press here</span>
  </ContextMenuTrigger>
  <ContextMenuContent>
    <ContextMenuGroup>
      <ContextMenuCheckboxItem defaultChecked>Show Bookmarks Bar</ContextMenuCheckboxItem>
      <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
      <ContextMenuCheckboxItem defaultChecked>Show Developer Tools</ContextMenuCheckboxItem>
    </ContextMenuGroup>
  </ContextMenuContent>
</ContextMenu>
```

> **Info:** Interactive checkbox items use `defaultChecked` for their initial uncontrolled state, allowing the Runtime menu controller to toggle them after hydration.

## Composition

Use the following composition to build a `ContextMenu`:

```text
ContextMenu
├── ContextMenuTrigger
└── ContextMenuContent
    ├── ContextMenuGroup
    │   ├── ContextMenuLabel
    │   ├── ContextMenuItem
    │   └── ContextMenuCheckboxItem
    ├── ContextMenuSeparator
    └── ContextMenuSub
        ├── ContextMenuSubTrigger
        └── ContextMenuSubContent
            └── ContextMenuGroup
                ├── ContextMenuItem
                └── ContextMenuItem
```

## Framework Availability
Context Menu is available for Astro and React.
Astro available; React available
| Framework | Status | Notes |
| --- | --- | --- |
| Astro | available | - |
| React | available | - |
## API Reference
### ContextMenu
- Inherits div attributes.

### ContextMenuTrigger
- Inherits div attributes.

### ContextMenuContent
- Inherits div attributes.

### ContextMenuItem
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `inset` | `boolean` | No | `false` | Wrapper prop | Adds leading inset spacing for visual alignment. |
- Inherits div attributes.

### ContextMenuCheckboxItem
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `closeOnClick` | `boolean` | No | `false` | Wrapper prop | Closes the containing surface after the item is activated. |
| `indicatorClass` | `string` | No | - | Wrapper prop | Adds classes to the generated selection indicator. |
| `inset` | `boolean` | No | `false` | Wrapper prop | Adds leading inset spacing for visual alignment. |
| `showIndicator` | `boolean` | No | `true` | Wrapper prop | Shows the generated selection indicator. |
- Inherits div attributes. Omits `aria-checked` and `role`.

### ContextMenuCheckboxItemIndicator
- Inherits span attributes.

### ContextMenuRadioGroup
- Inherits div attributes.

### ContextMenuRadioItem
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `closeOnClick` | `boolean` | No | `false` | Wrapper prop | Closes the containing surface after the item is activated. |
| `indicatorClass` | `string` | No | - | Wrapper prop | Adds classes to the generated selection indicator. |
| `inset` | `boolean` | No | `false` | Wrapper prop | Adds leading inset spacing for visual alignment. |
| `showIndicator` | `boolean` | No | `true` | Wrapper prop | Shows the generated selection indicator. |
| `value` | `string` | Yes | - | Wrapper prop | Controls or identifies the component value. |
- Inherits div attributes. Omits `aria-checked` and `role`.

### ContextMenuRadioItemIndicator
- Inherits span attributes.

### ContextMenuGroup
- Inherits div attributes.

### ContextMenuLabel
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `inset` | `boolean` | No | `false` | Wrapper prop | Adds leading inset spacing for visual alignment. |
- Inherits div attributes.

### ContextMenuSeparator
- Inherits div attributes.

### ContextMenuShortcut
- Inherits span attributes.

### ContextMenuSub
- Inherits div attributes.

### ContextMenuSubTrigger
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `inset` | `boolean` | No | `false` | Wrapper prop | Adds leading inset spacing for visual alignment. |
- Inherits div attributes.

### ContextMenuSubContent
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `side` | `"top" \| "right" \| "bottom" \| "left"` | No | `"right"` | Primitive override | Selects the preferred side for floating content. |
| `sideOffset` | `number` | No | `0` | Primitive override | Sets the distance in pixels between floating content and its anchor. |
- Inherits div attributes.
### Primitive And Runtime API
Behavior, state, events, form participation, and imperative methods are documented in the lower-level references.
- Primitive: [Context Menu Primitive](/docs/primitives/context-menu/)
- Runtime factory: [`createContextMenu`](/docs/runtime/#create-context-menu) from `@starwind-ui/runtime/context-menu`

## Changelog

### v2.0.0

- Rebuilt Context Menu on Starwind Runtime for opening, keyboard navigation, submenus, and checked items.
- See the [Context Menu Primitive](/docs/primitives/context-menu/) for the underlying unstyled anatomy and behavior API.