From df3b4252b0a3b27cf62cb36c0badf99e7c5626d4 Mon Sep 17 00:00:00 2001 From: Kam Date: Mon, 15 Jan 2024 22:04:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 25 +++++++++++++++++++++ package.json | 2 ++ src/Nodes/NodeA/NodeA.tsx | 31 +++++++++++++++----------- src/Nodes/NodeB/NodeB.tsx | 47 ++++++++++++++++++++++++--------------- src/Nodes/NodeC/NodeC.tsx | 47 ++++++++++++++++++++++++--------------- src/views/DemoA.tsx | 19 ++++++++++++++-- 6 files changed, 120 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42d69a2..49f9c2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,8 @@ "antd": "^5.12.8", "axios": "^1.4.0", "dayjs": "^1.11.10", + "hotkeys": "^1.0.0", + "hotkeys-js": "^3.13.5", "immer": "^10.0.3", "immutability-helper": "^3.1.1", "react": "^18.2.0", @@ -7785,6 +7787,19 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "node_modules/hotkeys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hotkeys/-/hotkeys-1.0.0.tgz", + "integrity": "sha512-nfvwHkZTef+Zu9RZ5wFpX/xmnZxdxlE+WHX7jP+HKb4UAs6gk4VLl1ezCIE5WIkephVXGXs2Jf0PqbNb5PFxIQ==" + }, + "node_modules/hotkeys-js": { + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.5.tgz", + "integrity": "sha512-xqPBCCC9QtLUpNZhlncfPhY/KMMiiA5+YsLDCTbwDfVBvCM+IQJPZwqB8iURZI9GQYcsmqpSlARZ238puVEs3Q==", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + } + }, "node_modules/html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -23860,6 +23875,16 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "hotkeys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hotkeys/-/hotkeys-1.0.0.tgz", + "integrity": "sha512-nfvwHkZTef+Zu9RZ5wFpX/xmnZxdxlE+WHX7jP+HKb4UAs6gk4VLl1ezCIE5WIkephVXGXs2Jf0PqbNb5PFxIQ==" + }, + "hotkeys-js": { + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.13.5.tgz", + "integrity": "sha512-xqPBCCC9QtLUpNZhlncfPhY/KMMiiA5+YsLDCTbwDfVBvCM+IQJPZwqB8iURZI9GQYcsmqpSlARZ238puVEs3Q==" + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", diff --git a/package.json b/package.json index ed807ea..3c44e42 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,8 @@ "antd": "^5.12.8", "axios": "^1.4.0", "dayjs": "^1.11.10", + "hotkeys": "^1.0.0", + "hotkeys-js": "^3.13.5", "immer": "^10.0.3", "immutability-helper": "^3.1.1", "react": "^18.2.0", diff --git a/src/Nodes/NodeA/NodeA.tsx b/src/Nodes/NodeA/NodeA.tsx index dec9c46..7d72383 100644 --- a/src/Nodes/NodeA/NodeA.tsx +++ b/src/Nodes/NodeA/NodeA.tsx @@ -3,6 +3,7 @@ import styles from "./NodeA.module.less" import { Handle, Position } from "reactflow" import type { NodeProps } from "@reactflow/core/dist/esm/types/nodes" import { useFlowDataSelector } from "@/context/FlowData" +import hotkeys from "hotkeys-js" interface NodeAProps extends NodeProps { isMenu?: boolean @@ -12,20 +13,24 @@ export interface NodeAInstance { } -const position = [Position.Top, Position.Left, Position.Right, Position.Bottom] +export const position = [Position.Top, Position.Left, Position.Right, Position.Bottom] const NodeA = forwardRef((props, ref) => { - const { isMenu, isConnectable } = props + const {isMenu, isConnectable} = props const activeNode = useFlowDataSelector((store) => store.activeNode) - - useEffect(() => { - }, [activeNode]) + useImperativeHandle(ref, (): NodeAInstance => { return {} }) + useEffect(() => { + hotkeys("a", (event) => { + console.log("--a--", event) + }) + }, []) + return (
{ @@ -34,12 +39,12 @@ const NodeA = forwardRef((props, ref) => { { position.map(i => ( @@ -48,12 +53,12 @@ const NodeA = forwardRef((props, ref) => { { position.map(i => ( diff --git a/src/Nodes/NodeB/NodeB.tsx b/src/Nodes/NodeB/NodeB.tsx index cc78f0b..444b819 100644 --- a/src/Nodes/NodeB/NodeB.tsx +++ b/src/Nodes/NodeB/NodeB.tsx @@ -3,6 +3,7 @@ import styles from "./NodeB.module.less" import { Handle, Position } from "reactflow" import type { NodeProps } from "@reactflow/core/dist/esm/types/nodes" import { useFlowDataSelector } from "@/context/FlowData" +import { position } from "@/Nodes/NodeA/NodeA" interface NodeBProps extends NodeProps { isMenu?: boolean @@ -27,24 +28,34 @@ const NodeB = forwardRef((props, ref) => { { !isMenu && ( <> - - + { + position.map(i => ( + + )) + } + { + position.map(i => ( + + )) + } NodeB ) diff --git a/src/Nodes/NodeC/NodeC.tsx b/src/Nodes/NodeC/NodeC.tsx index 1b4d61f..c03b332 100644 --- a/src/Nodes/NodeC/NodeC.tsx +++ b/src/Nodes/NodeC/NodeC.tsx @@ -3,6 +3,7 @@ import styles from "./NodeC.module.less" import { Handle, Position } from "reactflow" import type { NodeProps } from "@reactflow/core/dist/esm/types/nodes" import { useFlowDataSelector } from "@/context/FlowData" +import { position } from "@/Nodes/NodeA/NodeA" interface NodeCProps extends NodeProps { isMenu?: boolean @@ -27,24 +28,34 @@ const NodeC = forwardRef((props, ref) => { { !isMenu && ( <> - - + { + position.map(i => ( + + )) + } + { + position.map(i => ( + + )) + } NodeC ) diff --git a/src/views/DemoA.tsx b/src/views/DemoA.tsx index 1df9e13..f491781 100644 --- a/src/views/DemoA.tsx +++ b/src/views/DemoA.tsx @@ -10,7 +10,7 @@ import ReactFlow, { useNodes, useStore, useReactFlow, - useOnSelectionChange + useOnSelectionChange, Position, } from "reactflow" import styles from "./DemoA.module.less" import CustomNode from "./components/CustomNode" @@ -24,6 +24,7 @@ import FlowManager from "@/FlowManager" import { Flow } from "@/types" import FlowDataProvider from "../context/FlowData" import useSetActiveNode from "../hooks/useSetActiveNode" +import { ConnectionLineType } from "@reactflow/core" const initialNodes = [ {id: "1", position: {x: 0, y: 0}, data: {label: "1"}}, @@ -68,6 +69,12 @@ function DemoA() { const onConnect = useCallback( (connection: Connection) => { // 通过connection处理两个节点的handle方向 + const sourcePosition = document.querySelector(`[data-id="${connection.source}"]`)?.getBoundingClientRect() + const targetPosition = document.querySelector(`[data-id="${connection.target}"]`)?.getBoundingClientRect() + + // connection.sourceHandle = `source_${Position.Right}` + // connection.targetHandle = `target_${Position.Top}` + console.log("---", connection, sourcePosition?.left, targetPosition?.left) setEdges((eds) => addEdge(connection, eds)) }, [setEdges], @@ -116,6 +123,11 @@ function DemoA() { return FlowManager.getAllNodes() }, []) + const isValidConnection = useCallback((connection: Connection): boolean => { + return !!(connection.source && connection.target && connection.source !== connection.target); + + }, []) + return (
@@ -124,7 +136,7 @@ function DemoA() { nodesComponent.map(node => { const NodeItem = node.component return ( -
+
onDragStart(event, node.type) } draggable> @@ -150,6 +162,9 @@ function DemoA() { onConnect={ onConnect } nodeTypes={ nodeTypes } edgeTypes={ edgeTypes } + connectionRadius={6} + isValidConnection={isValidConnection} + connectionLineType={ ConnectionLineType.Straight } >