component.tsx 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import React, { FC, ReactNode, useEffect, useRef } from 'react';
  2. import { PositionSchema } from '@flowgram.ai/utils';
  3. interface NodePanelContainerProps {
  4. onSelect: (nodeType: string | undefined) => void;
  5. position: PositionSchema;
  6. children: ReactNode;
  7. }
  8. export const NodePanelContainer: FC<NodePanelContainerProps> = (props) => {
  9. const { onSelect, position, children } = props;
  10. const panelRef = useRef<HTMLDivElement>(null);
  11. useEffect(() => {
  12. const handleClickOutside = (event: MouseEvent) => {
  13. // 确保点击事件的目标不是组件本身或其子元素
  14. if (panelRef.current && !panelRef.current.contains(event.target as Node)) {
  15. onSelect(undefined);
  16. }
  17. };
  18. // 添加事件监听器到document
  19. document.addEventListener('mousedown', handleClickOutside);
  20. // 清理函数
  21. return () => {
  22. document.removeEventListener('mousedown', handleClickOutside);
  23. };
  24. }, [onSelect]); // 依赖项为onSelect,确保回调函数变化时重新绑定
  25. return (
  26. <div
  27. ref={panelRef}
  28. className="node-panel-container"
  29. data-flow-editor-selectable="false"
  30. style={{
  31. position: 'absolute',
  32. zIndex: 9999,
  33. top: position.y,
  34. left: position.x,
  35. }}
  36. >
  37. {children}
  38. </div>
  39. );
  40. };