fix(ios): connection error + dont snap invalid connection lines

This commit is contained in:
moklick
2023-02-03 20:40:32 +01:00
parent 1998a3b088
commit c48efe969f
3 changed files with 48 additions and 44 deletions
@@ -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;
} }
+33 -38
View File
@@ -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);
+13 -4
View File
@@ -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');
} }