From b1c30ee653600778ad17d7ecb41df1ee910abeb8 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 14 Mar 2024 16:14:48 +0100 Subject: [PATCH] refactor(intersections): use passed node values for calculations --- .../react/src/examples/Intersection/index.tsx | 21 ++++++---- packages/react/src/hooks/useReactFlow.ts | 38 ++++++++++--------- .../svelte/src/lib/hooks/useSvelteFlow.ts | 30 +++++++-------- packages/system/src/utils/graph.ts | 2 +- 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/examples/react/src/examples/Intersection/index.tsx b/examples/react/src/examples/Intersection/index.tsx index 006ddc77..2deb471e 100644 --- a/examples/react/src/examples/Intersection/index.tsx +++ b/examples/react/src/examples/Intersection/index.tsx @@ -17,28 +17,34 @@ const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', n const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node); const initialNodes: Node[] = [ + { + id: '0', + data: { label: 'rectangle' }, + position: { x: 0, y: 0 }, + width: 100, + height: 100, + draggable: false, + style: { + opacity: 0.5, + }, + }, { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 0, y: 0 }, - className: 'light', - style: { - width: 200, - height: 100, - }, + width: 200, + height: 100, }, { id: '2', data: { label: 'Node 2' }, position: { x: 0, y: 150 }, - className: 'light', }, { id: '3', data: { label: 'Node 3' }, position: { x: 250, y: 0 }, - className: 'light', }, { id: '4', @@ -48,7 +54,6 @@ const initialNodes: Node[] = [ width: 50, height: 50, }, - className: 'light', }, ]; diff --git a/packages/react/src/hooks/useReactFlow.ts b/packages/react/src/hooks/useReactFlow.ts index 5fd605fd..d05135c9 100644 --- a/packages/react/src/hooks/useReactFlow.ts +++ b/packages/react/src/hooks/useReactFlow.ts @@ -1,5 +1,12 @@ import { useCallback, useMemo, useRef, useState } from 'react'; -import { getElementsToRemove, getOverlappingArea, isRectObject, nodeToRect, type Rect } from '@xyflow/system'; +import { + getElementsToRemove, + getOverlappingArea, + isRectObject, + nodeHasDimensions, + nodeToRect, + type Rect, +} from '@xyflow/system'; import useViewportHelper from './useViewportHelper'; import { useStoreApi } from './useStore'; @@ -216,32 +223,26 @@ export function useReactFlow { - const isRect = isRectObject(nodeOrRect); - const node = isRect ? null : (store.getState().nodeLookup.get(nodeOrRect.id) as NodeType); + const getNodeRect = useCallback((nodeOrRect: NodeType | { id: Node['id'] }): Rect | null => { + const node = + isNode(nodeOrRect) && nodeHasDimensions(nodeOrRect) + ? nodeOrRect + : (store.getState().nodeLookup.get(nodeOrRect.id) as NodeType); - if (!isRect && !node) { - return [null, null, isRect]; - } - - const nodeRect = isRect ? nodeOrRect : nodeToRect(node!); - - return [nodeRect, node, isRect]; - }, - [] - ); + return node ? nodeToRect(node) : null; + }, []); const getIntersectingNodes = useCallback>( (nodeOrRect, partially = true, nodes) => { - const [nodeRect, node, isRect] = getNodeRect(nodeOrRect); + const isRect = isRectObject(nodeOrRect); + const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect); if (!nodeRect) { return []; } return (nodes || store.getState().nodes).filter((n) => { - if (!isRect && (n.id === node!.id || !n.computed?.positionAbsolute)) { + if (!isRect && (n.id === nodeOrRect!.id || !n.computed?.positionAbsolute)) { return false; } @@ -257,7 +258,8 @@ export function useReactFlow>( (nodeOrRect, area, partially = true) => { - const [nodeRect] = getNodeRect(nodeOrRect); + const isRect = isRectObject(nodeOrRect); + const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect); if (!nodeRect) { return false; diff --git a/packages/svelte/src/lib/hooks/useSvelteFlow.ts b/packages/svelte/src/lib/hooks/useSvelteFlow.ts index c035a52a..22d7de6f 100644 --- a/packages/svelte/src/lib/hooks/useSvelteFlow.ts +++ b/packages/svelte/src/lib/hooks/useSvelteFlow.ts @@ -13,7 +13,8 @@ import { type Rect, getViewportForBounds, getElementsToRemove, - rendererPointToPoint + rendererPointToPoint, + nodeHasDimensions } from '@xyflow/system'; import { useStore } from '$lib/store'; @@ -242,19 +243,12 @@ export function useSvelteFlow(): { edgeLookup } = useStore(); - const getNodeRect = ( - nodeOrRect: Node | { id: Node['id'] } | Rect - ): [Rect | null, Node | null | undefined, boolean] => { - const isRect = isRectObject(nodeOrRect); - const node = isRect ? null : get(nodes).find((n) => n.id === nodeOrRect.id); - - if (!isRect && !node) { - return [null, null, isRect]; - } - - const nodeRect = isRect ? nodeOrRect : nodeToRect(node!); - - return [nodeRect, node, isRect]; + const getNodeRect = (nodeOrRect: Node | { id: Node['id'] }): Rect | null => { + const node = + isNode(nodeOrRect) && nodeHasDimensions(nodeOrRect) + ? nodeOrRect + : get(nodeLookup).get(nodeOrRect.id); + return node ? nodeToRect(node) : null; }; const updateNode = ( @@ -329,14 +323,15 @@ export function useSvelteFlow(): { partially = true, nodesToIntersect?: Node[] ) => { - const [nodeRect, node, isRect] = getNodeRect(nodeOrRect); + const isRect = isRectObject(nodeOrRect); + const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect); if (!nodeRect) { return []; } return (nodesToIntersect || get(nodes)).filter((n) => { - if (!isRect && (n.id === node!.id || !n.computed?.positionAbsolute)) { + if (!isRect && (n.id === nodeOrRect.id || !n.computed?.positionAbsolute)) { return false; } @@ -352,7 +347,8 @@ export function useSvelteFlow(): { area: Rect, partially = true ) => { - const [nodeRect] = getNodeRect(nodeOrRect); + const isRect = isRectObject(nodeOrRect); + const nodeRect = isRect ? nodeOrRect : getNodeRect(nodeOrRect); if (!nodeRect) { return false; diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts index 9f4342dc..06bf7f62 100644 --- a/packages/system/src/utils/graph.ts +++ b/packages/system/src/utils/graph.ts @@ -45,7 +45,7 @@ export const isEdgeBase = (element: any): * @returns A boolean indicating whether the element is an Node */ export const isNodeBase = (element: any): element is NodeType => - 'id' in element && !('source' in element) && !('target' in element); + 'id' in element && 'position' in element && !('source' in element) && !('target' in element); /** * Pass in a node, and get connected nodes where edge.source === node.id