diff --git a/examples/react/src/examples/NodeResizer/index.tsx b/examples/react/src/examples/NodeResizer/index.tsx index a4f59ada..397c1f22 100644 --- a/examples/react/src/examples/NodeResizer/index.tsx +++ b/examples/react/src/examples/NodeResizer/index.tsx @@ -128,7 +128,7 @@ const initialNodes: Node[] = [ data: { label: 'Parent', keepAspectRatio: true }, position: { x: 700, y: 0 }, width: 300, - height: 400, + height: 300, style: { ...nodeStyle }, }, { @@ -148,7 +148,9 @@ const initialNodes: Node[] = [ id: '5b', type: 'defaultResizer', data: { label: 'Child with expandParent' }, - position: { x: 150, y: 100 }, + position: { x: 100, y: 100 }, + width: 100, + height: 100, parentId: '5', expandParent: true, style: { ...nodeStyle }, @@ -187,7 +189,6 @@ const CustomNodeFlow = () => { minZoom={0.2} maxZoom={5} snapToGrid={snapToGrid} - nodeOrigin={[1, 1]} fitView onlyRenderVisibleElements > diff --git a/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx b/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx index 517dbd9f..7f1139c1 100644 --- a/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx +++ b/packages/react/src/additional-components/NodeResizer/NodeResizeControl.tsx @@ -84,8 +84,8 @@ function ResizeControl({ height, ...evaluateAbsolutePosition( { - x: change.x ?? node.internals.positionAbsolute.x, - y: change.y ?? node.internals.positionAbsolute.y, + x: change.x ?? node.position.x, + y: change.y ?? node.position.y, }, { width, height }, node.parentId, @@ -94,6 +94,7 @@ function ResizeControl({ ), }, }; + console.log(child); const parentExpandChanges = handleExpandParent([child], nodeLookup, parentLookup, nodeOrigin); changes.push(...parentExpandChanges); diff --git a/packages/react/src/components/NodeWrapper/index.tsx b/packages/react/src/components/NodeWrapper/index.tsx index 515fc78c..be14ff77 100644 --- a/packages/react/src/components/NodeWrapper/index.tsx +++ b/packages/react/src/components/NodeWrapper/index.tsx @@ -39,7 +39,6 @@ export function NodeWrapper({ rfId, nodeTypes, nodeExtent, - nodeOrigin, onError, }: NodeWrapperProps) { const { node, internals, isParent } = useStore((s) => { @@ -87,7 +86,9 @@ export function NodeWrapper({ const nodeDimensions = getNodeDimensions(node); const inlineDimensions = getNodeInlineStyleDimensions(node); // TODO: clamping should happen earlier - let clampedPosition = nodeExtent ? clampPosition(internals.positionAbsolute, nodeExtent) : internals.positionAbsolute; + const clampedPosition = nodeExtent + ? clampPosition(internals.positionAbsolute, nodeExtent) + : internals.positionAbsolute; const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave; diff --git a/packages/react/src/container/GraphView/index.tsx b/packages/react/src/container/GraphView/index.tsx index 8050ca20..d74a0fdb 100644 --- a/packages/react/src/container/GraphView/index.tsx +++ b/packages/react/src/container/GraphView/index.tsx @@ -32,7 +32,6 @@ export type GraphViewProps > & { rfId: string; @@ -97,7 +96,6 @@ function GraphViewComponent diff --git a/packages/react/src/container/NodeRenderer/index.tsx b/packages/react/src/container/NodeRenderer/index.tsx index 39b20323..2b178ae5 100644 --- a/packages/react/src/container/NodeRenderer/index.tsx +++ b/packages/react/src/container/NodeRenderer/index.tsx @@ -22,7 +22,6 @@ export type NodeRendererProps = Pick< | 'noDragClassName' | 'rfId' | 'disableKeyboardA11y' - | 'nodeOrigin' | 'nodeExtent' | 'nodeTypes' >; @@ -72,7 +71,6 @@ function NodeRendererComponent(props: NodeRendererProps( noPanClassName={noPanClassName} rfId={rfId} disableKeyboardA11y={disableKeyboardA11y} - nodeOrigin={nodeOrigin} nodeExtent={nodeExtent} viewport={viewport} onViewportChange={onViewportChange} diff --git a/packages/react/src/types/nodes.ts b/packages/react/src/types/nodes.ts index a01a894a..71e03036 100644 --- a/packages/react/src/types/nodes.ts +++ b/packages/react/src/types/nodes.ts @@ -1,12 +1,5 @@ import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react'; -import type { - CoordinateExtent, - NodeBase, - NodeOrigin, - OnError, - NodeProps as NodePropsBase, - InternalNodeBase, -} from '@xyflow/system'; +import type { CoordinateExtent, NodeBase, OnError, NodeProps as NodePropsBase, InternalNodeBase } from '@xyflow/system'; import { NodeTypes } from './general'; @@ -59,7 +52,6 @@ export type NodeWrapperProps = { disableKeyboardA11y: boolean; nodeTypes?: NodeTypes; nodeExtent?: CoordinateExtent; - nodeOrigin: NodeOrigin; onError?: OnError; }; diff --git a/packages/react/src/types/store.ts b/packages/react/src/types/store.ts index 7bf6e692..52ffae5d 100644 --- a/packages/react/src/types/store.ts +++ b/packages/react/src/types/store.ts @@ -54,7 +54,7 @@ export type ReactFlowStore>; - parentLookup: Map[]>; + parentLookup: Map>>; edges: Edge[]; edgeLookup: EdgeLookup; connectionLookup: ConnectionLookup; diff --git a/packages/svelte/src/lib/store/initial-store.ts b/packages/svelte/src/lib/store/initial-store.ts index 073f206c..34d3635b 100644 --- a/packages/svelte/src/lib/store/initial-store.ts +++ b/packages/svelte/src/lib/store/initial-store.ts @@ -107,7 +107,7 @@ export const getInitialStore = ({ flowId: writable(null), nodes: createNodesStore(nodes, nodeLookup, parentLookup), nodeLookup: readable>(nodeLookup), - parentLookup: readable>(parentLookup), + parentLookup: readable>>(parentLookup), edgeLookup: readable>(edgeLookup), visibleNodes: readable([]), edges: createEdgesStore(edges, connectionLookup, edgeLookup), diff --git a/packages/svelte/src/lib/store/utils.ts b/packages/svelte/src/lib/store/utils.ts index 5fd66cfe..4eb402dc 100644 --- a/packages/svelte/src/lib/store/utils.ts +++ b/packages/svelte/src/lib/store/utils.ts @@ -13,7 +13,8 @@ import { type PanZoomInstance, type ConnectionLookup, type EdgeLookup, - type NodeLookup + type NodeLookup, + type ParentLookup } from '@xyflow/system'; import type { DefaultEdgeOptions, DefaultNodeOptions, Edge, InternalNode, Node } from '$lib/types'; @@ -128,7 +129,7 @@ export type NodeStoreOptions = { export const createNodesStore = ( nodes: Node[], nodeLookup: NodeLookup, - parentLookup: Map + parentLookup: ParentLookup ): { subscribe: (this: void, run: Subscriber) => Unsubscriber; update: (this: void, updater: Updater) => void; diff --git a/packages/system/src/types/nodes.ts b/packages/system/src/types/nodes.ts index a6cf407f..afe1b3fa 100644 --- a/packages/system/src/types/nodes.ts +++ b/packages/system/src/types/nodes.ts @@ -154,4 +154,4 @@ export type NodeHandle = Optional; export type Align = 'center' | 'start' | 'end'; export type NodeLookup = Map; -export type ParentLookup = Map; +export type ParentLookup = Map>; diff --git a/packages/system/src/utils/general.ts b/packages/system/src/utils/general.ts index 95a02f81..f2087ab9 100644 --- a/packages/system/src/utils/general.ts +++ b/packages/system/src/utils/general.ts @@ -118,29 +118,6 @@ export const devWarn = (id: string, message: string) => { } }; -export const getPositionWithOrigin = ({ - x, - y, - width, - height, - origin = [0, 0], -}: { - x: number; - y: number; - width: number; - height: number; - origin?: NodeOrigin; -}): XYPosition => { - if (!width || !height || origin[0] < 0 || origin[1] < 0 || origin[0] > 1 || origin[1] > 1) { - return { x, y }; - } - - return { - x: x - width * origin[0], - y: y - height * origin[1], - }; -}; - export const snapPosition = (position: XYPosition, snapGrid: SnapGrid = [1, 1]): XYPosition => { return { x: snapGrid[0] * Math.round(position.x / snapGrid[0]), @@ -243,7 +220,7 @@ export function nodeHasDimensions(node: No */ export function evaluateAbsolutePosition( position: XYPosition, - dimensions: { width: number; height: number }, + dimensions: { width?: number; height?: number } = { width: 0, height: 0 }, parentId: string, nodeLookup: NodeLookup, nodeOrigin: NodeOrigin @@ -257,10 +234,8 @@ export function evaluateAbsolutePosition( if (parent) { const origin = parent.origin || nodeOrigin; - const xOffset = (parent.measured.width ?? 0) * origin[0]; - const yOffset = (parent.measured.height ?? 0) * origin[1]; - positionAbsolute.x += parent.internals.positionAbsolute.x - dimensions.width * nodeOrigin[0]; - positionAbsolute.y += parent.internals.positionAbsolute.y - dimensions.height * nodeOrigin[1]; + positionAbsolute.x += parent.internals.positionAbsolute.x - (dimensions.width ?? 0) * origin[0]; + positionAbsolute.y += parent.internals.positionAbsolute.y - (dimensions.height ?? 0) * origin[1]; } } diff --git a/packages/system/src/utils/store.ts b/packages/system/src/utils/store.ts index 60184f16..87accbc0 100644 --- a/packages/system/src/utils/store.ts +++ b/packages/system/src/utils/store.ts @@ -15,7 +15,6 @@ import { NodeDimensionChange, NodePositionChange, ParentLookup, - Dimensions, } from '../types'; import { getDimensions, getHandleBounds } from './dom'; import { getBoundsOfRects, getNodeDimensions, isNumeric, nodeToRect } from './general'; @@ -23,8 +22,8 @@ import { getNodePositionWithOrigin } from './graph'; import { ParentExpandChild } from './types'; export function updateAbsolutePositions( - nodeLookup: Map>, - parentLookup: Map[]>, + nodeLookup: NodeLookup>, + parentLookup: ParentLookup>, options: UpdateNodesOptions = { nodeOrigin: [0, 0] as NodeOrigin, elevateNodesOnSelect: true, @@ -49,8 +48,8 @@ type UpdateNodesOptions = { export function adoptUserNodes( nodes: NodeType[], - nodeLookup: Map>, - parentLookup: Map[]>, + nodeLookup: NodeLookup>, + parentLookup: ParentLookup>, options: UpdateNodesOptions = { nodeOrigin: [0, 0] as NodeOrigin, elevateNodesOnSelect: true, @@ -94,8 +93,8 @@ export function adoptUserNodes( function updateChildPosition( node: InternalNodeBase, - nodeLookup: NodeLookup, - parentLookup: ParentLookup, + nodeLookup: NodeLookup>, + parentLookup: ParentLookup>, options: UpdateNodesOptions = { nodeOrigin: [0, 0] as NodeOrigin, elevateNodesOnSelect: true, @@ -111,9 +110,9 @@ function updateChildPosition( // update the parentLookup const childNodes = parentLookup.get(parentId); if (childNodes) { - childNodes.push(node); + childNodes.set(node.id, node); } else { - parentLookup.set(parentId, [node]); + parentLookup.set(parentId, new Map([[node.id, node]]); } const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0; @@ -160,7 +159,7 @@ export function handleExpandParent( ): (NodeDimensionChange | NodePositionChange)[] { const changes: (NodeDimensionChange | NodePositionChange)[] = []; const parentExpansions = new Map(); - + console.log(children) // determine the expanded rectangle the child nodes would take for each parent for (const child of children) { const parent = nodeLookup.get(child.parentId); @@ -168,14 +167,13 @@ export function handleExpandParent( continue; } - const parentRect = - parentExpansions.get(child.parentId)?.expandedRect ?? nodeToRect(parent, parent.origin ?? nodeOrigin); - + const parentRect = parentExpansions.get(child.parentId)?.expandedRect ?? nodeToRect(parent); const expandedRect = getBoundsOfRects(parentRect, child.rect); parentExpansions.set(child.parentId, { expandedRect, parent }); } + if (parentExpansions.size > 0) { parentExpansions.forEach(({ expandedRect, parent }, parentId) => { // determine the position & dimensions of the parent @@ -208,8 +206,7 @@ export function handleExpandParent( // We move all child nodes in the oppsite direction // so the x,y changes of the parent do not move the children - const childNodes = parentLookup.get(parentId); - childNodes?.forEach((childNode) => { + parentLookup.get(parentId)?.forEach((childNode) => { if (!children.some((child) => child.id === childNode.id)) { changes.push({ id: childNode.id, @@ -295,7 +292,7 @@ export function updateNodeInternals( }, }; if (node.parentId) { - updateChildPosition(node, nodeLookup, parentLookup, { nodeOrigin }); + updateChildPosition(node, nodeLookup, parentLookup, { nodeOrigin }); } updatedInternals = true;