refactor(nodes): re-init when sourcePos, targetPos or type changes
This commit is contained in:
@@ -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,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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user