refactor(internals): use non enumerable props

This commit is contained in:
moklick
2022-05-26 19:55:03 +02:00
parent 03f0be62f7
commit 27b5de2d96
8 changed files with 41 additions and 22 deletions
+4 -2
View File
@@ -6,6 +6,7 @@ import { getBezierPath } from '../Edges/BezierEdge';
import { getSmoothStepPath } from '../Edges/SmoothStepEdge'; import { getSmoothStepPath } from '../Edges/SmoothStepEdge';
import { ConnectionLineType, ConnectionLineComponent, HandleType, Node, ReactFlowState, Position } from '../../types'; import { ConnectionLineType, ConnectionLineComponent, HandleType, Node, ReactFlowState, Position } from '../../types';
import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge'; import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge';
import { handleBoundsSymbol } from '../../utils';
interface ConnectionLineProps { interface ConnectionLineProps {
connectionNodeId: string; connectionNodeId: string;
@@ -37,12 +38,13 @@ export default ({
const { nodeInternals, transform } = useStore(selector, shallow); const { nodeInternals, transform } = useStore(selector, shallow);
const fromNode = useRef<Node | undefined>(nodeInternals.get(nodeId)); const fromNode = useRef<Node | undefined>(nodeInternals.get(nodeId));
const fromHandleBounds = fromNode.current?.[handleBoundsSymbol];
if (!fromNode.current || !isConnectable || !fromNode.current.handleBounds?.[connectionHandleType]) { if (!fromNode.current || !isConnectable || !fromHandleBounds?.[connectionHandleType]) {
return null; return null;
} }
const handleBound = fromNode.current.handleBounds?.[connectionHandleType]; const handleBound = fromHandleBounds[connectionHandleType];
const fromHandle = handleId ? handleBound?.find((d) => d.id === handleId) : handleBound?.[0]; const fromHandle = handleId ? handleBound?.find((d) => d.id === handleId) : handleBound?.[0];
const fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.current?.width ?? 0) / 2; const fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.current?.width ?? 0) / 2;
const fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.current?.height ?? 0; const fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.current?.height ?? 0;
+5 -4
View File
@@ -13,7 +13,7 @@ import {
Transform, Transform,
XYPosition, XYPosition,
} from '../../types'; } from '../../types';
import { rectToBox } from '../../utils'; import { handleBoundsSymbol, rectToBox } from '../../utils';
export type CreateEdgeTypes = (edgeTypes: EdgeTypes) => EdgeTypesWrapped; export type CreateEdgeTypes = (edgeTypes: EdgeTypes) => EdgeTypesWrapped;
@@ -168,10 +168,11 @@ export function isEdgeVisible({
export function getNodeData(nodeInternals: NodeInternals, nodeId: string): [Rect, NodeHandleBounds | null, boolean] { export function getNodeData(nodeInternals: NodeInternals, nodeId: string): [Rect, NodeHandleBounds | null, boolean] {
const node = nodeInternals.get(nodeId); const node = nodeInternals.get(nodeId);
const handleBounds = node?.handleBounds; const handleBounds = node?.[handleBoundsSymbol] || null;
const isInvalid = const isInvalid =
!node || !node ||
!node.handleBounds || !handleBounds ||
!node.width || !node.width ||
!node.height || !node.height ||
typeof node.positionAbsolute?.x === 'undefined' || typeof node.positionAbsolute?.x === 'undefined' ||
@@ -184,7 +185,7 @@ export function getNodeData(nodeInternals: NodeInternals, nodeId: string): [Rect
width: node?.width || 0, width: node?.width || 0,
height: node?.height || 0, height: node?.height || 0,
}, },
handleBounds || null, handleBounds,
!isInvalid, !isInvalid,
]; ];
} }
+3 -2
View File
@@ -11,6 +11,7 @@ import {
ReactFlowState, ReactFlowState,
WrapNodeProps, WrapNodeProps,
} from '../../types'; } from '../../types';
import { isParentSymbol, zSymbol } from '../../utils';
interface NodeRendererProps { interface NodeRendererProps {
nodeTypes: NodeTypesWrapped; nodeTypes: NodeTypesWrapped;
@@ -117,8 +118,8 @@ const NodeRenderer = (props: NodeRendererProps) => {
isConnectable={isConnectable} isConnectable={isConnectable}
resizeObserver={resizeObserver} resizeObserver={resizeObserver}
dragHandle={node.dragHandle} dragHandle={node.dragHandle}
zIndex={node.z ?? 0} zIndex={node[zSymbol] ?? 0}
isParent={!!node.isParent} isParent={!!node[isParentSymbol]}
noDragClassName={props.noDragClassName} noDragClassName={props.noDragClassName}
noPanClassName={props.noPanClassName} noPanClassName={props.noPanClassName}
/> />
+2 -2
View File
@@ -3,7 +3,7 @@ import { useCallback } from 'react';
import { useStore } from '../store'; import { useStore } from '../store';
import { isEdgeVisible } from '../container/EdgeRenderer/utils'; import { isEdgeVisible } from '../container/EdgeRenderer/utils';
import { ReactFlowState, NodeInternals, Edge } from '../types'; import { ReactFlowState, NodeInternals, Edge } from '../types';
import { isNumeric } from '../utils'; import { isNumeric, zSymbol } from '../utils';
const defaultEdgeTree = [{ level: 0, isMaxLevel: true, edges: [] }]; const defaultEdgeTree = [{ level: 0, isMaxLevel: true, edges: [] }];
@@ -17,7 +17,7 @@ function groupEdgesByZLevel(edges: Edge[], nodeInternals: NodeInternals, elevate
if (elevateEdgesOnSelect) { if (elevateEdgesOnSelect) {
z = hasZIndex z = hasZIndex
? edge.zIndex! ? edge.zIndex!
: Math.max(nodeInternals.get(edge.source)?.z || 0, nodeInternals.get(edge.target)?.z || 0); : Math.max(nodeInternals.get(edge.source)?.[zSymbol] || 0, nodeInternals.get(edge.target)?.[zSymbol] || 0);
} }
if (tree[z]) { if (tree[z]) {
+2 -2
View File
@@ -1,7 +1,7 @@
import create from 'zustand'; import create from 'zustand';
import createContext from 'zustand/context'; import createContext from 'zustand/context';
import { clampPosition, getDimensions } from '../utils'; import { clampPosition, getDimensions, handleBoundsSymbol } from '../utils';
import { applyNodeChanges } from '../utils/changes'; import { applyNodeChanges } from '../utils/changes';
import { import {
ReactFlowState, ReactFlowState,
@@ -60,7 +60,7 @@ const createStore = () =>
const handleBounds = getHandleBounds(update.nodeElement, transform[2]); const handleBounds = getHandleBounds(update.nodeElement, transform[2]);
nodeInternals.set(node.id, { nodeInternals.set(node.id, {
...node, ...node,
handleBounds, [handleBoundsSymbol]: handleBounds,
...dimensions, ...dimensions,
}); });
+17 -7
View File
@@ -1,7 +1,7 @@
import { zoomIdentity } from 'd3-zoom'; import { zoomIdentity } from 'd3-zoom';
import { GetState, SetState } from 'zustand'; import { GetState, SetState } from 'zustand';
import { isNumeric } from '../utils'; import { handleBoundsSymbol, isNumeric, isParentSymbol, zSymbol } from '../utils';
import { getD3Transition, getRectOfNodes, getTransformForBounds } from '../utils/graph'; import { getD3Transition, getRectOfNodes, getTransformForBounds } from '../utils/graph';
import { import {
Edge, Edge,
@@ -30,7 +30,7 @@ function calculateXYZPosition(
return calculateXYZPosition(parentNode, nodeInternals, parentNodes, { return calculateXYZPosition(parentNode, nodeInternals, parentNodes, {
x: (result.x ?? 0) + (parentNode.position?.x ?? 0), x: (result.x ?? 0) + (parentNode.position?.x ?? 0),
y: (result.y ?? 0) + (parentNode.position?.y ?? 0), y: (result.y ?? 0) + (parentNode.position?.y ?? 0),
z: (parentNode.z ?? 0) > (result.z ?? 0) ? parentNode.z ?? 0 : result.z ?? 0, z: (parentNode[zSymbol] ?? 0) > (result.z ?? 0) ? parentNode[zSymbol] ?? 0 : result.z ?? 0,
}); });
} }
@@ -45,18 +45,28 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
const internals: Node = { const internals: Node = {
width: currInternals?.width, width: currInternals?.width,
height: currInternals?.height, height: currInternals?.height,
handleBounds: currInternals?.handleBounds,
...node, ...node,
positionAbsolute: { positionAbsolute: {
x: node.position.x, x: node.position.x,
y: node.position.y, y: node.position.y,
}, },
z,
}; };
if (node.parentNode) { if (node.parentNode) {
internals.parentNode = node.parentNode; internals.parentNode = node.parentNode;
parentNodes[node.parentNode] = true; parentNodes[node.parentNode] = true;
} }
Object.defineProperty(internals, handleBoundsSymbol, {
enumerable: false,
value: currInternals?.[handleBoundsSymbol],
});
Object.defineProperty(internals, zSymbol, {
enumerable: false,
value: z,
});
nextNodeInternals.set(node.id, internals); nextNodeInternals.set(node.id, internals);
}); });
@@ -68,7 +78,7 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
if (node.parentNode || parentNodes[node.id]) { if (node.parentNode || parentNodes[node.id]) {
const { x, y, z } = calculateXYZPosition(node, nextNodeInternals, parentNodes, { const { x, y, z } = calculateXYZPosition(node, nextNodeInternals, parentNodes, {
...node.position, ...node.position,
z: node.z ?? 0, z: node[zSymbol] ?? 0,
}); });
node.positionAbsolute = { node.positionAbsolute = {
@@ -76,10 +86,10 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
y, y,
}; };
node.z = z; node[zSymbol] = z;
if (parentNodes[node.id]) { if (parentNodes[node.id]) {
node.isParent = true; node[isParentSymbol] = true;
} }
} }
}); });
+4 -3
View File
@@ -2,6 +2,7 @@ import { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
import { XYPosition, Position, CoordinateExtent } from './utils'; import { XYPosition, Position, CoordinateExtent } from './utils';
import { HandleElement } from './handles'; import { HandleElement } from './handles';
import { handleBoundsSymbol, isParentSymbol, zSymbol } from '../utils';
// interface for the user node items // interface for the user node items
export interface Node<T = any> { export interface Node<T = any> {
@@ -28,9 +29,9 @@ export interface Node<T = any> {
// only used internally // only used internally
positionAbsolute?: XYPosition; positionAbsolute?: XYPosition;
z?: number; [zSymbol]?: number;
handleBounds?: NodeHandleBounds; [handleBoundsSymbol]?: NodeHandleBounds;
isParent?: boolean; [isParentSymbol]?: boolean;
} }
// props that get passed to a custom node // props that get passed to a custom node
+4
View File
@@ -40,3 +40,7 @@ export const getBoundsofRects = (rect1: Rect, rect2: Rect): Rect =>
boxToRect(getBoundsOfBoxes(rectToBox(rect1), rectToBox(rect2))); boxToRect(getBoundsOfBoxes(rectToBox(rect1), rectToBox(rect2)));
export const isNumeric = (n: any): n is number => !isNaN(n) && isFinite(n); export const isNumeric = (n: any): n is number => !isNaN(n) && isFinite(n);
export const handleBoundsSymbol = Symbol('handleBound');
export const zSymbol = Symbol('z');
export const isParentSymbol = Symbol('isParent');