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