simplified handleExpandParent, removed isParent, improved some functions
This commit is contained in:
@@ -10,7 +10,8 @@ import {
|
|||||||
type NodeDimensionChange,
|
type NodeDimensionChange,
|
||||||
type NodePositionChange,
|
type NodePositionChange,
|
||||||
handleExpandParent,
|
handleExpandParent,
|
||||||
evaluateNodePosition,
|
evaluateAbsolutePosition,
|
||||||
|
ParentExpandChild,
|
||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
|
|
||||||
import { useStoreApi } from '../../hooks/useStore';
|
import { useStoreApi } from '../../hooks/useStore';
|
||||||
@@ -67,36 +68,32 @@ function ResizeControl({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
onChange: (change: XYResizerChange, childChanges: XYResizerChildChange[]) => {
|
onChange: (change: XYResizerChange, childChanges: XYResizerChildChange[]) => {
|
||||||
const { triggerNodeChanges, nodeLookup, parentLookup } = store.getState();
|
const { triggerNodeChanges, nodeLookup, parentLookup, nodeOrigin } = store.getState();
|
||||||
|
|
||||||
const changes: NodeChange[] = [];
|
const changes: NodeChange[] = [];
|
||||||
const newPosition = { x: change.x, y: change.y };
|
const newPosition = { x: change.x, y: change.y };
|
||||||
|
|
||||||
const node = nodeLookup.get(id);
|
const node = nodeLookup.get(id);
|
||||||
if (node && node.expandParent && node.parentId) {
|
if (node && node.expandParent && node.parentId) {
|
||||||
// We create a new node that will be used to handleExpandParent ...
|
const child: ParentExpandChild = {
|
||||||
const nodeWithChange = {
|
id: node.id,
|
||||||
...(node as InternalNodeWithParentExpand),
|
parentId: node.parentId,
|
||||||
position: {
|
rect: {
|
||||||
x: change.x ?? node.position.x,
|
width: change.width ?? node.measured.width!,
|
||||||
y: change.y ?? node.position.y,
|
height: change.height ?? node.measured.height!,
|
||||||
|
...evaluateAbsolutePosition(
|
||||||
|
{
|
||||||
|
x: change.x ?? node.position.x,
|
||||||
|
y: change.y ?? node.position.y,
|
||||||
|
},
|
||||||
|
node.parentId,
|
||||||
|
nodeLookup,
|
||||||
|
node.origin ?? nodeOrigin
|
||||||
|
),
|
||||||
},
|
},
|
||||||
measured: {
|
|
||||||
width: change.width,
|
|
||||||
height: change.height,
|
|
||||||
},
|
|
||||||
width: change.width,
|
|
||||||
height: change.height,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ...determine its new absolute position...
|
const parentExpandChanges = handleExpandParent([child], nodeLookup, parentLookup, nodeOrigin);
|
||||||
nodeWithChange.internals = {
|
|
||||||
...nodeWithChange.internals,
|
|
||||||
positionAbsolute: evaluateNodePosition(nodeWithChange, nodeLookup),
|
|
||||||
};
|
|
||||||
|
|
||||||
// ... and use it to expand the parent
|
|
||||||
const parentExpandChanges = handleExpandParent([nodeWithChange], nodeLookup, parentLookup);
|
|
||||||
changes.push(...parentExpandChanges);
|
changes.push(...parentExpandChanges);
|
||||||
|
|
||||||
// when the parent was expanded by the child node, its position will be clamped at 0,0
|
// when the parent was expanded by the child node, its position will be clamped at 0,0
|
||||||
|
|||||||
@@ -42,12 +42,14 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
nodeOrigin,
|
nodeOrigin,
|
||||||
onError,
|
onError,
|
||||||
}: NodeWrapperProps<NodeType>) {
|
}: NodeWrapperProps<NodeType>) {
|
||||||
const { node, internals } = useStore((s) => {
|
const { node, internals, isParent } = useStore((s) => {
|
||||||
const node = s.nodeLookup.get(id)! as InternalNode<NodeType>;
|
const node = s.nodeLookup.get(id)! as InternalNode<NodeType>;
|
||||||
|
const isParent = s.parentLookup.has(id);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
node,
|
node,
|
||||||
internals: node.internals,
|
internals: node.internals,
|
||||||
|
isParent,
|
||||||
};
|
};
|
||||||
}, shallow);
|
}, shallow);
|
||||||
|
|
||||||
@@ -209,7 +211,7 @@ export function NodeWrapper<NodeType extends Node>({
|
|||||||
{
|
{
|
||||||
selected: node.selected,
|
selected: node.selected,
|
||||||
selectable: isSelectable,
|
selectable: isSelectable,
|
||||||
parent: internals.isParent,
|
parent: isParent,
|
||||||
draggable: isDraggable,
|
draggable: isDraggable,
|
||||||
dragging,
|
dragging,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
evaluateNodePosition,
|
evaluateAbsolutePosition,
|
||||||
getElementsToRemove,
|
getElementsToRemove,
|
||||||
getOverlappingArea,
|
getOverlappingArea,
|
||||||
isInternalNodeBase,
|
|
||||||
isRectObject,
|
isRectObject,
|
||||||
nodeToRect,
|
nodeToRect,
|
||||||
type Rect,
|
type Rect,
|
||||||
@@ -233,12 +232,15 @@ export function useReactFlow<NodeType extends Node = Node, EdgeType extends Edge
|
|||||||
|
|
||||||
const getNodeRect = useCallback((node: NodeType | { id: string }): Rect | null => {
|
const getNodeRect = useCallback((node: NodeType | { id: string }): Rect | null => {
|
||||||
const { nodeLookup, nodeOrigin } = store.getState();
|
const { nodeLookup, nodeOrigin } = store.getState();
|
||||||
|
|
||||||
const nodeToUse = isNode<NodeType>(node) ? node : nodeLookup.get(node.id)!;
|
const nodeToUse = isNode<NodeType>(node) ? node : nodeLookup.get(node.id)!;
|
||||||
const positionAbsolute = evaluateNodePosition(nodeToUse, nodeLookup, nodeOrigin);
|
const position = nodeToUse.parentId
|
||||||
|
? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.parentId, nodeLookup, nodeOrigin)
|
||||||
|
: nodeToUse.position;
|
||||||
|
|
||||||
const nodeWithPosition = {
|
const nodeWithPosition = {
|
||||||
id: nodeToUse.id,
|
id: nodeToUse.id,
|
||||||
position: positionAbsolute,
|
position,
|
||||||
width: nodeToUse.measured?.width ?? nodeToUse.width,
|
width: nodeToUse.measured?.width ?? nodeToUse.width,
|
||||||
height: nodeToUse.measured?.height ?? nodeToUse.height,
|
height: nodeToUse.measured?.height ?? nodeToUse.height,
|
||||||
data: nodeToUse.data,
|
data: nodeToUse.data,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
NodeChange,
|
NodeChange,
|
||||||
EdgeSelectionChange,
|
EdgeSelectionChange,
|
||||||
NodeSelectionChange,
|
NodeSelectionChange,
|
||||||
|
ParentExpandChild,
|
||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
|
|
||||||
import { applyEdgeChanges, applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
|
import { applyEdgeChanges, applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
|
||||||
@@ -124,8 +125,7 @@ const createRFStore = ({
|
|||||||
},
|
},
|
||||||
updateNodePositions: (nodeDragItems, dragging = false) => {
|
updateNodePositions: (nodeDragItems, dragging = false) => {
|
||||||
const { nodeLookup, parentLookup } = get();
|
const { nodeLookup, parentLookup } = get();
|
||||||
type ExpandParentInternalNode = InternalNode & { parentId: string; expandParent: true };
|
const parentExpandChildren: ParentExpandChild[] = [];
|
||||||
const expandParentNodes: ExpandParentInternalNode[] = [];
|
|
||||||
|
|
||||||
const changes: NodeChange[] = nodeDragItems.map((node) => {
|
const changes: NodeChange[] = nodeDragItems.map((node) => {
|
||||||
// @todo add expandParent to drag item so that we can get rid of the look up here
|
// @todo add expandParent to drag item so that we can get rid of the look up here
|
||||||
@@ -138,14 +138,15 @@ const createRFStore = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (internalNode?.expandParent && internalNode?.parentId && change.position) {
|
if (internalNode?.expandParent && internalNode?.parentId && change.position) {
|
||||||
expandParentNodes.push({
|
parentExpandChildren.push({
|
||||||
...internalNode,
|
id: internalNode.id,
|
||||||
position: { ...node.position },
|
parentId: internalNode.parentId,
|
||||||
internals: {
|
rect: {
|
||||||
...internalNode.internals,
|
...node.internals.positionAbsolute,
|
||||||
positionAbsolute: node.internals.positionAbsolute,
|
width: internalNode.measured.width!,
|
||||||
|
height: internalNode.measured.height!,
|
||||||
},
|
},
|
||||||
} as ExpandParentInternalNode);
|
});
|
||||||
|
|
||||||
change.position.x = Math.max(0, change.position.x);
|
change.position.x = Math.max(0, change.position.x);
|
||||||
change.position.y = Math.max(0, change.position.y);
|
change.position.y = Math.max(0, change.position.y);
|
||||||
@@ -154,8 +155,8 @@ const createRFStore = ({
|
|||||||
return change;
|
return change;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (expandParentNodes.length > 0) {
|
if (parentExpandChildren.length > 0) {
|
||||||
const parentExpandChanges = handleExpandParent(expandParentNodes, nodeLookup, parentLookup);
|
const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup);
|
||||||
changes.push(...parentExpandChanges);
|
changes.push(...parentExpandChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
nodesDraggable,
|
nodesDraggable,
|
||||||
nodesConnectable,
|
nodesConnectable,
|
||||||
elementsSelectable,
|
elementsSelectable,
|
||||||
updateNodeInternals
|
updateNodeInternals,
|
||||||
|
parentLookup
|
||||||
} = useStore();
|
} = useStore();
|
||||||
|
|
||||||
const resizeObserver: ResizeObserver | null =
|
const resizeObserver: ResizeObserver | null =
|
||||||
@@ -65,7 +66,7 @@
|
|||||||
positionY={node.internals.positionAbsolute.y}
|
positionY={node.internals.positionAbsolute.y}
|
||||||
positionOriginX={posOrigin.x ?? 0}
|
positionOriginX={posOrigin.x ?? 0}
|
||||||
positionOriginY={posOrigin.y ?? 0}
|
positionOriginY={posOrigin.y ?? 0}
|
||||||
isParent={!!node.internals.isParent}
|
isParent={$parentLookup.has(node.id)}
|
||||||
style={node.style}
|
style={node.style}
|
||||||
class={node.class}
|
class={node.class}
|
||||||
type={node.type ?? 'default'}
|
type={node.type ?? 'default'}
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ export type InternalNodeBase<NodeType extends NodeBase = NodeBase> = NodeType &
|
|||||||
internals: {
|
internals: {
|
||||||
positionAbsolute: XYPosition;
|
positionAbsolute: XYPosition;
|
||||||
z: number;
|
z: number;
|
||||||
// @todo should we rename this to "handles" and use same type as node.handles?
|
|
||||||
isParent: boolean;
|
|
||||||
/** Holds a reference to the original node object provided by the user.
|
/** Holds a reference to the original node object provided by the user.
|
||||||
* Used as an optimization to avoid certain operations. */
|
* Used as an optimization to avoid certain operations. */
|
||||||
userNode: NodeType;
|
userNode: NodeType;
|
||||||
|
|||||||
@@ -222,25 +222,27 @@ export function nodeHasDimensions<NodeType extends NodeBase = NodeBase>(node: No
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to calculate the absolute position of a node
|
* Convert child position to aboslute position
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
* @param node
|
* @param position
|
||||||
|
* @param parentId
|
||||||
* @param nodeLookup
|
* @param nodeLookup
|
||||||
* @param nodeOrigin
|
* @param nodeOrigin
|
||||||
* @returns an internal node with an absolute position
|
* @returns an internal node with an absolute position
|
||||||
*/
|
*/
|
||||||
export function evaluateNodePosition(
|
export function evaluateAbsolutePosition(
|
||||||
node: NodeBase | InternalNodeBase,
|
position: XYPosition,
|
||||||
|
parentId: string,
|
||||||
nodeLookup: NodeLookup,
|
nodeLookup: NodeLookup,
|
||||||
nodeOrigin: NodeOrigin = [0, 0]
|
nodeOrigin: NodeOrigin = [0, 0]
|
||||||
): XYPosition {
|
): XYPosition {
|
||||||
let parentId = node.parentId;
|
let nextParentId: string | undefined = parentId;
|
||||||
const positionAbsolute = { ...node.position };
|
const positionAbsolute = { ...position };
|
||||||
|
|
||||||
while (parentId) {
|
while (nextParentId) {
|
||||||
const parent = nodeLookup.get(parentId);
|
const parent = nodeLookup.get(parentId);
|
||||||
parentId = parent?.parentId;
|
nextParentId = parent?.parentId;
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const origin = parent.origin || nodeOrigin;
|
const origin = parent.origin || nodeOrigin;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
import { getDimensions, getHandleBounds } from './dom';
|
import { getDimensions, getHandleBounds } from './dom';
|
||||||
import { getBoundsOfRects, getNodeDimensions, isNumeric, nodeToRect } from './general';
|
import { getBoundsOfRects, getNodeDimensions, isNumeric, nodeToRect } from './general';
|
||||||
import { getNodePositionWithOrigin } from './graph';
|
import { getNodePositionWithOrigin } from './graph';
|
||||||
|
import { ParentExpandChild } from './types';
|
||||||
|
|
||||||
export function updateAbsolutePositions<NodeType extends NodeBase>(
|
export function updateAbsolutePositions<NodeType extends NodeBase>(
|
||||||
nodeLookup: Map<string, InternalNodeBase<NodeType>>,
|
nodeLookup: Map<string, InternalNodeBase<NodeType>>,
|
||||||
@@ -27,42 +28,41 @@ export function updateAbsolutePositions<NodeType extends NodeBase>(
|
|||||||
nodeOrigin: [0, 0] as NodeOrigin,
|
nodeOrigin: [0, 0] as NodeOrigin,
|
||||||
elevateNodesOnSelect: true,
|
elevateNodesOnSelect: true,
|
||||||
defaults: {},
|
defaults: {},
|
||||||
},
|
}
|
||||||
parentLookup?: Map<string, InternalNodeBase<NodeType>[]>
|
|
||||||
) {
|
) {
|
||||||
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
|
const selectedNodeZ: number = options?.elevateNodesOnSelect ? 1000 : 0;
|
||||||
|
|
||||||
for (const [id, node] of nodeLookup) {
|
for (const [, node] of nodeLookup) {
|
||||||
const parentId = node.parentId;
|
const parentId = node.parentId;
|
||||||
|
|
||||||
if (parentId && !nodeLookup.has(parentId)) {
|
if (!parentId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nodeLookup.has(parentId)) {
|
||||||
throw new Error(`Parent node ${parentId} not found`);
|
throw new Error(`Parent node ${parentId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentId || node.internals.isParent || parentLookup?.has(id)) {
|
const parentNode = nodeLookup.get(parentId);
|
||||||
const parentNode = parentId ? nodeLookup.get(parentId) : null;
|
const { x, y, z } = calculateXYZPosition(
|
||||||
const { x, y, z } = calculateXYZPosition(
|
node,
|
||||||
node,
|
nodeLookup,
|
||||||
nodeLookup,
|
{
|
||||||
{
|
...node.position,
|
||||||
...node.position,
|
z: (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0),
|
||||||
z: (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0),
|
},
|
||||||
},
|
parentNode?.origin ?? options.nodeOrigin
|
||||||
parentNode?.origin ?? options.nodeOrigin
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const currPosition = node.internals.positionAbsolute;
|
const currPosition = node.internals.positionAbsolute;
|
||||||
const positionChanged = x !== currPosition.x || y !== currPosition.y;
|
const positionChanged = x !== currPosition.x || y !== currPosition.y;
|
||||||
|
|
||||||
|
if (positionChanged || z !== node.internals.z) {
|
||||||
node.internals = {
|
node.internals = {
|
||||||
...node.internals,
|
...node.internals,
|
||||||
positionAbsolute: positionChanged ? { x, y } : currPosition,
|
positionAbsolute: positionChanged ? { x, y } : currPosition,
|
||||||
z,
|
z,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (parentLookup !== undefined) {
|
|
||||||
node.internals.isParent = !!parentLookup.has(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,6 @@ export function adoptUserNodes<NodeType extends NodeBase>(
|
|||||||
handleBounds: currentStoreNode?.internals.handleBounds,
|
handleBounds: currentStoreNode?.internals.handleBounds,
|
||||||
z: (isNumeric(userNode.zIndex) ? userNode.zIndex : 0) + (userNode.selected ? selectedNodeZ : 0),
|
z: (isNumeric(userNode.zIndex) ? userNode.zIndex : 0) + (userNode.selected ? selectedNodeZ : 0),
|
||||||
userNode,
|
userNode,
|
||||||
isParent: false,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
nodeLookup.set(userNode.id, internalNode);
|
nodeLookup.set(userNode.id, internalNode);
|
||||||
@@ -128,7 +127,7 @@ export function adoptUserNodes<NodeType extends NodeBase>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (parentLookup.size > 0) {
|
if (parentLookup.size > 0) {
|
||||||
updateAbsolutePositions(nodeLookup, options, parentLookup);
|
updateAbsolutePositions(nodeLookup, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,30 +156,30 @@ function calculateXYZPosition<NodeType extends NodeBase>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExpandParentNode<NodeType> = NodeType & { parentId: string; expandParent: true };
|
|
||||||
|
|
||||||
export function handleExpandParent(
|
export function handleExpandParent(
|
||||||
nodes: ExpandParentNode<InternalNodeBase>[],
|
children: ParentExpandChild[],
|
||||||
nodeLookup: NodeLookup,
|
nodeLookup: NodeLookup,
|
||||||
parentLookup: ParentLookup
|
parentLookup: ParentLookup,
|
||||||
|
nodeOrigin?: NodeOrigin
|
||||||
): (NodeDimensionChange | NodePositionChange)[] {
|
): (NodeDimensionChange | NodePositionChange)[] {
|
||||||
const changes: (NodeDimensionChange | NodePositionChange)[] = [];
|
const changes: (NodeDimensionChange | NodePositionChange)[] = [];
|
||||||
const childNodeRects = new Map<string, { expandedRect: Rect; parent: InternalNodeBase }>();
|
const parentExpansions = new Map<string, { expandedRect: Rect; parent: InternalNodeBase }>();
|
||||||
|
|
||||||
// determine the expanded rectangle the child nodes would take for each parent
|
// determine the expanded rectangle the child nodes would take for each parent
|
||||||
for (const node of nodes) {
|
for (const child of children) {
|
||||||
const parent = nodeLookup.get(node.parentId);
|
const parent = nodeLookup.get(child.parentId);
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentRect = childNodeRects.get(node.parentId)?.expandedRect ?? nodeToRect(parent, node.origin);
|
const parentRect =
|
||||||
const expandedRect = getBoundsOfRects(parentRect, nodeToRect(node, node.origin));
|
parentExpansions.get(child.parentId)?.expandedRect ?? nodeToRect(parent, parent.origin ?? nodeOrigin);
|
||||||
childNodeRects.set(node.parentId, { expandedRect, parent });
|
const expandedRect = getBoundsOfRects(parentRect, child.rect);
|
||||||
|
parentExpansions.set(child.parentId, { expandedRect, parent });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childNodeRects.size > 0) {
|
if (parentExpansions.size > 0) {
|
||||||
childNodeRects.forEach(({ expandedRect, parent }, parentId) => {
|
parentExpansions.forEach(({ expandedRect, parent }, parentId) => {
|
||||||
// determine the position & dimensions of the parent
|
// determine the position & dimensions of the parent
|
||||||
const { position } = getNodePositionWithOrigin(parent, parent.origin);
|
const { position } = getNodePositionWithOrigin(parent, parent.origin);
|
||||||
const dimensions = getNodeDimensions(parent);
|
const dimensions = getNodeDimensions(parent);
|
||||||
@@ -202,7 +201,7 @@ export function handleExpandParent(
|
|||||||
// so the x,y changes of the parent do not move the children
|
// so the x,y changes of the parent do not move the children
|
||||||
const childNodes = parentLookup.get(parentId);
|
const childNodes = parentLookup.get(parentId);
|
||||||
childNodes?.forEach((childNode) => {
|
childNodes?.forEach((childNode) => {
|
||||||
if (!nodes.some((n) => n.id === childNode.id)) {
|
if (!children.some((child) => child.id === childNode.id)) {
|
||||||
changes.push({
|
changes.push({
|
||||||
id: childNode.id,
|
id: childNode.id,
|
||||||
type: 'position',
|
type: 'position',
|
||||||
@@ -250,7 +249,7 @@ export function updateNodeInternals<NodeType extends InternalNodeBase>(
|
|||||||
const style = window.getComputedStyle(viewportNode);
|
const style = window.getComputedStyle(viewportNode);
|
||||||
const { m22: zoom } = new window.DOMMatrixReadOnly(style.transform);
|
const { m22: zoom } = new window.DOMMatrixReadOnly(style.transform);
|
||||||
// in this array we collect nodes, that might trigger changes (like expanding parent)
|
// in this array we collect nodes, that might trigger changes (like expanding parent)
|
||||||
const parentExpandNodes: ExpandParentNode<NodeType>[] = [];
|
const parentExpandChildren: ParentExpandChild[] = [];
|
||||||
|
|
||||||
updates.forEach((update) => {
|
updates.forEach((update) => {
|
||||||
const node = nodeLookup.get(update.id);
|
const node = nodeLookup.get(update.id);
|
||||||
@@ -297,15 +296,19 @@ export function updateNodeInternals<NodeType extends InternalNodeBase>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (newNode.expandParent && newNode.parentId) {
|
if (newNode.expandParent && newNode.parentId) {
|
||||||
parentExpandNodes.push(newNode as ExpandParentNode<NodeType>);
|
parentExpandChildren.push({
|
||||||
|
id: newNode.id,
|
||||||
|
parentId: newNode.parentId,
|
||||||
|
rect: nodeToRect(newNode, newNode.origin || nodeOrigin),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (parentExpandNodes.length > 0) {
|
if (parentExpandChildren.length > 0) {
|
||||||
const parentExpandChanges = handleExpandParent(parentExpandNodes, nodeLookup, parentLookup);
|
const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup, nodeOrigin);
|
||||||
changes.push(...parentExpandChanges);
|
changes.push(...parentExpandChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
|
import { Rect } from '../types';
|
||||||
|
|
||||||
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
||||||
|
|
||||||
|
export type ParentExpandChild = { id: string; parentId: string; rect: Rect };
|
||||||
|
|||||||
Reference in New Issue
Block a user