React + MotionOverlays

Menú contextual

Un menú compacto y esmerilado que se abre desde un botón de «más» con acciones como copiar, compartir y eliminar.

Ajustes

20px

Código

import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { ChevronRight, Copy, Link2, MoreHorizontal, Share2, Trash2 } from "lucide-react";

const spring = { type: "spring" as const, stiffness: 300, damping: 30 };

const ITEMS = [
  { icon: Copy, label: "Copiar" },
  { icon: Link2, label: "Copiar enlace" },
  { icon: Share2, label: "Compartir" },
  { icon: Trash2, label: "Eliminar" },
];

interface ContextMenuProps {
  blur?: number;
}

export default function ContextMenu({ blur = 20 }: ContextMenuProps) {
  const [open, setOpen] = useState(false);

  return (
    <div className="relative text-[#1d1d1f] dark:text-[#f5f5f7]">
      <button
        type="button"
        aria-label="Más acciones"
        aria-expanded={open}
        onClick={() => setOpen((o) => !o)}
        className="grid h-12 w-12 place-items-center rounded-full bg-white dark:bg-[#1c1c1e] shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)]"
      >
        <MoreHorizontal />
      </button>
      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0, scale: 0.9, y: -6 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            exit={{ opacity: 0, scale: 0.9 }}
            transition={spring}
            className="absolute left-1/2 top-14 z-10 w-48 -translate-x-1/2 rounded-2xl border border-black/10 bg-white/70 p-1.5 shadow-[0_4px_12px_rgba(0,0,0,0.04),0_24px_60px_rgba(0,0,0,0.1)] dark:border-white/10 dark:bg-black/70"
            style={{ backdropFilter: `blur(${blur}px)` }}
          >
            {ITEMS.map(({ icon: Icon, label }) => (
              <button
                key={label}
                type="button"
                className="flex w-full items-center gap-2 rounded-xl px-3 py-2 text-sm hover:bg-black/5 dark:hover:bg-white/10"
              >
                <Icon className="h-4 w-4" />
                {label}
                <ChevronRight className="ml-auto h-3 w-3" />
              </button>
            ))}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

Prompt para IA

Pégalo en ChatGPT, Claude o Cursor y adaptará el bloque a tu proyecto con estos ajustes, aunque no uses React.

Más en Overlays

Dónde usarlo

El botón de tres puntos esconde acciones útiles pero no constantes: copiar el enlace de un documento, compartir una foto de una galería o eliminar un borrador en un gestor de contenidos. El fondo de cristal desenfocado lo deja ligero, como los menús del Mac. Este menú contextual en React encaja en listas de archivos, tarjetas y filas de tablas.

Pon las acciones destructivas como «Eliminar» al final y plantéate pintarlas de rojo. Sube el blur si el menú se abre sobre imágenes cargadas y bájalo sobre fondos lisos. Más de seis opciones suele indicar que alguna sobra ahí.