// Right-click menu on a session card (docs/SIDEBAR.md): rename, spawn similar, // kill. Rendered into so a scrolling sidebar cannot clip it. import { useEffect, useRef } from "react"; import { createPortal } from "react-dom"; export interface ContextMenuItem { label: string; danger?: boolean; onSelect(): void; } export interface ContextMenuProps { x: number; y: number; items: ContextMenuItem[]; onClose(): void; } export function ContextMenu({ x, y, items, onClose }: ContextMenuProps) { const ref = useRef(null); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; const onDown = (e: Event) => { if (!ref.current?.contains(e.target as Node)) onClose(); }; document.addEventListener("keydown", onKey); document.addEventListener("pointerdown", onDown, true); return () => { document.removeEventListener("keydown", onKey); document.removeEventListener("pointerdown", onDown, true); }; }, [onClose]); return createPortal(
{items.map((item) => ( ))}
, document.body, ); }