Right-click here
"use client";
import { ContextMenu, Text } from "@vortexlabs/vortex";
import { BoxArchive, Clone, PenLine, Trash } from "@vortexlabs/vortex-icons";
export const ContextMenuExample = () => {
return (
<ContextMenu width="280px">
<ContextMenu.Trigger>
{(attributes) => (
<div
{...attributes}
tabIndex={0}
style={{
...attributes.style,
display: "grid",
placeItems: "center",
width: "100%",
height: 240,
border: "1px dashed var(--vortex-color-border-default)",
borderRadius: "var(--vortex-border-radius-sm)",
}}
>
<Text color="subtle">Right-click here</Text>
</div>
)}
</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Section>
<ContextMenu.Item startIcon={PenLine} shortcut="⌘R" onClick={() => {}}>
Rename
</ContextMenu.Item>
<ContextMenu.Item startIcon={Clone} shortcut="⌘D" onClick={() => {}}>
Duplicate
</ContextMenu.Item>
</ContextMenu.Section>
<ContextMenu.Section>
<ContextMenu.Item startIcon={BoxArchive} onClick={() => {}}>
Archive
</ContextMenu.Item>
<ContextMenu.Item tone="critical" startIcon={Trash} shortcut="⌘⌫" onClick={() => {}}>
Delete
</ContextMenu.Item>
</ContextMenu.Section>
</ContextMenu.Content>
</ContextMenu>
);
};Features
- Opens at the pointer on right-click or touch long press.
- Supports icons, shortcuts, sections, destructive items, and submenus.
- Names the menu after its trigger by default.
Anatomy
<ContextMenu>
<ContextMenu.Trigger>
{(attributes) => <div {...attributes} tabIndex={0}>File</div>}
</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Item>Rename</ContextMenu.Item>
<ContextMenu.Item>Delete</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu>Component Part
Description
Holds the open state and positions the menu at the pointer.
Gives your element the attributes that open the menu on right-click, long press, or Shift+F10.
Holds the menu items and names the menu after the trigger.
Runs one action and closes the menu.
Groups related items.
Names a section.
Holds a nested menu that opens from its
SubTrigger.Opens the submenu on hover or with the arrow key.
Cards
Pass the attributes to a Card to open the menu from it. On a native element, spread them and merge their style with yours to keep the iOS long-press callout off.
Quarterly report.pdf
Edited 2 hours ago
// FileActions renders the ContextMenu.Content from the first example
<ContextMenu width="280px">
<ContextMenu.Trigger>
{(attributes) => (
<Card attributes={{ ...attributes, tabIndex: 0 }}>
<Text weight="medium">Quarterly report.pdf</Text>
<Text size="body-sm-desktop" color="subtle">
Edited 2 hours ago
</Text>
</Card>
)}
</ContextMenu.Trigger>
<FileActions />
</ContextMenu>Repeated Items
Give each row its own ContextMenu, so actions apply to the clicked item.
Brand guidelines.fig |
Roadmap.pdf |
Invoices.xlsx |
// FileActions renders the ContextMenu.Content from the first example
const files = ["Brand guidelines.fig", "Roadmap.pdf", "Invoices.xlsx"];
<table style={{ width: "100%", borderCollapse: "collapse" }}>
<tbody>
{files.map((file) => (
<ContextMenu key={file} width="280px">
<ContextMenu.Trigger>
{(attributes) => (
<tr {...attributes} tabIndex={0}>
<td style={{ padding: "var(--vortex-spacing-xs) var(--vortex-spacing-sm)" }}>
<Text>{file}</Text>
</td>
</tr>
)}
</ContextMenu.Trigger>
<FileActions />
</ContextMenu>
))}
</tbody>
</table>Submenus
Wrap a SubTrigger and a nested Content in SubMenu. It opens on hover or with the arrow key.
Right-click here
import { Link, Mail, PenLine, Share, Trash } from "@vortexlabs/vortex-icons";
<ContextMenu width="280px">
<ContextMenu.Trigger>
{(attributes) => <div {...attributes} tabIndex={0}>Right-click here</div>}
</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Item startIcon={PenLine} shortcut="⌘R" onClick={() => {}}>
Rename
</ContextMenu.Item>
<ContextMenu.SubMenu width="240px">
<ContextMenu.SubTrigger startIcon={Share}>Share</ContextMenu.SubTrigger>
<ContextMenu.Content>
<ContextMenu.Item startIcon={Link} onClick={() => {}}>
Copy link
</ContextMenu.Item>
<ContextMenu.Item startIcon={Mail} onClick={() => {}}>
Email
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu.SubMenu>
<ContextMenu.Item tone="critical" startIcon={Trash} shortcut="⌘⌫" onClick={() => {}}>
Delete
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu>Right-click menus are hard to find, so also offer the actions in a visible DropdownMenu.
Accessibility
Key
Description
EnterSpace
Selects the focused item and closes the menu.
ShiftF10Menu key
Opens the menu below the focused area.
Down arrowUp arrow
Moves to the next or previous item, wrapping at the ends.
Right arrow
Opens a submenu (ArrowLeft in right-to-left layouts).
Left arrow
Closes a submenu (ArrowRight in right-to-left layouts).
Escape
Closes the menu.
Make the area focusable with
tabIndex={0} and give it an accessible name.