Merge pull request #4519 from xyflow/fix-connection-snapping

Fix connection snapping & update internal easy-connect example
This commit is contained in:
Moritz Klack
2024-08-12 17:19:05 +02:00
committed by GitHub
6 changed files with 31 additions and 23 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@xyflow/system': patch
---
fix(connection) snapped position not updated correctly
@@ -1,13 +1,10 @@
import { Handle, NodeProps, Position, ReactFlowState, useStore } from '@xyflow/react'; import { Handle, NodeProps, Position, useConnection } from '@xyflow/react';
const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionStartHandle?.nodeId;
export default function CustomNode({ id }: NodeProps) { export default function CustomNode({ id }: NodeProps) {
const connectionNodeId = useStore(connectionNodeIdSelector); const connection = useConnection();
const isConnecting = !!connectionNodeId;
const isTarget = connectionNodeId && connectionNodeId !== id; const isTarget = connection.inProgress && connection.fromNode.id !== id;
const targetHandleStyle = { zIndex: isTarget ? 3 : 1 };
const label = isTarget ? 'Drop here' : 'Drag to connect'; const label = isTarget ? 'Drop here' : 'Drag to connect';
return ( return (
@@ -19,17 +16,13 @@ export default function CustomNode({ id }: NodeProps) {
backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6', backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6',
}} }}
> >
{!isConnecting && ( {/* If handles are conditionally rendered and not present initially, you need to update the node internals https://reactflow.dev/docs/api/hooks/use-update-node-internals/ */}
<Handle className="customHandle" style={{ zIndex: 2 }} position={Position.Right} type="source" /> {/* In this case we don't need to use useUpdateNodeInternals, since !connection.inProgress is true at the beginning and all handles are rendered initially. */}
)} {!connection.inProgress && <Handle className="customHandle" position={Position.Right} type="source" id="src" />}
<Handle {/* We want to disable the target handle, if the connection was started from this node */}
className="customHandle" {/* {(!connection.inProgress || isTarget) && ( */}
style={targetHandleStyle} <Handle className="customHandle" position={Position.Left} type="target" isConnectableStart={false} id="trgt" />
position={Position.Left}
type="target"
isConnectableStart={false}
/>
{label} {label}
</div> </div>
</div> </div>
@@ -1,5 +1,4 @@
import { useCallback } from 'react'; import { EdgeProps, getStraightPath, useInternalNode } from '@xyflow/react';
import { useStore, getStraightPath, EdgeProps, useInternalNode } from '@xyflow/react';
import { getEdgeParams } from './utils.js'; import { getEdgeParams } from './utils.js';
@@ -1,5 +1,15 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { ReactFlow, Node, Edge, addEdge, useNodesState, useEdgesState, MarkerType, OnConnect } from '@xyflow/react'; import {
ReactFlow,
Node,
Edge,
addEdge,
useNodesState,
useEdgesState,
MarkerType,
OnConnect,
ConnectionMode,
} from '@xyflow/react';
import CustomNode from './CustomNode'; import CustomNode from './CustomNode';
import FloatingEdge from './FloatingEdge'; import FloatingEdge from './FloatingEdge';
@@ -19,12 +19,11 @@ function getNodeIntersection(intersectionNode: InternalNode, targetNode: Interna
const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h); const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h);
const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h); const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h);
const a = 1 / (Math.abs(xx1) + Math.abs(yy1)); const a = 1 / (Math.abs(xx1) + Math.abs(yy1) || 1);
const xx3 = a * xx1; const xx3 = a * xx1;
const yy3 = a * yy1; const yy3 = a * yy1;
const x = w * (xx3 + yy3) + x2; const x = w * (xx3 + yy3) + x2;
const y = h * (-xx3 + yy3) + y2; const y = h * (-xx3 + yy3) + y2;
return { x, y }; return { x, y };
} }
+3 -1
View File
@@ -175,7 +175,9 @@ function onPointerDown(
newConnection.toHandle && newConnection.toHandle &&
previousConnection.toHandle.type === newConnection.toHandle.type && previousConnection.toHandle.type === newConnection.toHandle.type &&
previousConnection.toHandle.nodeId === newConnection.toHandle.nodeId && previousConnection.toHandle.nodeId === newConnection.toHandle.nodeId &&
previousConnection.toHandle.id === newConnection.toHandle.id previousConnection.toHandle.id === newConnection.toHandle.id &&
previousConnection.to.x === newConnection.to.x &&
previousConnection.to.y === newConnection.to.y
) { ) {
return; return;
} }