Context menu
Opens actions at the pointer or with Shift+F10. Escape and outside click close the menu.
Preview
In action
When to use
Use it for
- Actions on a region or object that already has a primary interaction: a canvas, a row, a file.
- The same items shape as DropdownMenu.
Not for
- Actions with no other way in; add a visible DropdownMenu too.
- Touch-only surfaces without a long-press alternative.
Install
Three ways in. They share one source, so the pixels match whichever you pick.
1. Import the package
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { ContextMenu } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/context-menu.
2. Vendor the source
npx @noorddev/vlak-cli add context-menu
The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.
3. Through shadcn
npx shadcn add https://vlak.dev/r/context-menu.json
The same registry item, installed by shadcn's CLI.
CSS only
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
React
import { ContextMenu } from "@noorddev/vlak-react";
<ContextMenu items={[{ label: "Copy", onSelect: copy }, { label: "Paste", onSelect: paste }, { separator: true }, { label: "Inspect" }]}>
<Canvas />
</ContextMenu>Props
ContextMenu
Menu at the pointer on right-click, or anchored to the trigger on Shift+F10 / the ContextMenu key. The wrapper is tabbable (pass `tabIndex={-1}` when the child is focusable itself); focus returns to whatever had it when the menu closes.
| Prop | Type | Default | Description |
|---|---|---|---|
itemsrequired | DropdownMenuItem[] |
Also accepts HTMLAttributes<HTMLDivElement>.
Keyboard
| Keys | Does |
|---|---|
| Shift + F10, Context menu key | Opens the menu at the wrapper |
| Arrow down, Arrow up, Home, End, Type letters | Move between items |
| Enter, Space | Selects the item and closes |
| Escape | Closes and returns focus |
Accessibility
- The wrapper is a tab stop with aria-keyshortcuts="Shift+F10"; pass tabIndex={-1} when the child is focusable itself.
- The panel is role="menu" with menuitem buttons, roving focus, and type-ahead; focus returns to whatever had it when the menu closes.
- Right-click opens at the pointer; the keyboard opens at the trigger's edge.
Markup
<div class="rs-menu" role="menu"><button class="rs-menu-item" role="menuitem">Copy</button><button class="rs-menu-item" role="menuitem">Paste</button><hr class="rs-menu-sep" /><button class="rs-menu-item" role="menuitem">Inspect</button></div>