diff --git a/packages/system/src/types/handles.ts b/packages/system/src/types/handles.ts index be0ee608..c1ea7d0e 100644 --- a/packages/system/src/types/handles.ts +++ b/packages/system/src/types/handles.ts @@ -1,12 +1,16 @@ -import type { XYPosition, Position, Dimensions, OnConnect, IsValidConnection } from '.'; +import type { Position, OnConnect, IsValidConnection } from '.'; export type HandleType = 'source' | 'target'; -export type HandleElement = XYPosition & - Dimensions & { - id?: string | null; - position: Position; - }; +export type HandleElement = { + id?: string | null; + x: number; + y: number; + width: number; + height: number; + position: Position; + type?: HandleType; +}; export type ConnectingHandle = { nodeId: string; diff --git a/packages/system/src/types/nodes.ts b/packages/system/src/types/nodes.ts index 9d2359f3..8ca0131a 100644 --- a/packages/system/src/types/nodes.ts +++ b/packages/system/src/types/nodes.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { internalsSymbol } from '../constants'; -import type { XYPosition, Position, CoordinateExtent, HandleElement } from '.'; +import type { XYPosition, Position, CoordinateExtent, HandleElement, Dimensions } from '.'; // this is stuff that all nodes share independent of the framework export type NodeBase = { @@ -28,6 +28,8 @@ export type NodeBase ariaLabel?: string; focusable?: boolean; origin?: NodeOrigin; + handles?: HandleElement[]; + dimensions?: Dimensions; // only used internally [internalsSymbol]?: { diff --git a/packages/system/src/utils/edges/positions.ts b/packages/system/src/utils/edges/positions.ts index 28642d35..9d7af2b3 100644 --- a/packages/system/src/utils/edges/positions.ts +++ b/packages/system/src/utils/edges/positions.ts @@ -16,10 +16,10 @@ export type GetEdgePositionParams = { }; export function getEdgePosition(params: GetEdgePositionParams): EdgePosition | null { - const [sourceNodeRect, sourceHandleBounds, sourceIsValid] = getHandleDataByNode(params.sourceNode); - const [targetNodeRect, targetHandleBounds, targetIsValid] = getHandleDataByNode(params.targetNode); + const [sourceNodeRect, sourceHandleBounds, isSourceValid] = getHandleDataByNode(params.sourceNode); + const [targetNodeRect, targetHandleBounds, isTargetValid] = getHandleDataByNode(params.targetNode); - if (!sourceIsValid || !targetIsValid) { + if (!isSourceValid || !isTargetValid) { return null; } @@ -59,13 +59,39 @@ export function getEdgePosition(params: GetEdgePositionParams): EdgePosition | n }; } +function toHandleBounds(handles?: HandleElement[]) { + if (!handles) { + return null; + } + + return handles.reduce( + (res, item) => { + if (item.type === 'source') { + res.source?.push(item); + } + + if (item.type === 'target') { + res.target?.push(item); + } + + return res; + }, + { + source: [], + target: [], + } + ); +} + function getHandleDataByNode(node?: NodeBase): [Rect, NodeHandleBounds | null, boolean] { - const handleBounds = node?.[internalsSymbol]?.handleBounds || null; + const handleBounds = node?.[internalsSymbol]?.handleBounds || toHandleBounds(node?.handles) || null; + const nodeWidth = node?.width || node?.dimensions?.width; + const nodeHeight = node?.height || node?.dimensions?.height; const isValid = handleBounds && - node?.width && - node?.height && + nodeWidth && + nodeHeight && typeof node?.positionAbsolute?.x !== 'undefined' && typeof node?.positionAbsolute?.y !== 'undefined'; @@ -73,8 +99,8 @@ function getHandleDataByNode(node?: NodeBase): [Rect, NodeHandleBounds | null, b { x: node?.positionAbsolute?.x || 0, y: node?.positionAbsolute?.y || 0, - width: node?.width || 0, - height: node?.height || 0, + width: nodeWidth || 0, + height: nodeHeight || 0, }, handleBounds, !!isValid,