refactor(react): separate user nodes and indernal nodes
This commit is contained in:
@@ -26,13 +26,14 @@ import type {
|
||||
OnSelectionDrag,
|
||||
UpdateNodePositions,
|
||||
Box,
|
||||
InternalNodeBase,
|
||||
} from '../types';
|
||||
|
||||
export type OnDrag = (event: MouseEvent, dragItems: NodeDragItem[], node: NodeBase, nodes: NodeBase[]) => void;
|
||||
|
||||
type StoreItems<OnNodeDrag> = {
|
||||
nodes: NodeBase[];
|
||||
nodeLookup: Map<string, NodeBase>;
|
||||
nodeLookup: Map<string, InternalNodeBase>;
|
||||
edges: EdgeBase[];
|
||||
nodeExtent: CoordinateExtent;
|
||||
snapGrid: SnapGrid;
|
||||
@@ -130,19 +131,23 @@ export function XYDrag<OnNodeDrag extends (e: any, nodes: any, node: any) => voi
|
||||
|
||||
// if there is selection with multiple nodes and a node extent is set, we need to adjust the node extent for each node
|
||||
// based on its position so that the node stays at it's position relative to the selection.
|
||||
const adjustedNodeExtent: CoordinateExtent = [
|
||||
let adjustedNodeExtent: CoordinateExtent = [
|
||||
[nodeExtent[0][0], nodeExtent[0][1]],
|
||||
[nodeExtent[1][0], nodeExtent[1][1]],
|
||||
];
|
||||
|
||||
if (dragItems.length > 1 && nodeExtent && !n.extent) {
|
||||
adjustedNodeExtent[0][0] = n.computed.positionAbsolute.x - nodesBox.x + nodeExtent[0][0];
|
||||
adjustedNodeExtent[1][0] =
|
||||
n.computed.positionAbsolute.x + (n.computed?.width ?? 0) - nodesBox.x2 + nodeExtent[1][0];
|
||||
const { positionAbsolute } = n.internals;
|
||||
const x1 = positionAbsolute.x - nodesBox.x + nodeExtent[0][0];
|
||||
const x2 = positionAbsolute.x + (n.computed?.width ?? 0) - nodesBox.x2 + nodeExtent[1][0];
|
||||
|
||||
adjustedNodeExtent[0][1] = n.computed.positionAbsolute.y - nodesBox.y + nodeExtent[0][1];
|
||||
adjustedNodeExtent[1][1] =
|
||||
n.computed.positionAbsolute.y + (n.computed?.height ?? 0) - nodesBox.y2 + nodeExtent[1][1];
|
||||
const y1 = positionAbsolute.y - nodesBox.y + nodeExtent[0][1];
|
||||
const y2 = positionAbsolute.y + (n.computed?.height ?? 0) - nodesBox.y2 + nodeExtent[1][1];
|
||||
|
||||
adjustedNodeExtent = [
|
||||
[x1, y1],
|
||||
[x2, y2],
|
||||
];
|
||||
}
|
||||
|
||||
const { position, positionAbsolute } = calculateNodePosition({
|
||||
@@ -158,7 +163,7 @@ export function XYDrag<OnNodeDrag extends (e: any, nodes: any, node: any) => voi
|
||||
hasChange = hasChange || n.position.x !== position.x || n.position.y !== position.y;
|
||||
|
||||
n.position = position;
|
||||
n.computed.positionAbsolute = positionAbsolute;
|
||||
n.internals.positionAbsolute = positionAbsolute;
|
||||
|
||||
return n;
|
||||
});
|
||||
@@ -208,7 +213,6 @@ export function XYDrag<OnNodeDrag extends (e: any, nodes: any, node: any) => voi
|
||||
|
||||
function startDrag(event: UseDragEvent) {
|
||||
const {
|
||||
nodes,
|
||||
nodeLookup,
|
||||
multiSelectionActive,
|
||||
nodesDraggable,
|
||||
@@ -236,7 +240,7 @@ export function XYDrag<OnNodeDrag extends (e: any, nodes: any, node: any) => voi
|
||||
|
||||
const pointerPos = getPointerPosition(event.sourceEvent, { transform, snapGrid, snapToGrid });
|
||||
lastPos = pointerPos;
|
||||
dragItems = getDragItems(nodes, nodesDraggable, pointerPos, nodeId);
|
||||
dragItems = getDragItems(nodeLookup, nodesDraggable, pointerPos, nodeId);
|
||||
|
||||
if (dragItems.length > 0 && (onDragStart || onNodeDragStart || (!nodeId && onSelectionDragStart))) {
|
||||
const [currentNode, currentNodes] = getEventHandlerParams({
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { type NodeDragItem, type XYPosition, NodeBase } from '../types';
|
||||
import { type NodeDragItem, type XYPosition, InternalNodeBase, NodeBase, NodeLookup } from '../types';
|
||||
|
||||
export function wrapSelectionDragFunc(selectionFunc?: (event: MouseEvent, nodes: NodeBase[]) => void) {
|
||||
return (event: MouseEvent, _: NodeBase, nodes: NodeBase[]) => selectionFunc?.(event, nodes);
|
||||
}
|
||||
|
||||
export function isParentSelected<NodeType extends NodeBase>(node: NodeType, nodes: NodeType[]): boolean {
|
||||
export function isParentSelected<NodeType extends NodeBase>(node: NodeType, nodeLookup: NodeLookup): boolean {
|
||||
if (!node.parentNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parentNode = nodes.find((node) => node.id === node.parentNode);
|
||||
const parentNode = nodeLookup.get(node.parentNode);
|
||||
|
||||
if (!parentNode) {
|
||||
return false;
|
||||
@@ -19,7 +19,7 @@ export function isParentSelected<NodeType extends NodeBase>(node: NodeType, node
|
||||
return true;
|
||||
}
|
||||
|
||||
return isParentSelected(parentNode, nodes);
|
||||
return isParentSelected(parentNode, nodeLookup);
|
||||
}
|
||||
|
||||
export function hasSelector(target: Element, selector: string, domNode: Element): boolean {
|
||||
@@ -36,39 +36,43 @@ export function hasSelector(target: Element, selector: string, domNode: Element)
|
||||
|
||||
// looks for all selected nodes and created a NodeDragItem for each of them
|
||||
export function getDragItems<NodeType extends NodeBase>(
|
||||
nodes: NodeType[],
|
||||
nodeLookup: Map<string, InternalNodeBase<NodeType>>,
|
||||
nodesDraggable: boolean,
|
||||
mousePos: XYPosition,
|
||||
nodeId?: string
|
||||
): NodeDragItem[] {
|
||||
return nodes
|
||||
.filter(
|
||||
(n) =>
|
||||
(n.selected || n.id === nodeId) &&
|
||||
(!n.parentNode || !isParentSelected(n, nodes)) &&
|
||||
(n.draggable || (nodesDraggable && typeof n.draggable === 'undefined'))
|
||||
)
|
||||
.map((n) => ({
|
||||
id: n.id,
|
||||
position: n.position || { x: 0, y: 0 },
|
||||
distance: {
|
||||
x: mousePos.x - (n.computed?.positionAbsolute?.x ?? 0),
|
||||
y: mousePos.y - (n.computed?.positionAbsolute?.y ?? 0),
|
||||
},
|
||||
delta: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
extent: n.extent,
|
||||
parentNode: n.parentNode,
|
||||
origin: n.origin,
|
||||
expandParent: n.expandParent,
|
||||
computed: {
|
||||
positionAbsolute: n.computed?.positionAbsolute || { x: 0, y: 0 },
|
||||
width: n.computed?.width || 0,
|
||||
height: n.computed?.height || 0,
|
||||
},
|
||||
}));
|
||||
const dragItems: NodeDragItem[] = [];
|
||||
|
||||
for (const [id, node] of nodeLookup) {
|
||||
if (
|
||||
(node.selected || node.id === nodeId) &&
|
||||
(!node.parentNode || !isParentSelected(node, nodeLookup)) &&
|
||||
(node.draggable || (nodesDraggable && typeof node.draggable === 'undefined'))
|
||||
) {
|
||||
const internalNode = nodeLookup.get(id)!;
|
||||
|
||||
dragItems.push({
|
||||
id: internalNode.id,
|
||||
position: internalNode.position || { x: 0, y: 0 },
|
||||
distance: {
|
||||
x: mousePos.x - (internalNode.internals.positionAbsolute?.x ?? 0),
|
||||
y: mousePos.y - (internalNode.internals.positionAbsolute?.y ?? 0),
|
||||
},
|
||||
extent: internalNode.extent,
|
||||
parentNode: internalNode.parentNode,
|
||||
origin: internalNode.origin,
|
||||
expandParent: internalNode.expandParent,
|
||||
internals: {
|
||||
positionAbsolute: internalNode.internals.positionAbsolute || { x: 0, y: 0 },
|
||||
},
|
||||
computed: {
|
||||
width: internalNode.computed.width || 0,
|
||||
height: internalNode.computed.height || 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
return dragItems;
|
||||
}
|
||||
|
||||
// returns two params:
|
||||
@@ -91,7 +95,6 @@ export function getEventHandlerParams<NodeType extends NodeBase>({
|
||||
position: n.position,
|
||||
computed: {
|
||||
...n.computed,
|
||||
positionAbsolute: n.computed.positionAbsolute,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user