A powerful context menu plugin that supports both Vue 3 and React.
- 🎯 Framework agnostic - supports both Vue 3 and React
- 🎨 Themes support - includes light/dark themes and custom themes
- 📱 Responsive - works on both desktop and mobile devices
- ⌨️ Full keyboard navigation
- 🔍 Context-aware menu items
- 🎭 Transition animations
- ♿ Accessibility support
- 🛡️ TypeScript support
# NPM
npm install context-menu-plugin
# Yarn
yarn add context-menu-plugin
# PNPM
pnpm add context-menu-plugin
For Vue 3:
npm install vue@^3.2.0
For React:
npm install react@^16.8.0 react-dom@^16.8.0
- Register the plugin in your main.js:
import { createApp } from 'vue'
import ContextMenu from 'context-menu-plugin'
import App from './App.vue'
const app = createApp(App)
app.use(ContextMenu, { framework: 'vue3' })
app.mount('#app')
- Use in components:
<template>
<div v-contextmenu="menuItems">Right click here</div>
</template>
<script setup>
const menuItems = [
{ label: 'Copy', handler: () => console.log('Copy') },
{ label: 'Paste', handler: () => console.log('Paste') },
{ type: 'separator' },
{
label: 'More Actions',
children: [
{ label: 'Action 1', handler: () => console.log('Action 1') },
{ label: 'Action 2', handler: () => console.log('Action 2') }
]
}
]
</script>
- Import and use in your component:
import { useContextMenu, ContextMenu } from 'context-menu-plugin/react'
function App() {
const { showContextMenu, ...menuProps } = useContextMenu()
const menuItems = [
{ label: 'Copy', onClick: () => console.log('Copy') },
{ label: 'Paste', onClick: () => console.log('Paste') },
{ type: 'separator' },
{
label: 'More Actions',
children: [
{ label: 'Action 1', onClick: () => console.log('Action 1') },
{ label: 'Action 2', onClick: () => console.log('Action 2') }
]
}
]
return (
<div onContextMenu={(e) => showContextMenu(e, menuItems)}>
Right click here
<ContextMenu {...menuProps} />
</div>
)
}
The plugin can automatically adjust menu items based on the right-clicked element.
Vue 3:
<template>
<img v-contextmenu="{ contextAware: true }" src="image.jpg" />
<a v-contextmenu="{ contextAware: true }" href="https://example.com">Link</a>
</template>
React:
import { createContextAwareHandler } from 'context-menu-plugin/react'
function App() {
const { showContextMenu, ...menuProps } = useContextMenu()
const handleContextAware = createContextAwareHandler(showContextMenu)
return (
<>
<img onContextMenu={handleContextAware} src="image.jpg" />
<a onContextMenu={handleContextAware} href="https://example.com">Link</a>
<ContextMenu {...menuProps} />
</>
)
}
You can use built-in themes or create custom themes.
Vue 3:
<template>
<div v-contextmenu="{ items: menuItems, theme: 'dark' }">
Dark theme menu
</div>
</template>
React:
showContextMenu(e, menuItems, { theme: 'dark' })
Control menu positioning with various options:
const positionConfig = {
boundary: true, // Enable boundary detection
offset: 10, // Offset from edges
placement: 'bottom', // Preferred placement
fixed: false // Use fixed positioning
}
Vue 3:
<template>
<div v-contextmenu="{ items: menuItems, position: positionConfig }">
Custom position
</div>
</template>
React:
showContextMenu(e, menuItems, positionConfig)
interface MenuItem {
label: string | VNode // Menu item label
handler?: () => void // Click handler (Vue)
onClick?: () => void // Click handler (React)
disabled?: boolean // Disable the item
type?: 'normal' | 'separator' // Item type
children?: MenuItem[] // Submenu items
icon?: string | ReactNode // Item icon
shortcut?: string // Keyboard shortcut display
}
- light (default)
- dark
- blue
- green
Using CSS Variables:
:root {
--cm-bg-color: white;
--cm-text-color: black;
--cm-border-color: #ddd;
--cm-hover-bg: #f5f5f5;
--cm-disabled-opacity: 0.5;
}
.context-menu
- Main container.cm-item
- Menu item.cm-separator
- Separator line.cm-disabled
- Disabled item.cm-submenu
- Submenu container.cm-theme-{name}
- Theme specific class
v-contextmenu="config"
interface Config {
items?: MenuItem[]
theme?: string
position?: PositionConfig
contextAware?: boolean
}
const {
visible: boolean,
position: { x: number, y: number },
items: MenuItem[],
showContextMenu: (e: Event, items?: MenuItem[], config?: Config) => void,
hideContextMenu: () => void,
menuRef: React.RefObject
} = useContextMenu(options?: {
theme?: string
})
- Chrome >= 60
- Firefox >= 55
- Safari >= 12.1
- Edge >= 79
The plugin follows WAI-ARIA guidelines:
- Proper ARIA roles
- Keyboard navigation
- Focus management
- Screen reader support
The plugin includes TypeScript definitions for all features.