Skip to content
Highlight

V2 componentsUpdated Oct 14, 2026

Context Menu

A right-click menu anchored at the pointer. Items share styling with Menu; composition is explicit (Portal, Positioner, Popup) because there is no trigger button.

Source: packages/ui/src/components/context-menu

tsx
import { ContextMenu } from '@highlight/ui'

Change the props; the preview and the snippet update together.

Right-click here
Props
Submenu
Separator
Last item variant
tsx
<ContextMenu>  <ContextMenu.Trigger>Right-click here</ContextMenu.Trigger>  <ContextMenu.Portal>    <ContextMenu.Positioner>      <ContextMenu.Popup className="min-w-40">        <ContextMenu.Item>Rename…</ContextMenu.Item>        <ContextMenu.Item>Duplicate</ContextMenu.Item>        <ContextMenu.SubmenuRoot>          <ContextMenu.SubmenuTrigger>Move to</ContextMenu.SubmenuTrigger>          <ContextMenu.Portal>            <ContextMenu.Positioner>              <ContextMenu.Popup className="min-w-32">                <ContextMenu.Item>Inbox</ContextMenu.Item>                <ContextMenu.Item>Archive</ContextMenu.Item>              </ContextMenu.Popup>            </ContextMenu.Positioner>          </ContextMenu.Portal>        </ContextMenu.SubmenuRoot>        <ContextMenu.Separator />        <ContextMenu.Item variant="danger">Delete</ContextMenu.Item>      </ContextMenu.Popup>    </ContextMenu.Positioner>  </ContextMenu.Portal></ContextMenu>

Includes a nested submenu.

Right-click here
tsx
import { ContextMenu } from '@highlight/ui' export default function ContextMenuBasic() {  return (    <ContextMenu>      <ContextMenu.Trigger className="border-border text-foreground-secondary flex h-32 w-72 select-none items-center justify-center rounded-xl border border-dashed text-sm">        Right-click here      </ContextMenu.Trigger>      <ContextMenu.Portal>        <ContextMenu.Positioner>          <ContextMenu.Popup className="min-w-40">            <ContextMenu.Item>Rename…</ContextMenu.Item>            <ContextMenu.Item>Duplicate</ContextMenu.Item>            <ContextMenu.SubmenuRoot>              <ContextMenu.SubmenuTrigger>Move to</ContextMenu.SubmenuTrigger>              <ContextMenu.Portal>                <ContextMenu.Positioner>                  <ContextMenu.Popup className="min-w-32">                    <ContextMenu.Item>Inbox</ContextMenu.Item>                    <ContextMenu.Item>Archive</ContextMenu.Item>                  </ContextMenu.Popup>                </ContextMenu.Positioner>              </ContextMenu.Portal>            </ContextMenu.SubmenuRoot>            <ContextMenu.Separator />            <ContextMenu.Item variant="danger">Delete</ContextMenu.Item>          </ContextMenu.Popup>        </ContextMenu.Positioner>      </ContextMenu.Portal>    </ContextMenu>  )}

The root, then any compound sub-components. Every part accepts className and forwards the rest of its props to the element or Base UI part beneath it.

ContextMenu
Base UI ContextMenu.Root. Owns open state; opens at the pointer on right-click of its trigger.
ContextMenu.Trigger
The region that listens for contextmenu.
ContextMenu.Portal / Positioner / Popup
Always compose all three.
ContextMenu.Item / CheckboxItem / RadioGroup / RadioItem / Separator / Group / GroupLabel
Same API as Menu.
ContextMenu.SubmenuRoot / SubmenuTrigger
Nested menus.