у меня есть вот такой код 
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
import { Group, Layer, Line, Rect, Stage } from 'react-konva';
import Grid from './Grid';
import { SizeContext } from '../contexts/size-context';
import { useStageInteractionContext } from '../hooks/useStageInteractionContext';
import { useDocumentContext } from '../hooks/useDocumentContext';
import Konva from 'konva';
import WebFont from 'webfontloader';
import { SelectedObject, useGridStore, useSelectionStore } from '../store';
import { ContextMenu } from 'primereact/contextmenu';
import { MenuItem } from 'primereact/menuitem';
import { Subject, tap } from 'rxjs';
import TrashIcon from '@tecon/svg-icons/dist/esm/icons/TrashIcon';
import { IPoint } from '../models/infrastucture/point';
import { useEditorToolsStore } from '../store/editorTools-store';
import { Actions } from '../enums/actions';
import RenderPage from '../renderers/RenderPage';
import RenderFrame from '../renderers/RenderFrame';
import { EditorPrimitives } from '../models/primitives/enums/editor-primitives';
import { Frame } from '../models/frames/frame';
import InputOutputDarkblueIcon from '../../../svg-icons/src/icons/InputOutputDarkblueIcon';
import LinkDarkblueIcon from '../../../svg-icons/src/icons/LinkDarkblueIcon';
import CopyDarkblueIcon from '@tecon/svg-icons/dist/cjs/icons/CopyDarkblueIcon';
import PasteDarkblueIcon from '@tecon/svg-icons/dist/cjs/icons/PasteDarkblueIcon';
import TreeDarkblueIcon from '@tecon/svg-icons/dist/cjs/icons/TreeDarkblueIcon';
import { previewConnection$ } from '../renderers/RenderConnector';
import { useModalDialogStore } from '../store/modalDialog-store';
import { ModalKey } from '../constants';
import { Page } from '../models/pages/page';
import ImportDarkblueIcon from '../../../svg-icons/src/icons/ImportDarkblueIcon';
import { findCrossPageLink, findInPageLinkCouple, findPageLinkParent } from '../utils/primitiveSearch';
import { findPageById } from '../utils/inDocumentSearch';

export enum ObjectChange {
  Remove,
  Paste,
  Add,
  AddLink,
}

const objectChangeSource = new Subject<{
  pageId: string | number | undefined;
  id: Array<string | number | SelectedObject>;
  action: ObjectChange;
  data?: object;
}>();
export const objectChange$ = objectChangeSource.asObservable();

const dragSource = new Subject<{ pageId: string | number; position: IPoint }>();
export const drag$ = dragSource.asObservable();

const inversionSource = new Subject<{ id: string | number; inversion: boolean }>();
export const inversion$ = inversionSource.asObservable();

const breakSource = new Subject<{ id: string | number; position: IPoint }>();
export const break$ = breakSource.asObservable();

const goTreeSource = new Subject<{ id: string }>();
export const goTree$ = goTreeSource.asObservable();

interface GraphEditorProps {
  isDrag: boolean;
  onDragEnd: () => void;
  actionSource: Subject<{ action: Actions; pageId?: string | number; x?: number; y?: number }>;
}

