refactor(handles): add connectionStart and connectionEnd handle to store, cleanup

This commit is contained in:
moklick
2023-03-27 12:56:57 +02:00
parent 2fd5319cf2
commit 395a1586c3
9 changed files with 94 additions and 57 deletions
@@ -89,12 +89,17 @@ export function handlePointerDown({
setState({
connectionPosition,
connectionStatus: null,
// connectionNodeId etc will be removed in the next major in favor of connectionStartHandle
connectionNodeId: nodeId,
connectionHandleId: handleId,
connectionHandleType: handleType,
connectionStatus: null,
connectionTargetNodeId: null,
connectionTargetHandleId: null,
connectionStartHandle: {
nodeId,
handleId,
type: handleType,
},
connectionEndHandle: null,
});
onConnectStart?.(event, { nodeId, handleId, handleType });
@@ -141,8 +146,7 @@ export function handlePointerDown({
)
: connectionPosition,
connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
connectionTargetNodeId: connection.target,
connectionTargetHandleId: connection.targetHandle,
connectionEndHandle: result.endHandle,
});
if (!prevClosestHandle && !isValid && !handleDomNode) {
+37 -23
View File
@@ -7,8 +7,7 @@ import { useNodeId } from '../../contexts/NodeIdContext';
import { handlePointerDown } from './handler';
import { getHostForElement, isMouseEvent } from '../../utils';
import { addEdge } from '../../utils/graph';
import { Position } from '../../types';
import type { HandleProps, Connection, ReactFlowState } from '../../types';
import { type HandleProps, type Connection, type ReactFlowState, HandleType, Position } from '../../types';
import { isValidHandle } from './utils';
import { errorMessages } from '../../contants';
@@ -22,6 +21,23 @@ const selector = (s: ReactFlowState) => ({
noPanClassName: s.noPanClassName,
});
const connectingSelector =
(nodeId: string | null, handleId: string | null, type: HandleType) => (state: ReactFlowState) => {
const {
connectionStartHandle: startHandle,
connectionEndHandle: endHandle,
connectionClickStartHandle: clickHandle,
} = state;
return {
connecting:
(startHandle?.nodeId === nodeId && startHandle?.handleId === handleId && startHandle?.type === type) ||
(endHandle?.nodeId === nodeId && endHandle?.handleId === handleId && endHandle?.type === type),
clickConnecting:
clickHandle?.nodeId === nodeId && clickHandle?.handleId === handleId && clickHandle?.type === type,
};
};
const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
(
{
@@ -41,20 +57,17 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
},
ref
) => {
const handleId = id || null;
const isTarget = type === 'target';
const store = useStoreApi();
const nodeId = useNodeId();
const { connectOnClick, noPanClassName } = useStore(selector, shallow);
const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type));
if (!nodeId) {
store.getState().onError?.('010', errorMessages['error010']());
return null;
}
const { connectionStartHandle, connectOnClick, noPanClassName } = useStore(selector, shallow);
const handleId = id || null;
const isTarget = type === 'target';
const onConnectExtended = (params: Connection) => {
const { defaultEdgeOptions, onConnect: onConnectAction, hasDefaultEdges } = store.getState();
@@ -72,6 +85,10 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
};
const onPointerDown = (event: ReactMouseEvent<HTMLDivElement> | ReactTouchEvent<HTMLDivElement>) => {
if (!nodeId) {
return;
}
const isMouseTriggered = isMouseEvent(event);
if (isConnectableStart && ((isMouseTriggered && event.button === 0) || !isMouseTriggered)) {
@@ -98,17 +115,18 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
const {
onClickConnectStart,
onClickConnectEnd,
connectionClickStartHandle,
connectionMode,
isValidConnection: isValidConnectionStore,
} = store.getState();
if (!connectionStartHandle && !isConnectableStart) {
if (!nodeId || (!connectionClickStartHandle && !isConnectableStart)) {
return;
}
if (!connectionStartHandle) {
if (!connectionClickStartHandle) {
onClickConnectStart?.(event, { nodeId, handleId, handleType: type });
store.setState({ connectionStartHandle: { nodeId, type, handleId } });
store.setState({ connectionClickStartHandle: { nodeId, type, handleId } });
return;
}
@@ -122,9 +140,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
type,
},
connectionMode,
connectionStartHandle.nodeId,
connectionStartHandle.handleId || null,
connectionStartHandle.type,
connectionClickStartHandle.nodeId,
connectionClickStartHandle.handleId || null,
connectionClickStartHandle.type,
isValidConnectionHandler,
doc
);
@@ -135,14 +153,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
onClickConnectEnd?.(event as unknown as MouseEvent);
store.setState({ connectionStartHandle: null });
store.setState({ connectionClickStartHandle: null });
};
const connecting =
connectionStartHandle?.nodeId === nodeId &&
connectionStartHandle?.handleId === handleId &&
connectionStartHandle?.type === type;
return (
<div
data-handleid={handleId}
@@ -161,9 +174,10 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
connectable: isConnectable,
connectablestart: isConnectableStart,
connectableend: isConnectableEnd,
connecting,
connecting: clickConnecting,
// this class is used to style the handle when the user is connecting
connectionindicator:
(isConnectable && isConnectableStart && !connecting) || (isConnectableEnd && connecting),
isConnectable && ((isConnectableStart && !connecting) || (isConnectableEnd && connecting)),
},
])}
onMouseDown={onPointerDown}
+10 -2
View File
@@ -1,6 +1,6 @@
import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
import { ConnectionMode, ConnectionStatus } from '../../types';
import { ConnectingHandle, ConnectionMode, ConnectionStatus } from '../../types';
import { getEventPosition, internalsSymbol } from '../../utils';
import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '../../types';
@@ -59,6 +59,7 @@ type Result = {
handleDomNode: Element | null;
isValid: boolean;
connection: Connection;
endHandle: ConnectingHandle | null;
};
const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null };
@@ -70,7 +71,7 @@ export function isValidHandle(
connectionMode: ConnectionMode,
fromNodeId: string,
fromHandleId: string | null,
fromType: string,
fromType: HandleType,
isValidConnection: ValidConnectionFunc,
doc: Document | ShadowRoot
) {
@@ -86,6 +87,7 @@ export function isValidHandle(
handleDomNode: handleToCheck,
isValid: false,
connection: nullConnection,
endHandle: null,
};
if (handleToCheck) {
@@ -113,6 +115,12 @@ export function isValidHandle(
: handleNodeId !== fromNodeId || handleId !== fromHandleId);
if (isValid) {
result.endHandle = {
nodeId: handleNodeId as string,
handleId,
type: handleType as HandleType,
};
result.isValid = isValidConnection(connection);
}
}