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,
updateNodePosition: s.updateNodePosition,
unselectNodesAndEdges: s.unselectNodesAndEdges,
updateNodeDimensions: s.updateNodeDimensions,
});
export default (NodeComponent: ComponentType<NodeProps>) => {
@@ -51,8 +52,14 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
noDragClassName,
}: WrapNodeProps) => {
const store = useStoreApi();
const { addSelectedNodes, unselectNodesAndEdges, updateNodePosition } = useStore(selector, shallow);
const { addSelectedNodes, unselectNodesAndEdges, updateNodePosition, updateNodeDimensions } = useStore(
selector,
shallow
);
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 nodeStyle: CSSProperties = useMemo(
() => ({
@@ -186,6 +193,26 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
}
}, [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) {
return null;
}
+3 -3
View File
@@ -3,7 +3,7 @@ import shallow from 'zustand/shallow';
import useVisibleNodes from '../../hooks/useVisibleNodes';
import { useStore } from '../../store';
import { Node, NodeTypesType, ReactFlowState, WrapNodeProps } from '../../types';
import { Node, NodeTypesType, Position, ReactFlowState, WrapNodeProps } from '../../types';
interface NodeRendererProps {
nodeTypes: NodeTypesType;
@@ -87,8 +87,8 @@ const NodeRenderer = (props: NodeRendererProps) => {
style={node.style}
type={nodeType}
data={node.data}
sourcePosition={node.sourcePosition}
targetPosition={node.targetPosition}
sourcePosition={node.sourcePosition || Position.Bottom}
targetPosition={node.targetPosition || Position.Top}
hidden={node.hidden}
xPos={node.positionAbsolute?.x ?? 0}
yPos={node.positionAbsolute?.y ?? 0}
+2 -2
View File
@@ -78,8 +78,8 @@ export interface WrapNodeProps<T = any> {
onNodeDragStop?: NodeMouseHandler;
style?: CSSProperties;
className?: string;
sourcePosition?: Position;
targetPosition?: Position;
sourcePosition: Position;
targetPosition: Position;
hidden?: boolean;
snapToGrid?: boolean;
snapGrid?: SnapGrid;