refactor(nodes): re-init when sourcePos, targetPos or type changes

This commit is contained in:
moklick
2022-01-28 14:48:14 +01:00
parent 8d5231b043
commit 7e915ad39f
3 changed files with 33 additions and 6 deletions
+28 -1
View File
@@ -11,6 +11,7 @@ const selector = (s: ReactFlowState) => ({
addSelectedNodes: s.addSelectedNodes, addSelectedNodes: s.addSelectedNodes,
updateNodePosition: s.updateNodePosition, updateNodePosition: s.updateNodePosition,
unselectNodesAndEdges: s.unselectNodesAndEdges, unselectNodesAndEdges: s.unselectNodesAndEdges,
updateNodeDimensions: s.updateNodeDimensions,
}); });
export default (NodeComponent: ComponentType<NodeProps>) => { export default (NodeComponent: ComponentType<NodeProps>) => {
@@ -51,8 +52,14 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
noDragClassName, noDragClassName,
}: WrapNodeProps) => { }: WrapNodeProps) => {
const store = useStoreApi(); const store = useStoreApi();
const { addSelectedNodes, unselectNodesAndEdges, updateNodePosition } = useStore(selector, shallow); const { addSelectedNodes, unselectNodesAndEdges, updateNodePosition, updateNodeDimensions } = useStore(
selector,
shallow
);
const nodeElement = useRef<HTMLDivElement>(null); const nodeElement = useRef<HTMLDivElement>(null);
const prevSourcePosition = useRef(sourcePosition);
const prevTargetPosition = useRef(targetPosition);
const prevType = useRef(type);
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave; const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
const nodeStyle: CSSProperties = useMemo( const nodeStyle: CSSProperties = useMemo(
() => ({ () => ({
@@ -186,6 +193,26 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
} }
}, [hidden]); }, [hidden]);
useEffect(() => {
// when the user programmatically changes the source or handle position, we re-initialize the node
const typeChanged = prevType.current !== type;
const sourcePosChanged = prevSourcePosition.current !== sourcePosition;
const targetPosChanged = prevTargetPosition.current !== targetPosition;
if (nodeElement.current && (typeChanged || sourcePosChanged || targetPosChanged)) {
if (typeChanged) {
prevType.current = type;
}
if (sourcePosChanged) {
prevSourcePosition.current = sourcePosition;
}
if (targetPosChanged) {
prevTargetPosition.current = targetPosition;
}
updateNodeDimensions([{ id, nodeElement: nodeElement.current, forceUpdate: true }]);
}
}, [id, type, sourcePosition, targetPosition]);
if (hidden) { if (hidden) {
return null; return null;
} }
+3 -3
View File
@@ -3,7 +3,7 @@ import shallow from 'zustand/shallow';
import useVisibleNodes from '../../hooks/useVisibleNodes'; import useVisibleNodes from '../../hooks/useVisibleNodes';
import { useStore } from '../../store'; import { useStore } from '../../store';
import { Node, NodeTypesType, ReactFlowState, WrapNodeProps } from '../../types'; import { Node, NodeTypesType, Position, ReactFlowState, WrapNodeProps } from '../../types';
interface NodeRendererProps { interface NodeRendererProps {
nodeTypes: NodeTypesType; nodeTypes: NodeTypesType;
@@ -87,8 +87,8 @@ const NodeRenderer = (props: NodeRendererProps) => {
style={node.style} style={node.style}
type={nodeType} type={nodeType}
data={node.data} data={node.data}
sourcePosition={node.sourcePosition} sourcePosition={node.sourcePosition || Position.Bottom}
targetPosition={node.targetPosition} targetPosition={node.targetPosition || Position.Top}
hidden={node.hidden} hidden={node.hidden}
xPos={node.positionAbsolute?.x ?? 0} xPos={node.positionAbsolute?.x ?? 0}
yPos={node.positionAbsolute?.y ?? 0} yPos={node.positionAbsolute?.y ?? 0}
+2 -2
View File
@@ -78,8 +78,8 @@ export interface WrapNodeProps<T = any> {
onNodeDragStop?: NodeMouseHandler; onNodeDragStop?: NodeMouseHandler;
style?: CSSProperties; style?: CSSProperties;
className?: string; className?: string;
sourcePosition?: Position; sourcePosition: Position;
targetPosition?: Position; targetPosition: Position;
hidden?: boolean; hidden?: boolean;
snapToGrid?: boolean; snapToGrid?: boolean;
snapGrid?: SnapGrid; snapGrid?: SnapGrid;