import { useEffect, useRef } from "react"; import { useI18n } from "@arronqzy/i18n/react"; export type BlueprintContextMenuState = | { kind: "pane"; clientX: number; clientY: number; } | { kind: "node"; clientX: number; clientY: number; nodeId: string; role: "blueprint" | "logic" | "and" | "lifecycle" | "event" | "fetch" | "json" | "clock"; } | { kind: "edge"; clientX: number; clientY: number; edgeId: string; }; type BlueprintContextMenuProps = { menu: BlueprintContextMenuState | null; onClose: () => void; onAddBlueprintNode: (clientX: number, clientY: number) => void; onDeleteNode: (nodeId: string) => void; onDeleteEdge: (edgeId: string) => void; }; export function BlueprintContextMenu({ menu, onClose, onAddBlueprintNode, onDeleteNode, onDeleteEdge, }: BlueprintContextMenuProps) { const { t } = useI18n(); const menuRef = useRef(null); useEffect(() => { if (!menu) return; const closeOnPointerDown = (event: Event) => { const target = event.target as globalThis.Node | null; if (target && menuRef.current?.contains(target)) return; onClose(); }; const close = () => onClose(); window.addEventListener("pointerdown", closeOnPointerDown); window.addEventListener("scroll", close, true); window.addEventListener("resize", close); return () => { window.removeEventListener("pointerdown", closeOnPointerDown); window.removeEventListener("scroll", close, true); window.removeEventListener("resize", close); }; }, [menu, onClose]); if (!menu) return null; return (
e.stopPropagation()} onContextMenu={(e) => e.preventDefault()} > {menu.kind === "pane" ? ( ) : null} {menu.kind === "node" ? ( ) : null} {menu.kind === "edge" ? ( ) : null}
); }