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,
|
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,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
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user