const GraphEditor = ({ isDrag, onDragEnd, actionSource }: GraphEditorProps) => {
  const editorDocument = useDocumentContext();
  const stageInteraction = useStageInteractionContext();
  const size = useContext(SizeContext);
  const stageRef = useRef<Konva.Stage | null>(null);
  const [fontLoaded, setFontLoaded] = useState(false);
  const [pointerPosition, setPointerPosition] = useState<IPoint>({ x: 0, y: 0 });
  const [idForCopy, setIdForCopy] = useState<Array<string | number | SelectedObject>>([]);
  const [previewConnection, setPreviewConnection] = useState<number[]>([]);

  const selectedObjects = useSelectionStore((state) => state.selectedObjects);
  const setSelectedObjects = useSelectionStore((state) => state.setSelectedObjects);
  const selectedObjectReferenceId = useSelectionStore((state) => state.selectedObjectReferenceId);
  const setSelectedObjectReferenceId = useSelectionStore((state) => state.setSelectedObjectReferenceId);
  const [isDraggingStage, setIsDraggingStage] = useState(false);
  const editorToolsStore = useEditorToolsStore();
  const gridSize = useGridStore((state) => state.gridSize);
  const { setModalKey } = useModalDialogStore();

  useEffect(() => {
    WebFont.load({
      custom: {
        families: ['GOST Type A'], // Name of the font
        urls: ['../../index.css'], // URL to the font file
      },
      active: () => {
        setFontLoaded(true);
        console.log('Fonts loaded successfully');
      },
      inactive: () => {
        console.error('Failed to load fonts');
      },
    });
  }, []);

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        editorToolsStore.setAction(null);
        editorToolsStore.setPageId(null);
      }
    };

    window.addEventListener('keydown', handleKeyDown);

    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, []);

  useEffect(() => {
    setSelectedObjectReferenceId(null);
  }, [editorDocument.activePage?.id]);

  const handleStageClick = (e: Konva.KonvaEventObject<MouseEvent>) => {
    switch (e.evt.button) {
      case 0: {
        if (e.target === stageRef.current || e.target.id() === 'page') {
          setSelectedObjects([]);
          setSelectedObjectReferenceId(null);
        }
        break;
      }
    }

    checkClickOnEmptyStagePlace(e);

    if (editorToolsStore.action) {
      addSimplePrimitiveOnStage();
    }
  };

  const checkClickOnEmptyStagePlace = (e: Konva.KonvaEventObject<MouseEvent>) => {
    const stage = e.target.getStage();
    const pointerPosition = stage?.getPointerPosition();
    // Проверяем, есть ли объект под курсором
    const shape = pointerPosition && stage?.getIntersection(pointerPosition);

    if (!shape || shape.attrs.id === 'page') {
      setSelectedObjects([]);
    }
  };

  const addSimplePrimitiveOnStage = () => {
    if (!editorToolsStore.action || !editorToolsStore.pageId) {
      return;
    }

    const pointerPosition = getPointerPositionOnStage();

    actionSource.next({
      action: editorToolsStore.action,
      pageId: editorToolsStore.pageId,
      x: Math.round(pointerPosition.x / gridSize) * gridSize,
      y: Math.round(pointerPosition.y / gridSize) * gridSize,
    });

    editorToolsStore.setAction(null);
    editorToolsStore.setPageId(null);
  };

  const onDelete = () => {
    console.log('objects deletion', selectedObjects);
    const ids: (string | number)[] = [];
    selectedObjects?.forEach((object) =>
      object?.id.toString().startsWith('connection-')
        ? ids.push(object?.id.toString().replace(/connection-(.+?)-segment-\d+/, '$1'))
        : ids.push(object?.id),
    );

    objectChangeSource.next({
      pageId: editorDocument.activePage?.id,
      id: [...ids],
      action: ObjectChange.Remove,
    });
    setSelectedObjects([]);
    setSelectedObjectReferenceId(null);
  };

  const onPaste = () => {
    // Get the mouse position relative to the stage
    const stage = stageRef.current;
    const mousePosition = stage?.getPointerPosition() ?? { x: 0, y: 0 };

    // Calculate the position relative to the page
    const pageX = (mousePosition.x - stageInteraction.point.x) / stageInteraction.scale;
    const pageY = (mousePosition.y - stageInteraction.point.y) / stageInteraction.scale;

    // Use the calculated coordinates
    objectChangeSource.next({
      pageId: editorDocument.activePage?.id,
      id: idForCopy,
      action: ObjectChange.Paste,
      data: { x: pageX, y: pageY },
    });
  };

  /**
   * Инвертирует коннектор
   * @param connector
   */
  const onInversion = (connector: Konva.Shape) => {
    const inversion = connector.getAttr('inversion');
    inversionSource.next({
      id: connector.id().toString().replace('connector-', ''),
      inversion: !inversion,
    });
    connector.setAttr('inversion', !inversion);
  };

  /**
   * Добавляет излом на связь
   */
  const onAddBreak = () => {
    const stage = stageRef.current;
    const mousePosition = stage?.getPointerPosition() ?? { x: 0, y: 0 };
    const x = (mousePosition.x - stageInteraction.point.x) / stageInteraction.scale;
    const y = (mousePosition.y - stageInteraction.point.y) / stageInteraction.scale;

    if (mousePosition) {
      if (!selectedObjects[0]?.id) return;

      breakSource.next({
        id: selectedObjects[0].id,
        position: { x: x, y: y },
      });
    }
  };

  /**
   * Осуществляет переход к объекту в древе объектов
   */
  const onGoTree = () => {
    if (!selectedObjectReferenceId) {
      return;
    }
    goTreeSource.next({ id: selectedObjectReferenceId });
    setSelectedObjectReferenceId(null);
  };

  /**
   * Вызывает диалоговое окно элементов, связанных с выделенном сигналом
   */
  const showObjectLinks = () => {
    setModalKey(ModalKey.SELECT_SIGNAL_USAGE);
  };

  /**
   * Осуществляет переход  к входной или выходной ссылке
   */
  const onGoToLink = () => {
    const selectedLinkId = selectedObjects[0].id;
    const activePageId = editorDocument.activePage?.id;
    const pages = editorDocument.pages;

    findPageLink(activePageId, selectedLinkId, pages);
  };

  /**
   * Находит пары ссылок на страницах документа
   * @param activePageId - id активной страницы
   * @param linkId - id ссылки
   * @param pages -массив страниц документа
   */
  const findPageLink = (
    activePageId: string | undefined,
    linkId: string | number | undefined,
    pages: Page[] | undefined,
  ) => {
    if (!activePageId || !linkId || !pages) return;

    const activePage = pages.find((page) => page.id === activePageId);
    const primitiveParent = findPageLinkParent(linkId, activePage?.primitives, null);
    const coupleInPageLinkId =
      primitiveParent && findInPageLinkCouple(linkId, activePage?.primitives, primitiveParent?.id);

    //если ссылка внутристраничная
    if (coupleInPageLinkId) {
      setSelectedObjects([{ id: coupleInPageLinkId }]);
    }
    //если ссылка межстраничная
    else {
      for (const page of pages) {
        const crossPagePrimitive = findCrossPageLink(
          primitiveParent?.linkPageId,
          page.primitives,
          primitiveParent?.pageId,
          null,
        );
        if (crossPagePrimitive) {
          const page = findPageById(pages, crossPagePrimitive?.pageId);
          const inPageCouplePrimitiveId = [...(crossPagePrimitive?.primitives?.keys() || [])][0];

          editorDocument.setActivePage(page);
          inPageCouplePrimitiveId && setSelectedObjects([{ id: inPageCouplePrimitiveId }]);
          break;
        }
      }
    }
  };

  /**
   * Обработчик отображения контекстного меню
   * @param e
   */
  const handleContextMenu = (e: Konva.KonvaEventObject<MouseEvent>) => {
    e.evt.preventDefault(); // Prevent the default browser context menu

    if (e.target.id().startsWith('connector-')) {
      // Меню для коннектора
      setMenuItems([
        {
          label: 'Инверсия',
          command: () => {
            onInversion(e.target as Konva.Shape);
          },
          icon: InputOutputDarkblueIcon({ width: 25, height: 25 }),
        },
      ]);
    } else if (e.target.parent?.id().startsWith('connection-')) {
      // Меню для связи
      setMenuItems([
        {
          label: 'Излом',
          icon: <i className='pi pi-wave-pulse' style={{ color: '#1769AA' }} />,
          command: () => onAddBreak(),
        },
        {
          label: 'Удалить',
          icon: TrashIcon({ width: 25, height: 25 }),
          command: onDelete,
        },
      ]);
    } else if (selectedObjects.length !== 0 || idForCopy.length !== 0) {
      // Меню для оставшихся элементов
      let menu = [
        {
          disabled: selectedObjects?.length === 0 || selectedObjects?.length > 1,
          label: 'Создать ссылку',
          icon: LinkDarkblueIcon({ width: 25, height: 25 }),
          command: () => {
            if (!selectedObjects[0]?.id) return;

            objectChangeSource.next({
              pageId: editorDocument.activePage?.id,
              id: [selectedObjects[0].id],
              action: ObjectChange.AddLink,
            });
          },
        },
        {
          disabled: selectedObjects?.length === 0,
          label: 'Копировать',
          icon: CopyDarkblueIcon({ width: 25, height: 25 }),
          command: () => setIdForCopy([...selectedObjects]),
        },
        {
          disabled: idForCopy.length === 0,
          label: 'Вставить',
          icon: PasteDarkblueIcon({ width: 25, height: 25 }),
          command: onPaste,
        },
        {
          disabled: selectedObjectReferenceId === null,
          label: 'Выделить в древе',
          icon: TreeDarkblueIcon({ width: 25, height: 25 }),
          command: onGoTree,
        },
        {
          disabled: selectedObjectReferenceId === null,
          label: 'Показать связи',
          icon: (
            <div className='flex align-items-center justify-content-center'>
              <i
                className='pi pi-search flex align-items-center justify-content-center'
                style={{ width: 25, height: 25 }}
              ></i>
            </div>
          ),
          command: showObjectLinks,
        },
        {
          disabled: selectedObjects?.length === 0,
          label: 'Перейти по ссылке',
          icon: ImportDarkblueIcon({ width: 25, height: 25 }),
          command: onGoToLink,
        },
        { separator: true },
        {
          disabled: selectedObjects?.length === 0,
          label: 'Удалить',
          icon: TrashIcon({ width: 25, height: 25 }),
          command: onDelete,
        },
      ];

      if (selectedObjects.length === 0 || selectedObjects.length > 1) {
        menu = menu.slice(1);
      } else {
        const primitive = editorDocument.activePage?.primitives.get(selectedObjects[0].id);
        if (primitive && 'isResultSignal' in primitive && primitive.isResultSignal) {
          menu = menu.slice(1);
        }
      }

      setMenuItems(menu);
    } else {
      setMenuItems([]);
    }

    if (cm.current) {
      cm.current.show(e.evt);
    }
  };

  const cm = useRef<ContextMenu>(null);
  const [menuItems, setMenuItems] = useState<MenuItem[]>([]);

  const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
    if (e.code === 'Delete' && selectedObjects?.length > 0) {
      onDelete();
    }

    if (e.ctrlKey && e.code === 'KeyC' && selectedObjects?.length > 0) {
      setIdForCopy([...selectedObjects]);
    }

    if (e.ctrlKey && e.code === 'KeyV') {
      onPaste();
    }
  };

  /**
   * Получение положения мыши на сцене
   * @returns {{x: number, y: number}} - Положение мыши на сцене.
   */
  const getPointerPositionOnStage = useCallback((): IPoint => {
    if (!stageRef.current) return { x: 0, y: 0 };
    const pointerPosition = stageRef.current.getPointerPosition();
    if (!pointerPosition) {
      return { x: 0, y: 0 };
    }

    const x = (pointerPosition.x - stageInteraction.point.x) / stageInteraction.scale;
    const y = (pointerPosition.y - stageInteraction.point.y) / stageInteraction.scale;

    return { x: x, y: y };
  }, [stageInteraction.point.x, stageInteraction.point.y, stageInteraction.scale]);

  /**
   * Обработчик события перетаскивания над элементом
   * @param {React.DragEvent<HTMLDivElement>} e - Событие перетаскивания
   */
  const handleDragOver = useCallback(
    (e: React.DragEvent<HTMLDivElement>) => {
      if (!isDrag) {
        return;
      }
      e.preventDefault();
      stageRef.current?.setPointersPositions(e);

      // Вычисляем смещение относительно предыдущей позиции
      const pointerPosition = getPointerPositionOnStage();

      setPointerPosition({ x: pointerPosition.x, y: pointerPosition.y });
    },
    [isDrag, getPointerPositionOnStage],
  );

  /**
   * Обработчик события отпускания перетаскиваемого элемента
   */
  const handleDrop = useCallback(() => {
    if (!editorDocument.activePage) {
      return;
    }

    const pointerPosition = getPointerPositionOnStage();

    dragSource.next({
      position: {
        x: Math.round(pointerPosition.x / gridSize) * gridSize,
        y: Math.round(pointerPosition.y / gridSize) * gridSize,
      },
      pageId: editorDocument.activePage.id,
    });

    // Удаляем превью
  }, [editorDocument.activePage, getPointerPositionOnStage, gridSize]);

  useEffect(() => {
    const subscription = previewConnection$
      .pipe(
        tap(async ({ points }) => {
          setPreviewConnection(points);
        }),
      )
      .subscribe({ error: (err) => console.log(err) });

    return () => subscription.unsubscribe();
  }, []);

  /**
   * Функция для включения режима перемещения сцены
   */
  const enableStageDragging = () => {
    setIsDraggingStage(true);

    // Делаем всю сцену draggable
    stageRef.current?.draggable(true);
  };

  /**
   * Функция для выключения режима перемещения сцены
   */
  const disableStageDragging = () => {
    setIsDraggingStage(false);

    // Отключаем draggable у сцены
    stageRef.current?.draggable(false);
  };

  /**
   * Обработчик кликов по сцене
   */
  const handleMouseDown = (e: Konva.KonvaEventObject<MouseEvent>) => {
    // Проверяем, нажата ли средняя кнопка мыши
    if (e.evt.button === 1) {
      enableStageDragging();
    }
  };

  const handleOnMouseOver = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!editorToolsStore.action) {
      return;
    }
    e.preventDefault();
    stageRef.current?.setPointersPositions(e);

    // Вычисляем смещение относительно предыдущей позиции
    const pointerPosition = getPointerPositionOnStage();

    setPointerPosition({ x: pointerPosition.x, y: pointerPosition.y });
  };

  return fontLoaded ? (
    fontLoaded && editorDocument.activePage && (
      <div
        style={{ outline: 'none' }}
        tabIndex={1}
        onKeyDown={onKeyDown}
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragEnd={onDragEnd}
        onMouseMove={handleOnMouseOver}
      >
        <Stage
          ref={stageRef}
          width={size.width}
          height={size.height}
          scaleX={stageInteraction.scale}
          scaleY={stageInteraction.scale}
          x={stageInteraction.point.x}
          y={stageInteraction.point.y}
          onWheel={stageInteraction.handleWheel}
          onClick={handleStageClick}
          onContextMenu={handleContextMenu}
          onMouseDown={handleMouseDown}
          onMouseUp={disableStageDragging}
          onDragMove={(e) => {
            if (isDraggingStage) {
              // Меняем позицию канвы, только если активен режим перетаскивания сцены
              stageInteraction.setPoint(e.currentTarget.position());
            }
          }}
        >
          <Layer>
            <Rect
              id={'page'}
              key={`p-${editorDocument.activePage.id}`}
              x={0}
              y={0}
              width={editorDocument.activePage.width}
              height={editorDocument.activePage.height}
              strokeWidth={1}
              dash={[5, 10]}
              stroke={'#cf03fc'}
            />
            {Array.from(editorDocument.activePage.primitives.values())
              .filter((x) => x.type === EditorPrimitives.Frame)
              .map((x) => (
                <RenderFrame key={x.id} {...(x as Frame)} />
              ))}
            {/*{previewDraggingPrimitive && <RenderPrimitiveByType primitive={previewDraggingPrimitive} />}*/}
            <Line points={previewConnection} stroke='grey' strokeWidth={1} dash={[4, 4]} />

            {(isDrag || editorToolsStore.action) && (
              <Group
                x={Math.round(pointerPosition.x / gridSize) * gridSize - 2.5}
                y={Math.round(pointerPosition.y / gridSize) * gridSize - 2.5}
              >
                <Line points={[0, 0, 5, 5]} stroke={'black'} strokeWidth={1} />
                <Line points={[5, 0, 0, 5]} stroke={'black'} strokeWidth={1} />
              </Group>
            )}
          </Layer>
          <Layer>
            <Grid />
          </Layer>
          <Layer id={'pageLayer'}>
            <RenderPage page={editorDocument.activePage} />
          </Layer>
        </Stage>

        {/* Context Menu */}
        <ContextMenu ref={cm} model={menuItems} />
      </div>
    )
  ) : (
    // <Loader />

    <></>
  );
};

export default GraphEditor;

я хочу сделать так чтобы когда я щелкаю на пустое пространство и при этом у меня нет примитивово для копирвоания, то меню бы не отображалось. 
сейчас я ставлю там пустой массив элементом меню
но проблема в том что так я меню все равно отображается маленькой пустой плашкой 
а как сделать так чтобы оно вообще не показывалось на экране