Merge branch 'prevent-multiple-edge-label-renderers-collide-with-each-other' of github.com:liuruenshen/react-flow into liuruenshen-prevent-multiple-edge-label-renderers-collide-with-each-other

This commit is contained in:
moklick
2022-11-15 11:05:32 +01:00
4 changed files with 74 additions and 5 deletions

View File

@@ -0,0 +1,63 @@
import ReactFlow, { BaseEdge, EdgeLabelRenderer, EdgeProps, getSmoothStepPath, ReactFlowProvider } from 'reactflow';
import * as simpleflow from '../../fixtures/simpleflow';
function CustomEdge(props: EdgeProps) {
const [path, labelX, labelY] = getSmoothStepPath(props);
return (
<>
<BaseEdge path={path} labelX={labelX} labelY={labelY} />
<EdgeLabelRenderer>
<div className="label">{props.id}</div>
</EdgeLabelRenderer>
</>
);
}
const simpleflow1 = { ...simpleflow };
simpleflow1.edges = [...simpleflow1.edges];
simpleflow1.edges[0] = { ...simpleflow1.edges[0], id: 'edge1' };
const simpleflow2 = { ...simpleflow };
simpleflow2.edges = [...simpleflow2.edges];
simpleflow2.edges[0] = { ...simpleflow2.edges[0], id: 'edge2' };
describe('<ReactFlow />: Multiple Instances', () => {
describe('render EdgeLabelRenderer', () => {
beforeEach(() => {
cy.mount(
<>
<ReactFlowProvider>
<ReactFlow
defaultNodes={simpleflow1.nodes}
edgeTypes={{ default: CustomEdge }}
defaultEdges={simpleflow1.edges}
/>
</ReactFlowProvider>
<ReactFlowProvider>
<ReactFlow
defaultNodes={simpleflow2.nodes}
edgeTypes={{ default: CustomEdge }}
defaultEdges={simpleflow2.edges}
/>
</ReactFlowProvider>
</>
);
});
it('Each ReactFlow instance has one edge label in EdgeLabelRenderer', () => {
cy.get('.react-flow__edgelabel-renderer').should('have.length', 2);
cy.get('.react-flow__edgelabel-renderer')
.eq(0)
.within(() => {
cy.get('.label').should('have.length', 1).should('contain.text', 'edge1');
});
cy.get('.react-flow__edgelabel-renderer')
.eq(1)
.within(() => {
cy.get('.label').should('have.length', 1).should('contain.text', 'edge2');
});
});
});
});

View File

@@ -1,15 +1,20 @@
import { useRef } from 'react';
import type { ReactNode } from 'react';
import { createPortal } from 'react-dom';
import { useStore } from '../../hooks/useStore';
import { ReactFlowState } from '../../types';
const selector = (s: ReactFlowState) => ({
edgeLabelRenderer: s.domNode?.querySelector('.react-flow__edgelabel-renderer'),
});
function EdgeLabelRenderer({ children }: { children: ReactNode }) {
const wrapperRef = useRef(document.getElementById('edgelabel-portal'));
const { edgeLabelRenderer } = useStore(selector);
if (!wrapperRef.current) {
if (!edgeLabelRenderer) {
return null;
}
return createPortal(children, wrapperRef.current);
return createPortal(children, edgeLabelRenderer);
}
export default EdgeLabelRenderer;

View File

@@ -158,7 +158,7 @@ const GraphView = ({
disableKeyboardA11y={disableKeyboardA11y}
rfId={rfId}
/>
<div className="react-flow__edgelabel-renderer" id="edgelabel-portal" />
<div className="react-flow__edgelabel-renderer" />
<NodeRenderer
nodeTypes={nodeTypes}

View File

@@ -223,3 +223,4 @@ export const getTransformForBounds = (
export const getD3Transition = (selection: D3Selection<Element, unknown, null, undefined>, duration = 0) => {
return selection.transition().duration(duration);
};