Merge pull request #2958 from wbkd/feat/handle-start-connection
feat(handle): add isConnectableStart and isConnectableEnd
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
'@reactflow/background': minor
|
||||||
|
'@reactflow/core': minor
|
||||||
|
'@reactflow/minimap': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Handles: add isConnectableStart and isConnectableEnd props
|
||||||
@@ -6,15 +6,21 @@ import styles from './validation.module.css';
|
|||||||
const selector = (state: ReactFlowState) => ({
|
const selector = (state: ReactFlowState) => ({
|
||||||
connectionPosition: state.connectionPosition,
|
connectionPosition: state.connectionPosition,
|
||||||
connectionStatus: state.connectionStatus,
|
connectionStatus: state.connectionStatus,
|
||||||
connectionNodeId: state.connectionNodeId,
|
connectionStartNodeId: state.connectionStartHandle?.nodeId,
|
||||||
connectionTargetNodeId: state.connectionTargetNodeId,
|
connectionStartHandleType: state.connectionStartHandle?.type,
|
||||||
|
connectionEndNodeId: state.connectionEndHandle?.nodeId,
|
||||||
|
connectionEndHandleType: state.connectionEndHandle?.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
function ConnectionStatus() {
|
function ConnectionStatus() {
|
||||||
const { connectionPosition, connectionStatus, connectionNodeId, connectionTargetNodeId } = useStore(
|
const {
|
||||||
selector,
|
connectionPosition,
|
||||||
shallow
|
connectionStatus,
|
||||||
);
|
connectionStartNodeId,
|
||||||
|
connectionStartHandleType,
|
||||||
|
connectionEndNodeId,
|
||||||
|
connectionEndHandleType,
|
||||||
|
} = useStore(selector, shallow);
|
||||||
|
|
||||||
if (!connectionPosition) {
|
if (!connectionPosition) {
|
||||||
return null;
|
return null;
|
||||||
@@ -22,15 +28,17 @@ function ConnectionStatus() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.connectionstatus}>
|
<div className={styles.connectionstatus}>
|
||||||
{connectionNodeId ? (
|
{connectionStartNodeId ? (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<strong>connection info</strong>
|
<strong>connection info</strong>
|
||||||
</div>
|
</div>
|
||||||
<div>position: {JSON.stringify(connectionPosition)}</div>
|
<div>position: {JSON.stringify(connectionPosition)}</div>
|
||||||
<div>status: {JSON.stringify(connectionStatus)}</div>
|
<div>status: {connectionStatus}</div>
|
||||||
<div>source node id: {JSON.stringify(connectionNodeId)}</div>
|
<div>from node id: {connectionStartNodeId}</div>
|
||||||
<div>target node id: {JSON.stringify(connectionTargetNodeId)}</div>
|
<div>from handle type: {connectionStartHandleType}</div>
|
||||||
|
<div>to node id: {connectionEndNodeId}</div>
|
||||||
|
<div>to handle type: {connectionEndHandleType}</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
'no connection data'
|
'no connection data'
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const CustomInput: FC<NodeProps> = () => (
|
|||||||
|
|
||||||
const CustomNode: FC<NodeProps> = ({ id }) => (
|
const CustomNode: FC<NodeProps> = ({ id }) => (
|
||||||
<>
|
<>
|
||||||
<Handle type="target" position={Position.Left} />
|
<Handle type="target" position={Position.Left} isConnectableStart={false} />
|
||||||
<div>{id}</div>
|
<div>{id}</div>
|
||||||
<Handle type="source" position={Position.Right} />
|
<Handle type="source" position={Position.Right} />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -89,12 +89,17 @@ export function handlePointerDown({
|
|||||||
|
|
||||||
setState({
|
setState({
|
||||||
connectionPosition,
|
connectionPosition,
|
||||||
|
connectionStatus: null,
|
||||||
|
// connectionNodeId etc will be removed in the next major in favor of connectionStartHandle
|
||||||
connectionNodeId: nodeId,
|
connectionNodeId: nodeId,
|
||||||
connectionHandleId: handleId,
|
connectionHandleId: handleId,
|
||||||
connectionHandleType: handleType,
|
connectionHandleType: handleType,
|
||||||
connectionStatus: null,
|
connectionStartHandle: {
|
||||||
connectionTargetNodeId: null,
|
nodeId,
|
||||||
connectionTargetHandleId: null,
|
handleId,
|
||||||
|
type: handleType,
|
||||||
|
},
|
||||||
|
connectionEndHandle: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
onConnectStart?.(event, { nodeId, handleId, handleType });
|
onConnectStart?.(event, { nodeId, handleId, handleType });
|
||||||
@@ -141,8 +146,7 @@ export function handlePointerDown({
|
|||||||
)
|
)
|
||||||
: connectionPosition,
|
: connectionPosition,
|
||||||
connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
|
connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid),
|
||||||
connectionTargetNodeId: connection.target,
|
connectionEndHandle: result.endHandle,
|
||||||
connectionTargetHandleId: connection.targetHandle,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!prevClosestHandle && !isValid && !handleDomNode) {
|
if (!prevClosestHandle && !isValid && !handleDomNode) {
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import { useNodeId } from '../../contexts/NodeIdContext';
|
|||||||
import { handlePointerDown } from './handler';
|
import { handlePointerDown } from './handler';
|
||||||
import { getHostForElement, isMouseEvent } from '../../utils';
|
import { getHostForElement, isMouseEvent } from '../../utils';
|
||||||
import { addEdge } from '../../utils/graph';
|
import { addEdge } from '../../utils/graph';
|
||||||
import { Position } from '../../types';
|
import { type HandleProps, type Connection, type ReactFlowState, HandleType, Position } from '../../types';
|
||||||
import type { HandleProps, Connection, ReactFlowState } from '../../types';
|
|
||||||
import { isValidHandle } from './utils';
|
import { isValidHandle } from './utils';
|
||||||
import { errorMessages } from '../../contants';
|
import { errorMessages } from '../../contants';
|
||||||
|
|
||||||
@@ -22,6 +21,23 @@ const selector = (s: ReactFlowState) => ({
|
|||||||
noPanClassName: s.noPanClassName,
|
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>(
|
const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -29,6 +45,8 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
position = Position.Top,
|
position = Position.Top,
|
||||||
isValidConnection,
|
isValidConnection,
|
||||||
isConnectable = true,
|
isConnectable = true,
|
||||||
|
isConnectableStart = true,
|
||||||
|
isConnectableEnd = true,
|
||||||
id,
|
id,
|
||||||
onConnect,
|
onConnect,
|
||||||
children,
|
children,
|
||||||
@@ -39,20 +57,17 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
|
const handleId = id || null;
|
||||||
|
const isTarget = type === 'target';
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const nodeId = useNodeId();
|
const nodeId = useNodeId();
|
||||||
|
const { connectOnClick, noPanClassName } = useStore(selector, shallow);
|
||||||
|
const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type));
|
||||||
|
|
||||||
if (!nodeId) {
|
if (!nodeId) {
|
||||||
store.getState().onError?.('010', errorMessages['error010']());
|
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 onConnectExtended = (params: Connection) => {
|
||||||
const { defaultEdgeOptions, onConnect: onConnectAction, hasDefaultEdges } = store.getState();
|
const { defaultEdgeOptions, onConnect: onConnectAction, hasDefaultEdges } = store.getState();
|
||||||
|
|
||||||
@@ -70,9 +85,13 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onPointerDown = (event: ReactMouseEvent<HTMLDivElement> | ReactTouchEvent<HTMLDivElement>) => {
|
const onPointerDown = (event: ReactMouseEvent<HTMLDivElement> | ReactTouchEvent<HTMLDivElement>) => {
|
||||||
|
if (!nodeId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const isMouseTriggered = isMouseEvent(event);
|
const isMouseTriggered = isMouseEvent(event);
|
||||||
|
|
||||||
if ((isMouseTriggered && event.button === 0) || !isMouseTriggered) {
|
if (isConnectableStart && ((isMouseTriggered && event.button === 0) || !isMouseTriggered)) {
|
||||||
handlePointerDown({
|
handlePointerDown({
|
||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
@@ -96,12 +115,18 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
const {
|
const {
|
||||||
onClickConnectStart,
|
onClickConnectStart,
|
||||||
onClickConnectEnd,
|
onClickConnectEnd,
|
||||||
|
connectionClickStartHandle,
|
||||||
connectionMode,
|
connectionMode,
|
||||||
isValidConnection: isValidConnectionStore,
|
isValidConnection: isValidConnectionStore,
|
||||||
} = store.getState();
|
} = store.getState();
|
||||||
if (!connectionStartHandle) {
|
|
||||||
|
if (!nodeId || (!connectionClickStartHandle && !isConnectableStart)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!connectionClickStartHandle) {
|
||||||
onClickConnectStart?.(event, { nodeId, handleId, handleType: type });
|
onClickConnectStart?.(event, { nodeId, handleId, handleType: type });
|
||||||
store.setState({ connectionStartHandle: { nodeId, type, handleId } });
|
store.setState({ connectionClickStartHandle: { nodeId, type, handleId } });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,9 +140,9 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
type,
|
type,
|
||||||
},
|
},
|
||||||
connectionMode,
|
connectionMode,
|
||||||
connectionStartHandle.nodeId,
|
connectionClickStartHandle.nodeId,
|
||||||
connectionStartHandle.handleId || null,
|
connectionClickStartHandle.handleId || null,
|
||||||
connectionStartHandle.type,
|
connectionClickStartHandle.type,
|
||||||
isValidConnectionHandler,
|
isValidConnectionHandler,
|
||||||
doc
|
doc
|
||||||
);
|
);
|
||||||
@@ -128,7 +153,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
|
|
||||||
onClickConnectEnd?.(event as unknown as MouseEvent);
|
onClickConnectEnd?.(event as unknown as MouseEvent);
|
||||||
|
|
||||||
store.setState({ connectionStartHandle: null });
|
store.setState({ connectionClickStartHandle: null });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -147,10 +172,12 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
|||||||
source: !isTarget,
|
source: !isTarget,
|
||||||
target: isTarget,
|
target: isTarget,
|
||||||
connectable: isConnectable,
|
connectable: isConnectable,
|
||||||
connecting:
|
connectablestart: isConnectableStart,
|
||||||
connectionStartHandle?.nodeId === nodeId &&
|
connectableend: isConnectableEnd,
|
||||||
connectionStartHandle?.handleId === handleId &&
|
connecting: clickConnecting,
|
||||||
connectionStartHandle?.type === type,
|
// this class is used to style the handle when the user is connecting
|
||||||
|
connectionindicator:
|
||||||
|
isConnectable && ((isConnectableStart && !connecting) || (isConnectableEnd && connecting)),
|
||||||
},
|
},
|
||||||
])}
|
])}
|
||||||
onMouseDown={onPointerDown}
|
onMouseDown={onPointerDown}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react';
|
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 { getEventPosition, internalsSymbol } from '../../utils';
|
||||||
import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '../../types';
|
import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '../../types';
|
||||||
|
|
||||||
@@ -59,6 +59,7 @@ type Result = {
|
|||||||
handleDomNode: Element | null;
|
handleDomNode: Element | null;
|
||||||
isValid: boolean;
|
isValid: boolean;
|
||||||
connection: Connection;
|
connection: Connection;
|
||||||
|
endHandle: ConnectingHandle | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null };
|
const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null };
|
||||||
@@ -70,7 +71,7 @@ export function isValidHandle(
|
|||||||
connectionMode: ConnectionMode,
|
connectionMode: ConnectionMode,
|
||||||
fromNodeId: string,
|
fromNodeId: string,
|
||||||
fromHandleId: string | null,
|
fromHandleId: string | null,
|
||||||
fromType: string,
|
fromType: HandleType,
|
||||||
isValidConnection: ValidConnectionFunc,
|
isValidConnection: ValidConnectionFunc,
|
||||||
doc: Document | ShadowRoot
|
doc: Document | ShadowRoot
|
||||||
) {
|
) {
|
||||||
@@ -86,12 +87,15 @@ export function isValidHandle(
|
|||||||
handleDomNode: handleToCheck,
|
handleDomNode: handleToCheck,
|
||||||
isValid: false,
|
isValid: false,
|
||||||
connection: nullConnection,
|
connection: nullConnection,
|
||||||
|
endHandle: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (handleToCheck) {
|
if (handleToCheck) {
|
||||||
const handleType = getHandleType(undefined, handleToCheck);
|
const handleType = getHandleType(undefined, handleToCheck);
|
||||||
const handleNodeId = handleToCheck.getAttribute('data-nodeid');
|
const handleNodeId = handleToCheck.getAttribute('data-nodeid');
|
||||||
const handleId = handleToCheck.getAttribute('data-handleid');
|
const handleId = handleToCheck.getAttribute('data-handleid');
|
||||||
|
const connectable = handleToCheck.classList.contains('connectable');
|
||||||
|
const connectableEnd = handleToCheck.classList.contains('connectableend');
|
||||||
|
|
||||||
const connection: Connection = {
|
const connection: Connection = {
|
||||||
source: isTarget ? handleNodeId : fromNodeId,
|
source: isTarget ? handleNodeId : fromNodeId,
|
||||||
@@ -102,14 +106,21 @@ export function isValidHandle(
|
|||||||
|
|
||||||
result.connection = connection;
|
result.connection = connection;
|
||||||
|
|
||||||
|
const isConnectable = connectable && connectableEnd;
|
||||||
// in strict mode we don't allow target to target or source to source connections
|
// in strict mode we don't allow target to target or source to source connections
|
||||||
const isValid =
|
const isValid =
|
||||||
handleToCheck.classList.contains('connectable') &&
|
isConnectable &&
|
||||||
(connectionMode === ConnectionMode.Strict
|
(connectionMode === ConnectionMode.Strict
|
||||||
? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target')
|
? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target')
|
||||||
: handleNodeId !== fromNodeId || handleId !== fromHandleId);
|
: handleNodeId !== fromNodeId || handleId !== fromHandleId);
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
|
result.endHandle = {
|
||||||
|
nodeId: handleNodeId as string,
|
||||||
|
handleId,
|
||||||
|
type: handleType as HandleType,
|
||||||
|
};
|
||||||
|
|
||||||
result.isValid = isValidConnection(connection);
|
result.isValid = isValidConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,8 +275,8 @@ const createRFStore = () =>
|
|||||||
connectionHandleId: initialState.connectionHandleId,
|
connectionHandleId: initialState.connectionHandleId,
|
||||||
connectionHandleType: initialState.connectionHandleType,
|
connectionHandleType: initialState.connectionHandleType,
|
||||||
connectionStatus: initialState.connectionStatus,
|
connectionStatus: initialState.connectionStatus,
|
||||||
connectionTargetNodeId: initialState.connectionTargetNodeId,
|
connectionStartHandle: initialState.connectionStartHandle,
|
||||||
connectionTargetHandleId: initialState.connectionTargetHandleId,
|
connectionEndHandle: initialState.connectionEndHandle,
|
||||||
}),
|
}),
|
||||||
reset: () => set({ ...initialState }),
|
reset: () => set({ ...initialState }),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ const initialState: ReactFlowStore = {
|
|||||||
connectionNodeId: null,
|
connectionNodeId: null,
|
||||||
connectionHandleId: null,
|
connectionHandleId: null,
|
||||||
connectionHandleType: 'source',
|
connectionHandleType: 'source',
|
||||||
connectionTargetNodeId: null,
|
|
||||||
connectionTargetHandleId: null,
|
|
||||||
connectionPosition: { x: 0, y: 0 },
|
connectionPosition: { x: 0, y: 0 },
|
||||||
connectionStatus: null,
|
connectionStatus: null,
|
||||||
connectionMode: ConnectionMode.Strict,
|
connectionMode: ConnectionMode.Strict,
|
||||||
@@ -57,6 +55,8 @@ const initialState: ReactFlowStore = {
|
|||||||
multiSelectionActive: false,
|
multiSelectionActive: false,
|
||||||
|
|
||||||
connectionStartHandle: null,
|
connectionStartHandle: null,
|
||||||
|
connectionEndHandle: null,
|
||||||
|
connectionClickStartHandle: null,
|
||||||
connectOnClick: true,
|
connectOnClick: true,
|
||||||
|
|
||||||
ariaLiveMessage: '',
|
ariaLiveMessage: '',
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
min-width: 5px;
|
min-width: 5px;
|
||||||
min-height: 5px;
|
min-height: 5px;
|
||||||
|
|
||||||
&.connectable {
|
&.connectionindicator {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import type {
|
|||||||
NodeOrigin,
|
NodeOrigin,
|
||||||
} from './nodes';
|
} from './nodes';
|
||||||
import type { Edge, EdgeProps, WrapEdgeProps } from './edges';
|
import type { Edge, EdgeProps, WrapEdgeProps } from './edges';
|
||||||
import type { HandleType, StartHandle } from './handles';
|
import type { HandleType, ConnectingHandle } from './handles';
|
||||||
import type { DefaultEdgeOptions } from '.';
|
import type { DefaultEdgeOptions } from '.';
|
||||||
import type { ReactFlowInstance } from './instance';
|
import type { ReactFlowInstance } from './instance';
|
||||||
|
|
||||||
@@ -167,10 +167,9 @@ export type ReactFlowStore = {
|
|||||||
userSelectionActive: boolean;
|
userSelectionActive: boolean;
|
||||||
userSelectionRect: SelectionRect | null;
|
userSelectionRect: SelectionRect | null;
|
||||||
|
|
||||||
|
// @todo remove this in next major version in favor of connectionStartHandle
|
||||||
connectionNodeId: string | null;
|
connectionNodeId: string | null;
|
||||||
connectionHandleId: string | null;
|
connectionHandleId: string | null;
|
||||||
connectionTargetNodeId: string | null;
|
|
||||||
connectionTargetHandleId: string | null;
|
|
||||||
connectionHandleType: HandleType | null;
|
connectionHandleType: HandleType | null;
|
||||||
connectionPosition: XYPosition;
|
connectionPosition: XYPosition;
|
||||||
connectionStatus: ConnectionStatus | null;
|
connectionStatus: ConnectionStatus | null;
|
||||||
@@ -188,7 +187,10 @@ export type ReactFlowStore = {
|
|||||||
|
|
||||||
multiSelectionActive: boolean;
|
multiSelectionActive: boolean;
|
||||||
|
|
||||||
connectionStartHandle: StartHandle | null;
|
connectionStartHandle: ConnectingHandle | null;
|
||||||
|
connectionEndHandle: ConnectingHandle | null;
|
||||||
|
// @todo this is only used for the click connection - we might remove this in the next major version
|
||||||
|
connectionClickStartHandle: ConnectingHandle | null;
|
||||||
|
|
||||||
onNodeDragStart?: NodeDragHandler;
|
onNodeDragStart?: NodeDragHandler;
|
||||||
onNodeDrag?: NodeDragHandler;
|
onNodeDrag?: NodeDragHandler;
|
||||||
|
|||||||
@@ -2,22 +2,25 @@ import type { XYPosition, Position, Dimensions, OnConnect, Connection } from '.'
|
|||||||
|
|
||||||
export type HandleType = 'source' | 'target';
|
export type HandleType = 'source' | 'target';
|
||||||
|
|
||||||
export interface HandleElement extends XYPosition, Dimensions {
|
export type HandleElement = XYPosition &
|
||||||
id?: string | null;
|
Dimensions & {
|
||||||
position: Position;
|
id?: string | null;
|
||||||
}
|
position: Position;
|
||||||
|
};
|
||||||
|
|
||||||
export interface StartHandle {
|
export type ConnectingHandle = {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
type: HandleType;
|
type: HandleType;
|
||||||
handleId?: string | null;
|
handleId?: string | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface HandleProps {
|
export type HandleProps = {
|
||||||
type: HandleType;
|
type: HandleType;
|
||||||
position: Position;
|
position: Position;
|
||||||
isConnectable?: boolean;
|
isConnectable?: boolean;
|
||||||
|
isConnectableStart?: boolean;
|
||||||
|
isConnectableEnd?: boolean;
|
||||||
onConnect?: OnConnect;
|
onConnect?: OnConnect;
|
||||||
isValidConnection?: (connection: Connection) => boolean;
|
isValidConnection?: (connection: Connection) => boolean;
|
||||||
id?: string;
|
id?: string;
|
||||||
}
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user