

<Preview name="BasicContextMenuExample" />

## Overview [#overview]

The **Context Menu** component displays a menu triggered by right-clicking on an element, providing contextual actions and options. It supports keyboard shortcuts, checkboxes, radio groups, submenus, and separators. Built on Base UI primitives, it offers full keyboard navigation and accessibility features.

## Usage [#usage]

```tsx
import {
  ContextMenu,
  ContextMenuTrigger,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuCheckboxItem,
  ContextMenuRadioItem,
  ContextMenuRadioGroup,
  ContextMenuGroupLabel,
  ContextMenuSeparator,
  ContextMenuShortcut,
  ContextMenuSub,
  ContextMenuSubContent,
  ContextMenuSubTrigger,
} from "@tilt-legal/cubitt-components/primitives";
```

```tsx
<ContextMenu>
  <ContextMenuTrigger>Right click here</ContextMenuTrigger>
  <ContextMenuContent>
    <ContextMenuItem>Item 1</ContextMenuItem>
    <ContextMenuItem>Item 2</ContextMenuItem>
    <ContextMenuSeparator />
    <ContextMenuItem>Item 3</ContextMenuItem>
  </ContextMenuContent>
</ContextMenu>
```

## Examples [#examples]

### With Shortcuts [#with-shortcuts]

Display keyboard shortcuts alongside menu items for quick reference.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="ContextMenuWithShortcutsExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      ContextMenu,
      ContextMenuTrigger,
      ContextMenuContent,
      ContextMenuItem,
      ContextMenuSeparator,
      ContextMenuShortcut,
    } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <ContextMenu>
          <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
            Right click here
          </ContextMenuTrigger>
          <ContextMenuContent className="w-64">
            <ContextMenuItem>
              Back
              <ContextMenuShortcut>⌘[</ContextMenuShortcut>
            </ContextMenuItem>
            <ContextMenuItem>
              Forward
              <ContextMenuShortcut>⌘]</ContextMenuShortcut>
            </ContextMenuItem>
            <ContextMenuItem>
              Reload
              <ContextMenuShortcut>⌘R</ContextMenuShortcut>
            </ContextMenuItem>
            <ContextMenuSeparator />
            <ContextMenuItem>
              View Source
              <ContextMenuShortcut>⌘U</ContextMenuShortcut>
            </ContextMenuItem>
            <ContextMenuItem>
              Inspect
              <ContextMenuShortcut>⌘⇧I</ContextMenuShortcut>
            </ContextMenuItem>
          </ContextMenuContent>
        </ContextMenu>
      );
    }
    ```
  </Tab>
</Tabs>

### With Checkboxes [#with-checkboxes]

Use checkboxes for toggleable options in the context menu.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="ContextMenuWithCheckboxExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      ContextMenu,
      ContextMenuTrigger,
      ContextMenuContent,
      ContextMenuItem,
      ContextMenuCheckboxItem,
      ContextMenuSeparator,
    } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      const [showBookmarks, setShowBookmarks] = React.useState(true);
      const [showReadingList, setShowReadingList] = React.useState(false);

      return (
        <ContextMenu>
          <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
            Right click here
          </ContextMenuTrigger>
          <ContextMenuContent className="w-64">
            <ContextMenuItem>Reload</ContextMenuItem>
            <ContextMenuItem>Force Reload</ContextMenuItem>
            <ContextMenuSeparator />
            <ContextMenuCheckboxItem
              checked={showBookmarks}
              onCheckedChange={setShowBookmarks}
            >
              Show Bookmarks Bar
            </ContextMenuCheckboxItem>
            <ContextMenuCheckboxItem
              checked={showReadingList}
              onCheckedChange={setShowReadingList}
            >
              Show Reading List
            </ContextMenuCheckboxItem>
          </ContextMenuContent>
        </ContextMenu>
      );
    }
    ```
  </Tab>
</Tabs>

### With Radio Group [#with-radio-group]

