fix(ios): connection error + dont snap invalid connection lines
This commit is contained in:
@@ -24,10 +24,10 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.validationflow :global .react-flow__handle-connecting {
|
||||
.validationflow :global .connecting {
|
||||
background: #ff6060;
|
||||
}
|
||||
|
||||
.validationflow :global .react-flow__handle-valid {
|
||||
.validationflow :global .valid {
|
||||
background: #55dd99;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } fro
|
||||
import { StoreApi } from 'zustand';
|
||||
|
||||
import { getHostForElement, calcAutoPan, getEventPosition } from '../../utils';
|
||||
import type { OnConnect, HandleType, ReactFlowState } from '../../types';
|
||||
import type { OnConnect, HandleType, ReactFlowState, Connection } from '../../types';
|
||||
import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph';
|
||||
import {
|
||||
ConnectionHandle,
|
||||
@@ -65,6 +65,8 @@ export function handlePointerDown({
|
||||
let prevActiveHandle: Element;
|
||||
let connectionPosition = getEventPosition(event, containerBounds);
|
||||
let autoPanStarted = false;
|
||||
let connection: Connection | null = null;
|
||||
let isValid = false;
|
||||
|
||||
const handleLookup = getHandleLookup({
|
||||
nodes: getNodes(),
|
||||
@@ -108,23 +110,7 @@ export function handlePointerDown({
|
||||
autoPanStarted = true;
|
||||
}
|
||||
|
||||
setState({
|
||||
connectionPosition: prevClosestHandle
|
||||
? rendererPointToPoint(
|
||||
{
|
||||
x: prevClosestHandle.x,
|
||||
y: prevClosestHandle.y,
|
||||
},
|
||||
transform
|
||||
)
|
||||
: connectionPosition,
|
||||
});
|
||||
|
||||
if (!prevClosestHandle) {
|
||||
return resetRecentHandle(prevActiveHandle);
|
||||
}
|
||||
|
||||
const { connection, handleDomNode, isValid } = isValidHandle(
|
||||
const { handleDomNode, ...result } = isValidHandle(
|
||||
event,
|
||||
prevClosestHandle,
|
||||
connectionMode,
|
||||
@@ -135,33 +121,39 @@ export function handlePointerDown({
|
||||
doc
|
||||
);
|
||||
|
||||
setState({
|
||||
connectionPosition:
|
||||
prevClosestHandle && isValid
|
||||
? rendererPointToPoint(
|
||||
{
|
||||
x: prevClosestHandle.x,
|
||||
y: prevClosestHandle.y,
|
||||
},
|
||||
transform
|
||||
)
|
||||
: connectionPosition,
|
||||
});
|
||||
|
||||
if (!prevClosestHandle) {
|
||||
return resetRecentHandle(prevActiveHandle);
|
||||
}
|
||||
|
||||
connection = result.connection;
|
||||
isValid = result.isValid;
|
||||
|
||||
if (connection.source !== connection.target && handleDomNode) {
|
||||
resetRecentHandle(prevActiveHandle);
|
||||
prevActiveHandle = handleDomNode;
|
||||
handleDomNode.classList.add('react-flow__handle-connecting');
|
||||
// @todo: remove the old class names "react-flow__handle-" in the next major version
|
||||
handleDomNode.classList.add('connecting', 'react-flow__handle-connecting');
|
||||
handleDomNode.classList.toggle('valid', isValid);
|
||||
handleDomNode.classList.toggle('react-flow__handle-valid', isValid);
|
||||
}
|
||||
}
|
||||
|
||||
function onPointerUp(event: MouseEvent | TouchEvent) {
|
||||
cancelAnimationFrame(autoPanId);
|
||||
autoPanStarted = false;
|
||||
|
||||
if (prevClosestHandle) {
|
||||
const { connection, isValid } = isValidHandle(
|
||||
event,
|
||||
prevClosestHandle,
|
||||
connectionMode,
|
||||
nodeId,
|
||||
handleId,
|
||||
isTarget ? 'target' : 'source',
|
||||
isValidConnection,
|
||||
doc
|
||||
);
|
||||
|
||||
if (isValid) {
|
||||
onConnect?.(connection);
|
||||
}
|
||||
if (connection && isValid) {
|
||||
onConnect?.(connection);
|
||||
}
|
||||
|
||||
onConnectEnd?.(event);
|
||||
@@ -171,8 +163,11 @@ export function handlePointerDown({
|
||||
}
|
||||
|
||||
resetRecentHandle(prevActiveHandle);
|
||||
|
||||
cancelConnection();
|
||||
cancelAnimationFrame(autoPanId);
|
||||
autoPanStarted = false;
|
||||
isValid = false;
|
||||
connection = null;
|
||||
|
||||
doc.removeEventListener('mousemove', onPointerMove as EventListener);
|
||||
doc.removeEventListener('mouseup', onPointerUp as EventListener);
|
||||
|
||||
@@ -61,10 +61,12 @@ type Result = {
|
||||
connection: Connection;
|
||||
};
|
||||
|
||||
const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null };
|
||||
|
||||
// checks if and returns connection in fom of an object { source: 123, target: 312 }
|
||||
export function isValidHandle(
|
||||
event: MouseEvent | TouchEvent | ReactMouseEvent | ReactTouchEvent,
|
||||
handle: Pick<ConnectionHandle, 'nodeId' | 'id' | 'type'>,
|
||||
handle: Pick<ConnectionHandle, 'nodeId' | 'id' | 'type'> | null,
|
||||
connectionMode: ConnectionMode,
|
||||
fromNodeId: string,
|
||||
fromHandleId: string | null,
|
||||
@@ -72,6 +74,14 @@ export function isValidHandle(
|
||||
isValidConnection: ValidConnectionFunc,
|
||||
doc: Document | ShadowRoot
|
||||
) {
|
||||
if (!handle) {
|
||||
return {
|
||||
handleDomNode: null,
|
||||
isValid: false,
|
||||
connection: nullConnection,
|
||||
};
|
||||
}
|
||||
|
||||
const isTarget = fromType === 'target';
|
||||
const handleDomNode = doc.querySelector(
|
||||
`.react-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]`
|
||||
@@ -83,7 +93,7 @@ export function isValidHandle(
|
||||
const result: Result = {
|
||||
handleDomNode: handleToCheck,
|
||||
isValid: false,
|
||||
connection: { source: null, target: null, sourceHandle: null, targetHandle: null },
|
||||
connection: nullConnection,
|
||||
};
|
||||
|
||||
if (handleToCheck) {
|
||||
@@ -155,6 +165,5 @@ export function getHandleType(
|
||||
}
|
||||
|
||||
export function resetRecentHandle(handleDomNode: Element): void {
|
||||
handleDomNode?.classList.remove('react-flow__handle-valid');
|
||||
handleDomNode?.classList.remove('react-flow__handle-connecting');
|
||||
handleDomNode?.classList.remove('valid', 'connecting', 'react-flow__handle-valid', 'react-flow__handle-connecting');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user