Overlay

Right-click actions for dense product surfaces

ContextMenu opens from the native contextmenu gesture and renders an action surface at the pointer position. Use it for file rows, data tables, canvases, schedulers, and operational dashboards where secondary actions should stay close to the object being edited.

Examples

ContextMenu gives dashboards and work surfaces a predictable right-click action model with labels, separators, disabled items, and nested actions.



Context menu variants examples

Use Show output / Show code on each row. Snippets start with a Variant line naming the axis and token.


Item variant: DEFAULT


Item variant: OUTLINE


Item variant: GHOST


Item variant: WHITE


Item variant: BLACK


Item variant: SKY


Item variant: ROSE


Item variant: PURPLE


Item variant: PINK


Item variant: ORANGE


Item variant: YELLOW


Item variant: TEAL


Item variant: INDIGO


Item variant: EMERALD


Item variant: GRAY


Item variant: AMBER


Item variant: VIOLET


Item variant: GRADIENT-BLUE


Item variant: GRADIENT-GREEN


Item variant: GRADIENT-RED


Item variant: GRADIENT-YELLOW


Item variant: GRADIENT-PURPLE


Item variant: GRADIENT-TEAL


Item variant: GRADIENT-INDIGO


Item variant: GRADIENT-PINK


Item variant: GRADIENT-ORANGE


Content spacing: NONE


Content spacing: DEFAULT


Content spacing: SM


Content spacing: MD


Content spacing: LG


Content spacing: XL


Pattern: BASIC


Pattern: SUB-MENU


Pattern: DESTRUCTIVE


Pattern: DISABLED

CSS variable overrides

ContextMenu CSS variables

ContextMenu shares Dropdown content and item variables, plus label and separator tokens, so menu theming stays aligned across right-click and click-triggered actions.

