Merge branch 'next-release' into fix/selection-rect
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@reactflow/minimap': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
add a new property "ariaLabel" to configure or remove the aria-label of the minimap component
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@reactflow/core': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Core: Always elevate zIndex when node is selected
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@reactflow/core': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
EdgeLabelRenderer: handle multiple instances on a page
|
||||||
@@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
import { useRef } from 'react';
|
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
|
import { useStore } from '../../hooks/useStore';
|
||||||
|
import { ReactFlowState } from '../../types';
|
||||||
|
|
||||||
|
const selector = (s: ReactFlowState) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
|
||||||
|
|
||||||
function EdgeLabelRenderer({ children }: { children: ReactNode }) {
|
function EdgeLabelRenderer({ children }: { children: ReactNode }) {
|
||||||
const wrapperRef = useRef(document.getElementById('edgelabel-portal'));
|
const edgeLabelRenderer = useStore(selector);
|
||||||
|
|
||||||
if (!wrapperRef.current) {
|
if (!edgeLabelRenderer) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return createPortal(children, wrapperRef.current);
|
return createPortal(children, edgeLabelRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EdgeLabelRenderer;
|
export default EdgeLabelRenderer;
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ const GraphView = ({
|
|||||||
disableKeyboardA11y={disableKeyboardA11y}
|
disableKeyboardA11y={disableKeyboardA11y}
|
||||||
rfId={rfId}
|
rfId={rfId}
|
||||||
/>
|
/>
|
||||||
<div className="react-flow__edgelabel-renderer" id="edgelabel-portal" />
|
<div className="react-flow__edgelabel-renderer" />
|
||||||
|
|
||||||
<NodeRenderer
|
<NodeRenderer
|
||||||
nodeTypes={nodeTypes}
|
nodeTypes={nodeTypes}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
|
|||||||
const parentNodes: ParentNodes = {};
|
const parentNodes: ParentNodes = {};
|
||||||
|
|
||||||
nodes.forEach((node) => {
|
nodes.forEach((node) => {
|
||||||
const z = isNumeric(node.zIndex) ? node.zIndex : node.selected ? 1000 : 0;
|
const z = (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? 1000 : 0);
|
||||||
const currInternals = nodeInternals.get(node.id);
|
const currInternals = nodeInternals.get(node.id);
|
||||||
|
|
||||||
const internals: Node = {
|
const internals: Node = {
|
||||||
|
|||||||
@@ -243,3 +243,4 @@ export const getTransformForBounds = (
|
|||||||
export const getD3Transition = (selection: D3Selection<Element, unknown, null, undefined>, duration = 0) => {
|
export const getD3Transition = (selection: D3Selection<Element, unknown, null, undefined>, duration = 0) => {
|
||||||
return selection.transition().duration(duration);
|
return selection.transition().duration(duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ const selector = (s: ReactFlowState) => {
|
|||||||
const getAttrFunction = (func: any): GetMiniMapNodeAttribute => (func instanceof Function ? func : () => func);
|
const getAttrFunction = (func: any): GetMiniMapNodeAttribute => (func instanceof Function ? func : () => func);
|
||||||
|
|
||||||
const ARIA_LABEL_KEY = 'react-flow__minimap-desc';
|
const ARIA_LABEL_KEY = 'react-flow__minimap-desc';
|
||||||
|
|
||||||
function MiniMap({
|
function MiniMap({
|
||||||
style,
|
style,
|
||||||
className,
|
className,
|
||||||
@@ -54,6 +53,7 @@ function MiniMap({
|
|||||||
onNodeClick,
|
onNodeClick,
|
||||||
pannable = false,
|
pannable = false,
|
||||||
zoomable = false,
|
zoomable = false,
|
||||||
|
ariaLabel = 'React Flow mini map',
|
||||||
}: MiniMapProps) {
|
}: MiniMapProps) {
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const svg = useRef<SVGSVGElement>(null);
|
const svg = useRef<SVGSVGElement>(null);
|
||||||
@@ -156,7 +156,7 @@ function MiniMap({
|
|||||||
ref={svg}
|
ref={svg}
|
||||||
onClick={onSvgClick}
|
onClick={onSvgClick}
|
||||||
>
|
>
|
||||||
<title id={labelledBy}>React Flow mini map</title>
|
{ariaLabel && <title id={labelledBy}>{ariaLabel}</title>}
|
||||||
{nodes.map((node) => (
|
{nodes.map((node) => (
|
||||||
<MiniMapNode
|
<MiniMapNode
|
||||||
key={node.id}
|
key={node.id}
|
||||||
|
|||||||
@@ -16,4 +16,5 @@ export type MiniMapProps<NodeData = any> = Omit<HTMLAttributes<SVGSVGElement>, '
|
|||||||
onNodeClick?: (event: MouseEvent, node: Node<NodeData>) => void;
|
onNodeClick?: (event: MouseEvent, node: Node<NodeData>) => void;
|
||||||
pannable?: boolean;
|
pannable?: boolean;
|
||||||
zoomable?: boolean;
|
zoomable?: boolean;
|
||||||
|
ariaLabel?: string | null;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user