refactor(react): separate user nodes and indernal nodes

This commit is contained in:
moklick
2024-03-27 11:22:43 +01:00
parent d775012e1b
commit 844d574c4f
33 changed files with 374 additions and 315 deletions
+15 -11
View File
@@ -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({
+37 -34
View File
@@ -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,
},
};
});