185 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-dropdown-content-border: oklch(20.8% 0.042 265.755 / 0.1);
  --zui-dropdown-content-bg: oklch(96.8% 0.007 247.896);
  --zui-dropdown-content-fg: oklch(20.8% 0.042 265.755);
  --zui-dropdown-item-ring-focus: oklch(55.1% 0.027 264.364 / 0.6);
  --zui-dropdown-item-default-bg-hover: oklch(96.7% 0.003 264.542);
  --zui-dropdown-item-default-fg-hover: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-default-fg: oklch(21% 0.034 264.665);
  --zui-dropdown-item-outline-bg-hover: oklch(96.7% 0.003 264.542);
  --zui-dropdown-item-outline-fg-hover: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-outline-border: #000000;
  --zui-dropdown-item-outline-fg: oklch(21% 0.034 264.665);
  --zui-dropdown-item-ghost-bg-hover: oklch(96.7% 0.003 264.542);
  --zui-dropdown-item-ghost-fg-hover: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-ghost-bg: transparent;
  --zui-dropdown-item-ghost-fg: oklch(21% 0.034 264.665);
  --zui-dropdown-item-white-bg-hover: oklch(96.7% 0.003 264.542);
  --zui-dropdown-item-white-fg-hover: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-white-bg: #ffffff;
  --zui-dropdown-item-white-fg: oklch(21% 0.034 264.665);
  --zui-dropdown-item-black-bg-hover: oklch(96.7% 0.003 264.542);
  --zui-dropdown-item-black-fg-hover: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-black-bg: #000000;
  --zui-dropdown-item-black-fg: #ffffff;
  --zui-dropdown-item-sky-bg-hover: oklch(95.1% 0.026 236.824);
  --zui-dropdown-item-sky-fg-hover: oklch(44.3% 0.11 240.79);
  --zui-dropdown-item-sky-bg: oklch(90.1% 0.058 230.902);
  --zui-dropdown-item-sky-fg: oklch(39.1% 0.09 240.876);
  --zui-dropdown-item-rose-bg-hover: oklch(94.1% 0.03 12.58);
  --zui-dropdown-item-rose-fg-hover: oklch(45.5% 0.188 13.697);
  --zui-dropdown-item-rose-bg: oklch(89.2% 0.058 10.001);
  --zui-dropdown-item-rose-fg: oklch(41% 0.159 10.272);
  --zui-dropdown-item-purple-bg-hover: oklch(94.6% 0.033 307.174);
  --zui-dropdown-item-purple-fg-hover: oklch(43.8% 0.218 303.724);
  --zui-dropdown-item-purple-bg: oklch(90.2% 0.063 306.703);
  --zui-dropdown-item-purple-fg: oklch(38.1% 0.176 304.987);
  --zui-dropdown-item-pink-bg-hover: oklch(94.8% 0.028 342.258);
  --zui-dropdown-item-pink-fg-hover: oklch(45.9% 0.187 3.815);
  --zui-dropdown-item-pink-bg: oklch(89.9% 0.061 343.231);
  --zui-dropdown-item-pink-fg: oklch(40.8% 0.153 2.432);
  --zui-dropdown-item-orange-bg-hover: oklch(95.4% 0.038 75.164);
  --zui-dropdown-item-orange-fg-hover: oklch(47% 0.157 37.304);
  --zui-dropdown-item-orange-bg: oklch(90.1% 0.076 70.697);
  --zui-dropdown-item-orange-fg: oklch(40.8% 0.123 38.172);
  --zui-dropdown-item-yellow-bg-hover: oklch(97.3% 0.071 103.193);
  --zui-dropdown-item-yellow-fg-hover: oklch(47.6% 0.114 61.907);
  --zui-dropdown-item-yellow-bg: oklch(94.5% 0.129 101.54);
  --zui-dropdown-item-yellow-fg: oklch(42.1% 0.095 57.708);
  --zui-dropdown-item-teal-bg-hover: oklch(95.3% 0.051 180.801);
  --zui-dropdown-item-teal-fg-hover: oklch(43.7% 0.078 188.216);
  --zui-dropdown-item-teal-bg: oklch(91% 0.096 180.426);
  --zui-dropdown-item-teal-fg: oklch(38.6% 0.063 188.416);
  --zui-dropdown-item-indigo-bg-hover: oklch(93% 0.034 272.788);
  --zui-dropdown-item-indigo-fg-hover: oklch(39.8% 0.195 277.366);
  --zui-dropdown-item-indigo-bg: oklch(87% 0.065 274.039);
  --zui-dropdown-item-indigo-fg: oklch(35.9% 0.144 278.697);
  --zui-dropdown-item-emerald-bg-hover: oklch(95% 0.052 163.051);
  --zui-dropdown-item-emerald-fg-hover: oklch(43.2% 0.095 166.913);
  --zui-dropdown-item-emerald-bg: oklch(90.5% 0.093 164.15);
  --zui-dropdown-item-emerald-fg: oklch(37.8% 0.077 168.94);
  --zui-dropdown-item-gray-bg-hover: oklch(96.7% 0.003 264.542);
  --zui-dropdown-item-gray-fg-hover: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-gray-bg: oklch(92.8% 0.006 264.531);
  --zui-dropdown-item-gray-fg: oklch(55.1% 0.027 264.364);
  --zui-dropdown-item-amber-bg-hover: oklch(96.2% 0.059 95.617);
  --zui-dropdown-item-amber-fg-hover: oklch(47.3% 0.137 46.201);
  --zui-dropdown-item-amber-bg: oklch(92.4% 0.12 95.746);
  --zui-dropdown-item-amber-fg: oklch(41.4% 0.112 45.904);
  --zui-dropdown-item-violet-bg-hover: oklch(94.3% 0.029 294.588);
  --zui-dropdown-item-violet-fg-hover: oklch(43.2% 0.232 292.759);
  --zui-dropdown-item-violet-bg: oklch(89.4% 0.057 293.283);
  --zui-dropdown-item-violet-fg: oklch(38% 0.189 293.745);
  --zui-dropdown-item-gradient-blue-from: oklch(42.4% 0.199 265.638);
  --zui-dropdown-item-gradient-blue-to: oklch(43.8% 0.218 303.724);
  --zui-dropdown-item-gradient-blue-fg-hover: oklch(62.3% 0.214 259.815);
  --zui-dropdown-item-gradient-blue-fg: oklch(37.9% 0.146 265.522);
  --zui-dropdown-item-gradient-green-from: oklch(44.8% 0.119 151.328);
  --zui-dropdown-item-gradient-green-to: oklch(45.3% 0.124 130.933);
  --zui-dropdown-item-gradient-green-fg-hover: oklch(72.3% 0.219 149.579);
  --zui-dropdown-item-gradient-green-fg: oklch(39.3% 0.095 152.535);
  --zui-dropdown-item-gradient-red-from: oklch(44.4% 0.177 26.899);
  --zui-dropdown-item-gradient-red-to: oklch(45.9% 0.187 3.815);
  --zui-dropdown-item-gradient-red-fg-hover: oklch(63.7% 0.237 25.331);
  --zui-dropdown-item-gradient-red-fg: oklch(39.6% 0.141 25.723);
  --zui-dropdown-item-gradient-yellow-from: oklch(47.6% 0.114 61.907);
  --zui-dropdown-item-gradient-yellow-to: oklch(47% 0.157 37.304);
  --zui-dropdown-item-gradient-yellow-fg-hover: oklch(79.5% 0.184 86.047);
  --zui-dropdown-item-gradient-yellow-fg: oklch(42.1% 0.095 57.708);
  --zui-dropdown-item-gradient-purple-from: oklch(43.8% 0.218 303.724);
  --zui-dropdown-item-gradient-purple-to: oklch(45.9% 0.187 3.815);
  --zui-dropdown-item-gradient-purple-fg-hover: oklch(62.7% 0.265 303.9);
  --zui-dropdown-item-gradient-purple-fg: oklch(38.1% 0.176 304.987);
  --zui-dropdown-item-gradient-teal-from: oklch(43.7% 0.078 188.216);
  --zui-dropdown-item-gradient-teal-to: oklch(45% 0.085 224.283);
  --zui-dropdown-item-gradient-teal-fg-hover: oklch(70.4% 0.14 182.503);
  --zui-dropdown-item-gradient-teal-fg: oklch(38.6% 0.063 188.416);
  --zui-dropdown-item-gradient-indigo-from: oklch(39.8% 0.195 277.366);
  --zui-dropdown-item-gradient-indigo-to: oklch(43.8% 0.218 303.724);
  --zui-dropdown-item-gradient-indigo-fg-hover: oklch(58.5% 0.233 277.117);
  --zui-dropdown-item-gradient-indigo-fg: oklch(35.9% 0.144 278.697);
  --zui-dropdown-item-gradient-pink-from: oklch(45.9% 0.187 3.815);
  --zui-dropdown-item-gradient-pink-to: oklch(45.5% 0.188 13.697);
  --zui-dropdown-item-gradient-pink-fg-hover: oklch(65.6% 0.241 354.308);
  --zui-dropdown-item-gradient-pink-fg: oklch(40.8% 0.153 2.432);
  --zui-dropdown-item-gradient-orange-from: oklch(47% 0.157 37.304);
  --zui-dropdown-item-gradient-orange-to: oklch(44.4% 0.177 26.899);
  --zui-dropdown-item-gradient-orange-fg-hover: oklch(70.5% 0.213 47.604);
  --zui-dropdown-item-gradient-orange-fg: oklch(40.8% 0.123 38.172);
  --zui-dropdown-label-fg: oklch(55.1% 0.027 264.364);
  --zui-dropdown-separator-bg: oklch(20.8% 0.042 265.755 / 0.12);
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-dropdown-content-border-dark: #ffffff1a;
  --zui-dropdown-content-bg-dark: oklch(20.8% 0.042 265.755);
  /* ...same variables with -dark at the end */
}

