refactor(connection): cleanup
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port 3000 --open",
|
||||
"dev": "vite --port 3000 --open --host",
|
||||
"serve": "vite serve --port 3000",
|
||||
"build": "vite build",
|
||||
"test:dev": "cypress open",
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
||||
import { StoreApi } from 'zustand';
|
||||
|
||||
import { getHostForElement, calcAutoPan, getEventPosition, isMouseEvent } from '../../utils';
|
||||
import { getHostForElement, calcAutoPan, getEventPosition } from '../../utils';
|
||||
import type { OnConnect, HandleType, ReactFlowState } from '../../types';
|
||||
import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph';
|
||||
import { ConnectionHandle, getClosestHandle, getHandleLookup, isValidHandle, ValidConnectionFunc } from './utils';
|
||||
|
||||
function resetRecentHandle(handleDomNode: Element): void {
|
||||
handleDomNode?.classList.remove('react-flow__handle-valid');
|
||||
handleDomNode?.classList.remove('react-flow__handle-connecting');
|
||||
}
|
||||
import {
|
||||
ConnectionHandle,
|
||||
getClosestHandle,
|
||||
getHandleLookup,
|
||||
getHandleType,
|
||||
isValidHandle,
|
||||
resetRecentHandle,
|
||||
ValidConnectionFunc,
|
||||
} from './utils';
|
||||
|
||||
export function handlePointerDown({
|
||||
event,
|
||||
@@ -20,7 +23,7 @@ export function handlePointerDown({
|
||||
getState,
|
||||
setState,
|
||||
isValidConnection,
|
||||
elementEdgeUpdaterType,
|
||||
edgeUpdaterType,
|
||||
onEdgeUpdateEnd,
|
||||
}: {
|
||||
event: ReactMouseEvent | ReactTouchEvent;
|
||||
@@ -31,27 +34,34 @@ export function handlePointerDown({
|
||||
getState: StoreApi<ReactFlowState>['getState'];
|
||||
setState: StoreApi<ReactFlowState>['setState'];
|
||||
isValidConnection: ValidConnectionFunc;
|
||||
elementEdgeUpdaterType?: HandleType;
|
||||
edgeUpdaterType?: HandleType;
|
||||
onEdgeUpdateEnd?: (evt: MouseEvent | TouchEvent) => void;
|
||||
}): void {
|
||||
// when react-flow is used inside a shadow root we can't use document
|
||||
const doc = getHostForElement(event.target as HTMLElement);
|
||||
const { connectionMode, domNode, autoPanOnConnect, connectionRadius, onConnectStart, onConnectEnd, panBy, getNodes } =
|
||||
getState();
|
||||
const {
|
||||
connectionMode,
|
||||
domNode,
|
||||
autoPanOnConnect,
|
||||
connectionRadius,
|
||||
onConnectStart,
|
||||
onConnectEnd,
|
||||
panBy,
|
||||
getNodes,
|
||||
cancelConnection,
|
||||
} = getState();
|
||||
let autoPanId = 0;
|
||||
let prevClosestHandle: ConnectionHandle | null;
|
||||
|
||||
const { clientX, clientY } = isMouseEvent(event) ? event : event.touches[0]!;
|
||||
const clickedElement = doc?.elementFromPoint(clientX, clientY);
|
||||
const elementIsTarget = clickedElement?.classList.contains('target');
|
||||
const elementIsSource = clickedElement?.classList.contains('source');
|
||||
const { x, y } = getEventPosition(event);
|
||||
const clickedHandle = doc?.elementFromPoint(x, y);
|
||||
const handleType = getHandleType(edgeUpdaterType, clickedHandle);
|
||||
const containerBounds = domNode?.getBoundingClientRect();
|
||||
|
||||
if (!domNode || (!elementIsTarget && !elementIsSource && !elementEdgeUpdaterType)) {
|
||||
if (!containerBounds || !handleType) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleType = elementEdgeUpdaterType ? elementEdgeUpdaterType : elementIsTarget ? 'target' : 'source';
|
||||
const containerBounds = domNode.getBoundingClientRect();
|
||||
let prevActiveHandle: Element;
|
||||
let connectionPosition = getEventPosition(event, containerBounds);
|
||||
let autoPanStarted = false;
|
||||
@@ -154,17 +164,13 @@ export function handlePointerDown({
|
||||
|
||||
onConnectEnd?.(event);
|
||||
|
||||
if (elementEdgeUpdaterType) {
|
||||
if (edgeUpdaterType) {
|
||||
onEdgeUpdateEnd?.(event);
|
||||
}
|
||||
|
||||
resetRecentHandle(prevActiveHandle);
|
||||
|
||||
setState({
|
||||
connectionNodeId: null,
|
||||
connectionHandleId: null,
|
||||
connectionHandleType: null,
|
||||
});
|
||||
cancelConnection();
|
||||
|
||||
doc.removeEventListener('mousemove', onPointerMove as EventListener);
|
||||
doc.removeEventListener('mouseup', onPointerUp as EventListener);
|
||||
|
||||
@@ -68,9 +68,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
};
|
||||
|
||||
const onPointerDown = (event: ReactMouseEvent<HTMLDivElement> | ReactTouchEvent<HTMLDivElement>) => {
|
||||
const isMouse = isMouseEvent(event);
|
||||
const isMouseTriggered = isMouseEvent(event);
|
||||
|
||||
if ((isMouse && event.button === 0) || 'touches' in event) {
|
||||
if ((isMouseTriggered && event.button === 0) || !isMouseTriggered) {
|
||||
handlePointerDown({
|
||||
event,
|
||||
handleId,
|
||||
@@ -83,7 +83,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
});
|
||||
}
|
||||
|
||||
if (isMouse) {
|
||||
if (isMouseTriggered) {
|
||||
onMouseDown?.(event);
|
||||
} else {
|
||||
onTouchStart?.(event);
|
||||
|
||||
@@ -132,3 +132,23 @@ export function getHandleLookup({ nodes, nodeId, handleId, handleType }: GetHand
|
||||
return res;
|
||||
}, []);
|
||||
}
|
||||
|
||||
export function getHandleType(
|
||||
edgeUpdaterType: HandleType | undefined,
|
||||
handleDomNode: Element | null
|
||||
): HandleType | null {
|
||||
if (edgeUpdaterType) {
|
||||
return edgeUpdaterType;
|
||||
} else if (handleDomNode?.classList.contains('target')) {
|
||||
return 'target';
|
||||
} else if (handleDomNode?.classList.contains('source')) {
|
||||
return 'source';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function resetRecentHandle(handleDomNode: Element): void {
|
||||
handleDomNode?.classList.remove('react-flow__handle-valid');
|
||||
handleDomNode?.classList.remove('react-flow__handle-connecting');
|
||||
}
|
||||
|
||||
@@ -273,6 +273,7 @@ const createRFStore = () =>
|
||||
set({
|
||||
connectionNodeId: initialState.connectionNodeId,
|
||||
connectionHandleId: initialState.connectionHandleId,
|
||||
connectionHandleType: initialState.connectionHandleType,
|
||||
}),
|
||||
reset: () => set({ ...initialState }),
|
||||
}));
|
||||
|
||||
@@ -122,14 +122,14 @@ export const isMouseEvent = (
|
||||
|
||||
export const getEventPosition = (
|
||||
event: MouseEvent | ReactMouseEvent | TouchEvent | ReactTouchEvent,
|
||||
bounds: DOMRect
|
||||
bounds?: DOMRect
|
||||
) => {
|
||||
const isMouse = isMouseEvent(event);
|
||||
const evtX = isMouse ? event.clientX : event.touches?.[0].clientX;
|
||||
const evtY = isMouse ? event.clientY : event.touches?.[0].clientY;
|
||||
const isMouseTriggered = isMouseEvent(event);
|
||||
const evtX = isMouseTriggered ? event.clientX : event.touches?.[0].clientX;
|
||||
const evtY = isMouseTriggered ? event.clientY : event.touches?.[0].clientY;
|
||||
|
||||
return {
|
||||
x: evtX - bounds.left,
|
||||
y: evtY - bounds.top,
|
||||
x: evtX - (bounds?.left ?? 0),
|
||||
y: evtY - (bounds?.top ?? 0),
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user