← Components/Overlays

ContextMenu

contextmenu-1779388705776.tsx
'use client';
import { useState, useEffect, useRef } from 'react';

export default function ContextMenu() {
  const [menu, setMenu] = useState(null);
  const menuRef = useRef(null);

  const items = [
    { label: 'Open', icon: '↗', shortcut: '↵', action: 'open' },
    { label: 'Copy link', icon: '🔗', shortcut: '⌘C', action: 'copy' },
    { label: 'Rename', icon: '✏️', shortcut: 'F2', action: 'rename' },
    null,
    { label: 'Move to...', icon: '📁', shortcut: '', action: 'move' },
    { label: 'Duplicate', icon: '⧉', shortcut: '⌘D', action: 'dup' },
    null,
    { label: 'Delete', icon: '🗑️', shortcut: '⌫', action: 'delete', danger: true },
  ];

  useEffect(() => {
    const close = () => setMenu(null);
    window.addEventListener('click', close);
    return () => window.removeEventListener('click', close);
  }, []);

  return (
    <div
      onContextMenu={e => { e.preventDefault(); setMenu({ x: e.clientX, y: e.clientY }); }}
      style={{
        width: '320px', height: '180px',
        background: 'rgba(255,255,255,0.03)',
        border: '2px dashed rgba(255,255,255,0.12)',
        borderRadius: '16px',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'system-ui, sans-serif',
        color: 'rgba(245,245,240,0.3)',
        fontSize: '13px', cursor: 'context-menu',
        userSelect: 'none',
      }}
    >
      Right-click anywhere
      {menu && (
        <div ref={menuRef} onClick={e => e.stopPropagation()} style={{
          position: 'fixed', top: menu.y, left: menu.x,
          background: '#141414',
          border: '1px solid rgba(255,255,255,0.1)',
          borderRadius: '12px', padding: '6px',
          minWidth: '200px', boxShadow: '0 16px 48px rgba(0,0,0,0.6)',
          zIndex: 9999,
        }}>
          {items.map((item, i) => item === null ? (
            <div key={i} style={{ height: '1px', background: 'rgba(255,255,255,0.06)', margin: '4px 0' }} />
          ) : (
            <div key={i} style={{
              display: 'flex', alignItems: 'center', gap: '10px',
              padding: '8px 12px', borderRadius: '8px', cursor: 'pointer',
              color: item.danger ? '#ef4444' : '#F5F5F0', fontSize: '13px',
              transition: 'background 0.15s',
            }}
              onMouseEnter={e => e.currentTarget.style.background = item.danger ? 'rgba(239,68,68,0.1)' : 'rgba(255,255,255,0.05)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
              onClick={() => setMenu(null)}
            >
              <span style={{ width: '16px', textAlign: 'center' }}>{item.icon}</span>
              <span style={{ flex: 1 }}>{item.label}</span>
              {item.shortcut && <span style={{ color: 'rgba(245,245,240,0.3)', fontSize: '11px' }}>{item.shortcut}</span>}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Component info

CategoryOverlays
Frameworkreact
TierFREE
Views0
Copies0

About

Right-click context menu with keyboard shortcut hints

More from Overlays

'use client';

import React, { useState } from 'react';

interface AlertDialogProps {
  isOpen: boolean;
  onClose: () => void;
  onConfirm: () => void;
  title: string;
  description: string;
}

const AlertDialog: React.FC<AlertDialogProps> = ({
  i
AlertDialog
Overlays
'use client';

import { useState, useEffect } from 'react';

interface Command {
  id: number;
  title: string;
  description: string;
}

const commands: Command[] = [
  { id: 1, title: 'New File', description: 'Create a new file' },
  { id: 2, title
CommandPalette
Overlays
'use client'
import { useState, useEffect } from 'react'

const notifications = [
  { id: 1, type: '🎉', title: 'New component published', time: '2m ago', read: false },
  { id: 2, type: '💰', title: 'Pro subscription active', time: '1h ago', read: f
DrawerPanel
Overlays
'use client';

import { useState } from 'react';

interface BottomSheetProps {
  isOpen: boolean;
  onClose: () => void;
}

const BottomSheet = ({ isOpen, onClose }: BottomSheetProps) => {
  const [isDragging, setIsDragging] = useState(false);
  cons
BottomSheet
Overlays