All files / src/components/ui/menu ContextMenu.tsx

0% Statements 0/20
0% Branches 0/14
0% Functions 0/5
0% Lines 0/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54                                                                                                           
import React, { useCallback, useEffect, useRef } from "react";
import useNestedMenu from "ui/hooks/use-nested-menu";
import { PositionedPortal } from "ui/layout/PositionedPortal";
import { Menu } from "ui/menu/Menu";
 
interface ContextMenuProps {
  readonly x: number;
  readonly y: number;
  readonly children?: JSX.Element[];
  readonly onClose?: () => void;
  readonly onKeyDown?: (e: React.KeyboardEvent) => boolean;
}
 
export const ContextMenu = ({
  x,
  y,
  children,
  onClose,
  onKeyDown,
}: ContextMenuProps) => {
  const { menuRef, isOpen, childrenWithProps } = useNestedMenu(
    children,
    true,
    "right",
    onKeyDown,
  );
  const wasOpen = useRef(isOpen);
  useEffect(() => {
    Iif (wasOpen.current && !isOpen) {
      onClose?.();
    }
    wasOpen.current = isOpen;
  }, [isOpen, onClose]);
 
  const onHotkeyHandled = useCallback(() => {
    onClose?.();
  }, [onClose]);
 
  useEffect(() => {
    Iif (isOpen) {
      document.addEventListener("gbs::hotkey", onHotkeyHandled);
    }
    return () => {
      document.removeEventListener("gbs::hotkey", onHotkeyHandled);
    };
  }, [isOpen, onHotkeyHandled]);
 
  return isOpen ? (
    <PositionedPortal x={x} y={y} offsetX={-2} offsetY={-10}>
      <Menu ref={menuRef}>{childrenWithProps}</Menu>
    </PositionedPortal>
  ) : null;
};