The ContextMenu component provides a right-click context menu interface for displaying contextual actions. It's commonly used for file operations, text editing, and interactive elements that need contextual actions.
import { ContextMenu } from '@/components/contextmenu'export default function ContextMenuExample() {const items = [{ type: 'label', title: 'Copy Text', shortcut: '⌘C', description: 'Copy selected text to clipboard' },{ type: 'label', title: 'Paste Text', shortcut: '⌘V', description: 'Paste text from clipboard' },{ type: 'seperator' },{ type: 'label', title: 'Delete Item', shortcut: '⌘⌫', description: 'Remove selected item' }];return (<ContextMenuchildern="Right-click me"items={items}/>)}
Preview:
Right-click meThe ContextMenu component is a direct re-export from @dashflowx/core and accepts the following props:
| Prop | Type | Default | Description |
|---|---|---|---|
childern | string | JSX.Element | 'Right-click me' | The content that triggers the context menu |
items | Array | [] | Array of menu items with different types |
className | string | '' | Additional CSS classes for the container |
The ContextMenu component exports several sub-components from @dashflowx/core:
ContextMenuComp- Main container componentContextMenuTrigger- Trigger elementContextMenuContent- Menu content containerContextMenuItem- Individual menu itemContextMenuSeparator- Visual separatorContextMenuShortcut- Keyboard shortcut displayContextMenuLabel- Menu section labelContextMenuCheckboxItem- Checkbox menu itemContextMenuRadioGroup- Radio button groupContextMenuRadioItem- Radio button itemContextMenuSub- Submenu containerContextMenuSubTrigger- Submenu triggerContextMenuSubContent- Submenu content
interface ContextMenuItem {type: 'label' | 'seperator' | 'subMenu' | 'radio' | 'checkbox';title?: string | JSX.Element;shortcut?: string | JSX.Element;value?: string;checked?: boolean;children?: {title: string | JSX.Element;shortcut?: string | JSX.Element;value?: string;}[];}
const basicItems = [{ type: 'label', title: 'Copy Text', shortcut: '⌘C', description: 'Copy selected text to clipboard' },{ type: 'label', title: 'Paste Text', shortcut: '⌘V', description: 'Paste text from clipboard' },{ type: 'seperator' },{ type: 'label', title: 'Delete Item', shortcut: '⌘⌫', description: 'Remove selected item' }];<ContextMenuchildern="Right-click me"items={basicItems}/>
Preview:
Right-click meconst fileItems = [{ type: 'label', title: 'Open File', shortcut: '⌘O', description: 'Open the selected file' },{ type: 'label', title: 'Edit File', shortcut: '⌘E', description: 'Edit the selected file' },{ type: 'seperator' },{ type: 'label', title: 'Copy File', shortcut: '⌘C', description: 'Copy file to clipboard' },{ type: 'label', title: 'Move File', shortcut: '⌘M', description: 'Move file to new location' },{ type: 'seperator' },{ type: 'label', title: 'Delete File', shortcut: '⌘⌫', description: 'Move file to trash' }];<ContextMenuchildern="📁 File"items={fileItems}/>
Preview:
📁 Fileconst submenuItems = [{ type: 'label', title: 'Copy Text', shortcut: '⌘C', description: 'Copy selected text to clipboard' },{ type: 'label', title: 'Paste Text', shortcut: '⌘V', description: 'Paste text from clipboard' },{ type: 'seperator' },{type: 'subMenu',title: 'Text Formatting',children: [{ title: 'Make Bold', shortcut: '⌘B', description: 'Apply bold formatting' },{ title: 'Make Italic', shortcut: '⌘I', description: 'Apply italic formatting' },{ title: 'Add Underline', shortcut: '⌘U', description: 'Apply underline formatting' }]},{ type: 'seperator' },{ type: 'label', title: 'Delete Text', shortcut: '⌘⌫', description: 'Remove selected text' }];<ContextMenuchildern="📝 Text"items={submenuItems}/>
Preview:
📝 Textconst radioItems = [{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'seperator' },{type: 'radio',title: 'View Mode',value: 'grid',children: [{ title: 'Grid View', value: 'grid' },{ title: 'List View', value: 'list' },{ title: 'Detail View', value: 'detail' }]},{ type: 'seperator' },{ type: 'label', title: 'Delete', shortcut: '⌘⌫' }];<ContextMenuchildern="📊 Data"items={radioItems}/>
Preview:
📊 Dataconst checkboxItems = [{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'seperator' },{ type: 'checkbox', title: 'Show Hidden Files', checked: false },{ type: 'checkbox', title: 'Auto-save', checked: true },{ type: 'seperator' },{ type: 'label', title: 'Delete', shortcut: '⌘⌫' }];<ContextMenuchildern="⚙️ Settings"items={checkboxItems}/>
Preview:
⚙️ Settings<ContextMenuchildern="🎨 Custom Styled"items={basicItems}className="border-2 border-blue-500 rounded-xl"/>
Preview:
🎨 Custom Styledconst fileExplorerItems = [{ type: 'label', title: 'Open', shortcut: '⌘O' },{ type: 'label', title: 'Open With', shortcut: '⌘⇧O' },{ type: 'seperator' },{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Cut', shortcut: '⌘X' },{ type: 'label', title: 'Paste', shortcut: '⌘V' },{ type: 'seperator' },{ type: 'label', title: 'Rename', shortcut: '⌘R' },{ type: 'label', title: 'Move to Trash', shortcut: '⌘⌫' }];<ContextMenuchildern="📁 File Explorer"items={fileExplorerItems}/>
const textEditorItems = [{ type: 'label', title: 'Undo', shortcut: '⌘Z' },{ type: 'label', title: 'Redo', shortcut: '⌘Y' },{ type: 'seperator' },{ type: 'label', title: 'Cut', shortcut: '⌘X' },{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Paste', shortcut: '⌘V' },{ type: 'seperator' },{type: 'subMenu',title: 'Format',children: [{ title: 'Bold', shortcut: '⌘B' },{ title: 'Italic', shortcut: '⌘I' },{ title: 'Underline', shortcut: '⌘U' },{ title: 'Strikethrough', shortcut: '⌘⇧S' }]},{type: 'subMenu',title: 'Insert',children: [{ title: 'Link', shortcut: '⌘K' },{ title: 'Image', shortcut: '⌘⇧I' },{ title: 'Table', shortcut: '⌘⇧T' }]}];
const imageItems = [{ type: 'label', title: 'Open', shortcut: '⌘O' },{ type: 'label', title: 'Edit', shortcut: '⌘E' },{ type: 'seperator' },{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Save As', shortcut: '⌘⇧S' },{ type: 'seperator' },{type: 'subMenu',title: 'Resize',children: [{ title: 'Small (50%)', value: '50' },{ title: 'Medium (100%)', value: '100' },{ title: 'Large (150%)', value: '150' }]},{ type: 'seperator' },{ type: 'label', title: 'Delete', shortcut: '⌘⌫' }];
const tableItems = [{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Paste', shortcut: '⌘V' },{ type: 'seperator' },{type: 'subMenu',title: 'Insert',children: [{ title: 'Row Above', shortcut: '⌘⇧+' },{ title: 'Row Below', shortcut: '⌘+' },{ title: 'Column Left', shortcut: '⌘⇧⌥+' },{ title: 'Column Right', shortcut: '⌘⌥+' }]},{type: 'subMenu',title: 'Delete',children: [{ title: 'Row', shortcut: '⌘⌫' },{ title: 'Column', shortcut: '⌘⇧⌫' },{ title: 'Table', shortcut: '⌘⌥⌫' }]},{ type: 'seperator' },{ type: 'label', title: 'Sort', shortcut: '⌘S' }];
Use clear and descriptive menu item titles.
// ✅ Good - Clear menu itemsconst items = [{ type: 'label', title: 'Copy File', shortcut: '⌘C' },{ type: 'label', title: 'Move to Trash', shortcut: '⌘⌫' }];// ❌ Avoid - Unclear menu itemsconst items = [{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Delete', shortcut: '⌘⌫' }];
Group related menu items together with separators.
// ✅ Good - Logical groupingconst items = [{ type: 'label', title: 'Open', shortcut: '⌘O' },{ type: 'label', title: 'Edit', shortcut: '⌘E' },{ type: 'seperator' },{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Paste', shortcut: '⌘V' },{ type: 'seperator' },{ type: 'label', title: 'Delete', shortcut: '⌘⌫' }];
Use consistent keyboard shortcuts across your application.
// ✅ Good - Consistent shortcutsconst items = [{ type: 'label', title: 'Copy', shortcut: '⌘C' },{ type: 'label', title: 'Paste', shortcut: '⌘V' },{ type: 'label', title: 'Cut', shortcut: '⌘X' }];
Avoid too many nested submenus.
// ✅ Good - Reasonable depthconst items = [{type: 'subMenu',title: 'Format',children: [{ title: 'Bold', shortcut: '⌘B' },{ title: 'Italic', shortcut: '⌘I' }]}];// ❌ Avoid - Too deep nestingconst items = [{type: 'subMenu',title: 'Format',children: [{title: 'Text',children: [{title: 'Style',children: [{ title: 'Bold', shortcut: '⌘B' }]}]}]}];
Show only relevant actions for the current context.
// ✅ Good - Contextual actionsconst getContextMenuItems = (context: string) => {switch (context) {case 'file':return fileItems;case 'text':return textItems;case 'image':return imageItems;default:return basicItems;}};
You can customize the context menu appearance using CSS classes:
<ContextMenuchildern="Custom Styled"items={items}className="border-2 border-purple-500 rounded-xl shadow-lg"/>
Use different themes for different contexts:
// Light theme<ContextMenuchildern="Light Theme"items={items}className="bg-white border-gray-200"/>// Dark theme<ContextMenuchildern="Dark Theme"items={items}className="bg-gray-900 border-gray-700 text-white"/>
Use different sizes for different emphasis levels:
// Small context menu<ContextMenuchildern="Small"items={items}className="w-40"/>// Large context menu<ContextMenuchildern="Large"items={items}className="w-80"/>
Load menu items dynamically based on context:
const [menuItems, setMenuItems] = useState([]);useEffect(() => {// Load menu items based on current contextconst contextItems = getMenuItemsForContext(currentContext);setMenuItems(contextItems);}, [currentContext]);
Handle menu item actions:
const handleMenuAction = (action: string) => {switch (action) {case 'copy':copyToClipboard();break;case 'paste':pasteFromClipboard();break;case 'delete':deleteItem();break;default:console.log('Unknown action:', action);}};
Show/hide menu items based on conditions:
const getConditionalMenuItems = (hasSelection: boolean, isEditable: boolean) => {const items = [];if (hasSelection) {items.push({ type: 'label', title: 'Copy', shortcut: '⌘C' });}if (isEditable) {items.push({ type: 'label', title: 'Paste', shortcut: '⌘V' });}return items;};
- DropdownMenu: For dropdown menus
- Menu: For general menus
- Popover: For popover content
- Tooltip: For tooltips
- Dialog: For modal dialogs
For the complete API reference and advanced usage patterns, see the ContextMenu API documentation.