What it does

ContextMenu turns the browser contextmenu event into a themed React menu. It positions content at the pointer, clamps the menu inside the viewport, and closes on outside click, Escape, or item selection.

Composition and API

Compose ContextMenu with ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuSeparator, and the ContextMenuSub parts. Items support the same variants as Dropdown items, and content supports the same spacing tokens.

Common use cases

  • Attach file actions such as open, rename, duplicate, move, and delete to explorer rows.
  • Give data tables compact row-level actions without adding another visible button column.
  • Group advanced workspace or dashboard operations behind nested submenus.
  • Use disabled menu items to explain unavailable actions without changing layout.

Accessibility

ContextMenuContent uses role=menu and items use role=menuitem. Items can be selected by pointer, Enter, or Space, Escape closes the menu and returns focus to the trigger, and disabled actions expose aria-disabled.

Next.js integration notes

ContextMenu is a client component because it listens to pointer and keyboard events. Keep the preview route itself server-rendered and pass SEO content into the interactive sections, matching the rest of the App Router preview pages.

FAQ

Does ContextMenu share Dropdown styling?

Yes. ContextMenu uses the same dropdown item variants and dropdown-scoped CSS variables, so existing menu theming carries across.

Can ContextMenu render nested actions?

Yes. Use ContextMenuSub, ContextMenuSubTrigger, and ContextMenuSubContent to create hover and keyboard-opened nested menus.

How should I label a ContextMenu?

Use ContextMenuLabel for short group labels and ContextMenuSeparator between action groups. The label renders as a paragraph element so it follows the preview code example labeling pattern.