Use radio groups for mutually exclusive options.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="ContextMenuWithRadioExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      ContextMenu,
      ContextMenuTrigger,
      ContextMenuContent,
      ContextMenuItem,
      ContextMenuGroup,
      ContextMenuGroupLabel,
      ContextMenuRadioGroup,
      ContextMenuRadioItem,
      ContextMenuSeparator,
    } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      const [position, setPosition] = React.useState("top");

      return (
        <ContextMenu>
          <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
            Right click here
          </ContextMenuTrigger>
          <ContextMenuContent className="w-64">
            <ContextMenuItem>Preferences</ContextMenuItem>
            <ContextMenuSeparator />
            <ContextMenuGroup>
              <ContextMenuGroupLabel>Panel Position</ContextMenuGroupLabel>
              <ContextMenuRadioGroup value={position} onValueChange={setPosition}>
                <ContextMenuRadioItem value="top">Top</ContextMenuRadioItem>
                <ContextMenuRadioItem value="bottom">Bottom</ContextMenuRadioItem>
                <ContextMenuRadioItem value="right">Right</ContextMenuRadioItem>
              </ContextMenuRadioGroup>
            </ContextMenuGroup>
          </ContextMenuContent>
        </ContextMenu>
      );
    }
    ```
  </Tab>
</Tabs>

### With Submenu [#with-submenu]

Create nested menus for organizing related actions.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="ContextMenuWithSubmenuExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      ContextMenu,
      ContextMenuTrigger,
      ContextMenuContent,
      ContextMenuItem,
      ContextMenuSeparator,
      ContextMenuSub,
      ContextMenuSubContent,
      ContextMenuSubTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <ContextMenu>
          <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
            Right click here
          </ContextMenuTrigger>
          <ContextMenuContent className="w-64">
            <ContextMenuItem>New File</ContextMenuItem>
            <ContextMenuItem>New Folder</ContextMenuItem>
            <ContextMenuSeparator />
            <ContextMenuSub>
              <ContextMenuSubTrigger>Share</ContextMenuSubTrigger>
              <ContextMenuSubContent>
                <ContextMenuItem>Email</ContextMenuItem>
                <ContextMenuItem>Messages</ContextMenuItem>
                <ContextMenuItem>Copy Link</ContextMenuItem>
              </ContextMenuSubContent>
            </ContextMenuSub>
            <ContextMenuSeparator />
            <ContextMenuItem>Rename</ContextMenuItem>
            <ContextMenuItem variant="destructive">Delete</ContextMenuItem>
          </ContextMenuContent>
        </ContextMenu>
      );
    }
    ```
  </Tab>
</Tabs>

### With Inset [#with-inset]

Use the `inset` prop to add left padding for consistent alignment with checkboxes and radio items.

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="ContextMenuInsetExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    import {
      ContextMenu,
      ContextMenuTrigger,
      ContextMenuContent,
      ContextMenuItem,
      ContextMenuGroup,
      ContextMenuGroupLabel,
      ContextMenuSeparator,
      ContextMenuSub,
      ContextMenuSubContent,
      ContextMenuSubTrigger,
    } from "@tilt-legal/cubitt-components/primitives";

    export default function Component() {
      return (
        <ContextMenu>
          <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
            Right click here
          </ContextMenuTrigger>
          <ContextMenuContent className="w-64">
            <ContextMenuItem inset>View</ContextMenuItem>
            <ContextMenuItem inset>Edit</ContextMenuItem>
            <ContextMenuSeparator />
            <ContextMenuSub>
              <ContextMenuSubTrigger inset>More Tools</ContextMenuSubTrigger>
              <ContextMenuSubContent>
                <ContextMenuItem>Developer Tools</ContextMenuItem>
                <ContextMenuItem>Task Manager</ContextMenuItem>
                <ContextMenuItem>Extensions</ContextMenuItem>
              </ContextMenuSubContent>
            </ContextMenuSub>
            <ContextMenuSeparator />
            <ContextMenuGroup>
              <ContextMenuGroupLabel inset>Advanced</ContextMenuGroupLabel>
              <ContextMenuItem inset>Settings</ContextMenuItem>
            </ContextMenuGroup>
          </ContextMenuContent>
        </ContextMenu>
      );
    }
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### ContextMenu [#contextmenu]

The root component that manages context menu state.

