Menú contextual

Un menú contextual componible, basado en portales, para la interfaz de DayFlow. Admite submenús anidados, etiquetas, separadores y un selector de color integrado. Se cierra solo al hacer clic fuera, al desplazarse, al redimensionar o al pulsar Escape.

Instalación

npm install @dayflow/ui-context-menu
pnpm add @dayflow/ui-context-menu
yarn add @dayflow/ui-context-menu
bun add @dayflow/ui-context-menu

En proyectos que ya usan Tailwind CSS, importa el bundle de solo componentes:

@import '@dayflow/ui-context-menu/dist/styles.components.css';
@import 'tailwindcss';

En proyectos sin Tailwind CSS, importa en su lugar la hoja de estilos completa:

import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuLabel,
  ContextMenuSub,
  ContextMenuSubTrigger,
  ContextMenuSubContent,
  ContextMenuColorPicker,
} from '@dayflow/ui-context-menu';
import '@dayflow/ui-context-menu/dist/styles.css';

Uso básico

Renderiza ContextMenu en la posición del cursor capturada desde un evento contextmenu.

import { useState } from 'react';
import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuSeparator,
} from '@dayflow/ui-context-menu';

function MyComponent() {
  const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);

  const handleContextMenu = (e: React.MouseEvent) => {
    e.preventDefault();
    setMenu({ x: e.clientX, y: e.clientY });
  };

  return (
    <div onContextMenu={handleContextMenu}>
      Right-click here
      {menu && (
        <ContextMenu x={menu.x} y={menu.y} onClose={() => setMenu(null)}>
          <ContextMenuItem onClick={() => console.log('Edit')}>
            Edit
          </ContextMenuItem>
          <ContextMenuItem onClick={() => console.log('Copy')}>
            Copy
          </ContextMenuItem>
          <ContextMenuSeparator />
          <ContextMenuItem onClick={() => console.log('Delete')} danger>
            Delete
          </ContextMenuItem>
        </ContextMenu>
      )}
    </div>
  );
}

Con etiquetas e iconos

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuLabel>Actions</ContextMenuLabel>
  <ContextMenuItem icon={<PencilIcon />} onClick={() => onEdit()}>
    Edit Event
  </ContextMenuItem>
  <ContextMenuItem icon={<CopyIcon />} onClick={() => onDuplicate()}>
    Duplicate
  </ContextMenuItem>
  <ContextMenuSeparator />
  <ContextMenuItem icon={<TrashIcon />} onClick={() => onDelete()} danger>
    Delete
  </ContextMenuItem>
</ContextMenu>

Submenús anidados

Envuelve los elementos con ContextMenuSub para crear submenús que se abren al pasar el ratón. El submenú se reposiciona automáticamente para no salirse de la ventana.

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuItem onClick={() => onEdit()}>Edit</ContextMenuItem>
  <ContextMenuSub>
    <ContextMenuSubTrigger>Move to</ContextMenuSubTrigger>
    <ContextMenuSubContent>
      <ContextMenuItem onClick={() => onMove('work')}>Work</ContextMenuItem>
      <ContextMenuItem onClick={() => onMove('personal')}>
        Personal
      </ContextMenuItem>
    </ContextMenuSubContent>
  </ContextMenuSub>
  <ContextMenuSeparator />
  <ContextMenuItem danger onClick={() => onDelete()}>
    Delete
  </ContextMenuItem>
</ContextMenu>

Selector de color

ContextMenuColorPicker renderiza una fila de muestras predefinidas y, opcionalmente, una acción de «Color personalizado».

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuLabel>Calendar Color</ContextMenuLabel>
  <ContextMenuColorPicker
    selectedColor={currentColor}
    onSelect={color => {
      updateCalendarColor(color);
      onClose();
    }}
    onCustomColor={() => openColorDialog()}
    customColorLabel='Custom color...'
  />
</ContextMenu>

Elementos desactivados

<ContextMenuItem onClick={() => onPaste()} disabled={!hasClipboard}>
  Paste
</ContextMenuItem>

Referencia de la API

ContextMenu

PropTipoDescripción
xnumberPosición horizontal (por ejemplo, event.clientX)
ynumberPosición vertical (por ejemplo, event.clientY)
onClose() => voidSe llama cuando el menú debe cerrarse
childrenComponentChildrenElementos del menú
classNamestringClases CSS adicionales para el contenedor del menú

ContextMenuItem

PropTipoValor por defectoDescripción
onClick() => voidManejador del clic
childrenComponentChildrenEtiqueta del elemento
iconComponentChildrenIcono que se muestra a la izquierda de la etiqueta
dangerbooleanfalseMuestra el elemento en rojo, como acción destructiva
disabledbooleanfalseHace que el elemento no sea interactivo

ContextMenuColorPicker

PropTipoValor por defectoDescripción
selectedColorstringColor activo en este momento (hex)
onSelect(color: string) => voidSe llama al pulsar una muestra
onCustomColor() => voidSe llama al pulsar la fila de color personalizado
customColorLabelstring"Custom Color"Etiqueta de la acción de color personalizado

Otras exportaciones

ComponenteDescripción
ContextMenuSeparatorLínea divisoria horizontal
ContextMenuLabelEncabezado de sección, no interactivo
ContextMenuSubContenedor que gestiona el estado abierto de un submenú
ContextMenuSubTriggerFila que despliega el submenú al pasar el ratón
ContextMenuSubContentEl panel flotante del submenú

En esta página