Component
Context Menu
Right-click context menu with grouped actions, keyboard shortcuts, and screen-edge detection for file management applications.
- Component
- Tailwind
- HTML
- MIT
Preview
Live component
9:41 100%
devsnips.site/library/tailwind/components/dropdowns/context-menu/ fluid · no fixed width 100%
Install
Add to your project
npx devsnips add Tailwind/Components/Dropdowns/context-menu Tailwind/Components/Dropdowns/context-menu <!-- Context Menu -->
<div class="relative">
<div
id="context-trigger"
class="w-full max-w-md mx-auto p-8 bg-white rounded-xl border-2 border-dashed border-gray-300 text-center cursor-context-menu"
oncontextmenu="showContextMenu(event)"
>
<div class="flex flex-col items-center gap-3">
<svg class="w-12 h-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<p class="text-gray-600">Right-click anywhere to open context menu</p>
<p class="text-sm text-gray-400">This is the context trigger area</p>
</div>
</div>
<!-- Context Menu -->
<div
id="context-menu"
class="hidden fixed z-50 w-64 bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden"
style="left: 0; top: 0;"
>
<!-- File Actions -->
<div class="px-3 py-2 border-b border-gray-100">
<p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">File</p>
</div>
<div class="py-1">
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
</svg>
<span>New File</span>
<kbd class="ml-auto px-1.5 py-0.5 text-xs text-gray-400 bg-gray-100 rounded">⌘N</kbd>
</button>
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"></path>
</svg>
<span>Open Folder</span>
<kbd class="ml-auto px-1.5 py-0.5 text-xs text-gray-400 bg-gray-100 rounded">⌘O</kbd>
</button>
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"></path>
</svg>
<span>Share</span>
</button>
</div>
<!-- Divider -->
<div class="border-t border-gray-100"></div>
<!-- Edit Actions -->
<div class="px-3 py-2 border-b border-gray-100">
<p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Edit</p>
</div>
<div class="py-1">
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
<span>Rename</span>
<kbd class="ml-auto px-1.5 py-0.5 text-xs text-gray-400 bg-gray-100 rounded">F2</kbd>
</button>
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
</svg>
<span>Duplicate</span>
</button>
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"></path>
</svg>
<span>Copy Path</span>
<kbd class="ml-auto px-1.5 py-0.5 text-xs text-gray-400 bg-gray-100 rounded">⌘⌥C</kbd>
</button>
</div>
<!-- Divider -->
<div class="border-t border-gray-100"></div>
<!-- View -->
<div class="py-1">
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-blue-50 hover:text-blue-600 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
<span>Preview</span>
</button>
</div>
<!-- Divider -->
<div class="border-t border-gray-100"></div>
<!-- Destructive -->
<div class="py-1">
<button class="w-full flex items-center gap-3 px-4 py-2 text-sm text-red-600 hover:bg-red-50 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
<span>Delete</span>
<kbd class="ml-auto px-1.5 py-0.5 text-xs text-gray-400 bg-gray-100 rounded">⌘⌫</kbd>
</button>
</div>
</div>
</div>
<script>
function showContextMenu(event) {
event.preventDefault();
const menu = document.getElementById('context-menu');
menu.classList.remove('hidden');
// Position the menu
const x = event.clientX;
const y = event.clientY;
// Adjust if menu would go off screen
const menuWidth = 256;
const menuHeight = menu.offsetHeight;
const adjustedX = x + menuWidth > window.innerWidth ? window.innerWidth - menuWidth - 10 : x;
const adjustedY = y + menuHeight > window.innerHeight ? window.innerHeight - menuHeight - 10 : y;
menu.style.left = adjustedX + 'px';
menu.style.top = adjustedY + 'px';
}
document.addEventListener('click', function() {
const menu = document.getElementById('context-menu');
menu.classList.add('hidden');
});
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
const menu = document.getElementById('context-menu');
menu.classList.add('hidden');
}
});
</script> # Context Menu
Right-click / context menu pattern.
## Preview
Open `preview.html` for a standalone demonstration.
## Features
- Context positioning
- Action list
## Usage
```bash
npx devsnips add Tailwind/Components/Dropdowns/context-menu
```
Copy from `code.html`.
## Customization
- Menu surface and item styles
## Accessibility
- Provide keyboard alternatives to pointer-only context actions
## Dependencies
- Tailwind CSS; JS for positioning/open state as present
## File Structure
- `code.html` · `preview.html` · `metadata.json` · `README.md` 141 lines UTF-8 · LF · Spaces: 2
DevSnips AI ready Claude · Cursor · Windsurf
Agent skill & Model Context Protocol
Pass this component straight into your AI workflow. DevSnips exposes each resource as a structured, addressable registry entry, so your agent installs the real files instead of approximating them.
devsnips://components/dropdowns/context-menu I want to use this DevSnips resource in production: Page: https://devsnips.site/library/tailwind/components/dropdowns/context-menu/ Install: npx devsnips add Tailwind/Components/Dropdowns/context-menu This is the Context Menu — Right-click context menu with grouped actions, keyboard shortcuts, and screen-edge detection for file management applications. Use this DevSnips resource as the starting point for my project. Adapt it to my project's stack and conventions, fix any issues, and make it production-ready while preserving its intended design and behavior.
Paste into ChatGPT, Claude or your agent — it already carries the page URL and the exact install path.
Resource URI
devsnips://components/dropdowns/context-menu