| Prop           | Type                      | Default | Description                      |
| -------------- | ------------------------- | ------- | -------------------------------- |
| `open`         | `boolean`                 | -       | Controlled open state            |
| `defaultOpen`  | `boolean`                 | `false` | Initial open state               |
| `onOpenChange` | `(open: boolean) => void` | -       | Callback when open state changes |

### ContextMenuTrigger [#contextmenutrigger]

The element that triggers the context menu on right-click.

| Prop     | Type                 | Default | Description                         |
| -------- | -------------------- | ------- | ----------------------------------- |
| `render` | `React.ReactElement` | -       | Custom element to render as trigger |

### ContextMenuContent [#contextmenucontent]

The container for menu items.

| Prop          | Type                                     | Default    | Description                   |
| ------------- | ---------------------------------------- | ---------- | ----------------------------- |
| `align`       | `"start" \| "center" \| "end"`           | `"start"`  | Alignment relative to trigger |
| `side`        | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Side to render on             |
| `sideOffset`  | `number`                                 | `4`        | Distance from trigger         |
| `alignOffset` | `number`                                 | `0`        | Offset from alignment axis    |

### ContextMenuItem [#contextmenuitem]

A menu item that can be clicked.

| Prop       | Type                         | Default     | Description      |
| ---------- | ---------------------------- | ----------- | ---------------- |
| `disabled` | `boolean`                    | `false`     | Disable the item |
| `inset`    | `boolean`                    | `false`     | Add left padding |
| `variant`  | `"default" \| "destructive"` | `"default"` | Visual variant   |

### ContextMenuCheckboxItem [#contextmenucheckboxitem]

A menu item with a checkbox.

| Prop              | Type                         | Default | Description                   |
| ----------------- | ---------------------------- | ------- | ----------------------------- |
| `checked`         | `boolean`                    | -       | Controlled checked state      |
| `defaultChecked`  | `boolean`                    | `false` | Initial checked state         |
| `onCheckedChange` | `(checked: boolean) => void` | -       | Callback when checked changes |

### ContextMenuRadioGroup [#contextmenuradiogroup]

A container for radio items.

| Prop            | Type                      | Default | Description                 |
| --------------- | ------------------------- | ------- | --------------------------- |
| `value`         | `string`                  | -       | Controlled value            |
| `defaultValue`  | `string`                  | -       | Initial value               |
| `onValueChange` | `(value: string) => void` | -       | Callback when value changes |

### ContextMenuRadioItem [#contextmenuradioitem]

A menu item with a radio button.

| Prop       | Type      | Default | Description           |
| ---------- | --------- | ------- | --------------------- |
| `value`    | `string`  | -       | The value of the item |
| `disabled` | `boolean` | `false` | Disable the item      |

### ContextMenuSub [#contextmenusub]

Container for submenu.

### ContextMenuSubTrigger [#contextmenusubtrigger]

Trigger for opening a submenu.

| Prop       | Type      | Default | Description         |
| ---------- | --------- | ------- | ------------------- |
| `disabled` | `boolean` | `false` | Disable the trigger |
| `inset`    | `boolean` | `false` | Add left padding    |

### ContextMenuSubContent [#contextmenusubcontent]

Content for a submenu.

| Prop          | Type                                     | Default | Description                   |
| ------------- | ---------------------------------------- | ------- | ----------------------------- |
| `align`       | `"start" \| "center" \| "end"`           | -       | Alignment relative to trigger |
| `side`        | `"top" \| "right" \| "bottom" \| "left"` | -       | Side to render on             |
| `sideOffset`  | `number`                                 | `4`     | Distance from trigger         |
| `alignOffset` | `number`                                 | `0`     | Offset from alignment axis    |

### ContextMenuGroup [#contextmenugroup]

Container for grouping related menu items with a label.

### ContextMenuGroupLabel [#contextmenugrouplabel]

Label for a group of items.

| Prop    | Type      | Default | Description      |
| ------- | --------- | ------- | ---------------- |
| `inset` | `boolean` | `false` | Add left padding |

### ContextMenuSeparator [#contextmenuseparator]

Visual separator between items.

### ContextMenuShortcut [#contextmenushortcut]

Display keyboard shortcuts.
