test(examples): use new api for test examples
This commit is contained in:
@@ -127,29 +127,29 @@ describe('Basic Flow Rendering', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('drags the pane', () => {
|
it('drags the pane', () => {
|
||||||
const styleBeforeDrag = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeDrag = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
// for d3 we have to pass the window to the event
|
// for d3 we have to pass the window to the event
|
||||||
// https://github.com/cypress-io/cypress/issues/3441
|
// https://github.com/cypress-io/cypress/issues/3441
|
||||||
cy.window().then((win) => {
|
cy.window().then((win) => {
|
||||||
cy.get('.react-flow__renderer')
|
cy.get('.react-flow__pane')
|
||||||
.trigger('mousedown', 'topLeft', { which: 1, view: win })
|
.trigger('mousedown', 'topLeft', { which: 1, view: win })
|
||||||
.trigger('mousemove', 'bottomLeft')
|
.trigger('mousemove', 'bottomLeft')
|
||||||
.trigger('mouseup', { force: true, view: win })
|
.trigger('mouseup', { force: true, view: win })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterDrag = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterDrag = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeDrag).to.not.equal(styleAfterDrag);
|
expect(styleBeforeDrag).to.not.equal(styleAfterDrag);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('zooms the pane', () => {
|
it('zooms the pane', () => {
|
||||||
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
cy.get('.react-flow__renderer')
|
cy.get('.react-flow__pane')
|
||||||
.trigger('wheel', 'topLeft', { deltaY: -200 })
|
.trigger('wheel', 'topLeft', { deltaY: -200 })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,30 +8,30 @@ describe('Controls Testing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('zooms in', () => {
|
it('zooms in', () => {
|
||||||
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
cy.get('.react-flow__controls-zoomin')
|
cy.get('.react-flow__controls-zoomin')
|
||||||
.click()
|
.click()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('zooms out', () => {
|
it('zooms out', () => {
|
||||||
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
cy.get('.react-flow__controls-zoomout')
|
cy.get('.react-flow__controls-zoomout')
|
||||||
.click()
|
.click()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// view is already fitted so we drag the pane to un-fit it
|
// view is already fitted so we drag the pane to un-fit it
|
||||||
it('drags the pane', () => {
|
it('drags the pane', () => {
|
||||||
const styleBeforeDrag = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeDrag = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
// for d3 we have to pass the window to the event
|
// for d3 we have to pass the window to the event
|
||||||
// https://github.com/cypress-io/cypress/issues/3441
|
// https://github.com/cypress-io/cypress/issues/3441
|
||||||
@@ -41,19 +41,19 @@ describe('Controls Testing', () => {
|
|||||||
.trigger('mousemove', 'bottomLeft')
|
.trigger('mousemove', 'bottomLeft')
|
||||||
.trigger('mouseup', { force: true, view: win })
|
.trigger('mouseup', { force: true, view: win })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterDrag = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterDrag = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeDrag).to.not.equal(styleAfterDrag);
|
expect(styleBeforeDrag).to.not.equal(styleAfterDrag);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fits view', () => {
|
it('fits view', () => {
|
||||||
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
cy.get('.react-flow__controls-fitview')
|
cy.get('.react-flow__controls-fitview')
|
||||||
.click()
|
.click()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
expect(styleBeforeZoom).to.not.equal(styleAfterZoom);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,11 +20,6 @@ describe('Empty Flow Rendering', () => {
|
|||||||
cy.get('body').type('{shift}', { release: true });
|
cy.get('body').type('{shift}', { release: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders an empty mini map', () => {
|
|
||||||
cy.get('.react-flow__minimap');
|
|
||||||
cy.get('.react-flow__minimap-node').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('adds two nodes', () => {
|
it('adds two nodes', () => {
|
||||||
cy.contains('add node').click();
|
cy.contains('add node').click();
|
||||||
cy.contains('add node').click();
|
cy.contains('add node').click();
|
||||||
@@ -41,9 +36,4 @@ describe('Empty Flow Rendering', () => {
|
|||||||
|
|
||||||
cy.get('.react-flow__edge').should('have.length', 1);
|
cy.get('.react-flow__edge').should('have.length', 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders mini map with two nodes', () => {
|
|
||||||
cy.get('.react-flow__minimap');
|
|
||||||
cy.get('.react-flow__minimap-node').should('have.length', 2);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,41 +27,41 @@ describe('Graph Utils Testing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('tests getOutgoers function', () => {
|
it('tests getOutgoers function', () => {
|
||||||
const outgoers = getOutgoers(nodes[0], elements);
|
const outgoers = getOutgoers(nodes[0], nodes, edges);
|
||||||
expect(outgoers.length).to.be.equal(2);
|
expect(outgoers.length).to.be.equal(2);
|
||||||
|
|
||||||
const noOutgoers = getOutgoers(nodes[2], elements);
|
const noOutgoers = getOutgoers(nodes[2], nodes, edges);
|
||||||
expect(noOutgoers.length).to.be.equal(0);
|
expect(noOutgoers.length).to.be.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tests getIncomers function', () => {
|
it('tests getIncomers function', () => {
|
||||||
const incomers = getIncomers(nodes[2], elements);
|
const incomers = getIncomers(nodes[2], nodes, edges);
|
||||||
expect(incomers.length).to.be.equal(2);
|
expect(incomers.length).to.be.equal(2);
|
||||||
|
|
||||||
const noIncomers = getIncomers(nodes[0], elements);
|
const noIncomers = getIncomers(nodes[0], nodes, edges);
|
||||||
expect(noIncomers.length).to.be.equal(0);
|
expect(noIncomers.length).to.be.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('tests addEdge function', () => {
|
describe('tests addEdge function', () => {
|
||||||
it('adds edge', () => {
|
it('adds edge', () => {
|
||||||
const newEdge = { source: '1', target: '4' };
|
const newEdge = { source: '1', target: '4' };
|
||||||
const nextElements = addEdge(newEdge, elements);
|
const nextEdges = addEdge(newEdge, edges);
|
||||||
|
|
||||||
expect(nextElements.length).to.be.equal(elements.length + 1);
|
expect(nextEdges.length).to.be.equal(edges.length + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tries to add existing edge', () => {
|
it('tries to add existing edge', () => {
|
||||||
const newEdge = { source: '2', target: '3' };
|
const newEdge = { source: '2', target: '3' };
|
||||||
const nextElements = addEdge(newEdge, elements);
|
const nextEdges = addEdge(newEdge, edges);
|
||||||
|
|
||||||
expect(nextElements.length).to.be.equal(elements.length);
|
expect(nextEdges.length).to.be.equal(edges.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tries to add invalid edge', () => {
|
it('tries to add invalid edge', () => {
|
||||||
const newEdge = { nosource: '1', notarget: '3' };
|
const newEdge = { nosource: '1', notarget: '3' };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
addEdge(newEdge, elements);
|
addEdge(newEdge, edges);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e.message);
|
console.log(e.message);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,16 @@ describe('Hidden Flow Rendering', () => {
|
|||||||
cy.visit('/hidden');
|
cy.visit('/hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders empty flow', () => {
|
||||||
|
cy.get('.react-flow__node').should('not.exist');
|
||||||
|
cy.get('.react-flow__edge').should('not.exist');
|
||||||
|
cy.get('.react-flow__minimap-node').should('not.exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toggles isHidden mode', () => {
|
||||||
|
cy.get('.react-flow__ishidden').click();
|
||||||
|
});
|
||||||
|
|
||||||
it('renders initial flow', () => {
|
it('renders initial flow', () => {
|
||||||
cy.get('.react-flow__renderer');
|
cy.get('.react-flow__renderer');
|
||||||
cy.get('.react-flow__node').should('have.length', 4);
|
cy.get('.react-flow__node').should('have.length', 4);
|
||||||
@@ -10,7 +20,7 @@ describe('Hidden Flow Rendering', () => {
|
|||||||
cy.get('.react-flow__minimap-node').should('have.length', 4);
|
cy.get('.react-flow__minimap-node').should('have.length', 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('toggles isHidden mode', () => {
|
it('toggles isHidden mode again', () => {
|
||||||
cy.get('.react-flow__ishidden').click();
|
cy.get('.react-flow__ishidden').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -19,14 +29,4 @@ describe('Hidden Flow Rendering', () => {
|
|||||||
cy.get('.react-flow__edge').should('not.exist');
|
cy.get('.react-flow__edge').should('not.exist');
|
||||||
cy.get('.react-flow__minimap-node').should('not.exist');
|
cy.get('.react-flow__minimap-node').should('not.exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('toggles isHidden mode again', () => {
|
|
||||||
cy.get('.react-flow__ishidden').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders initial flow', () => {
|
|
||||||
cy.get('.react-flow__node').should('have.length', 4);
|
|
||||||
cy.get('.react-flow__edge').should('have.length', 3);
|
|
||||||
cy.get('.react-flow__minimap-node').should('have.length', 4);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -120,12 +120,12 @@ describe('Interaction Flow Rendering', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('zooms by scroll', () => {
|
it('zooms by scroll', () => {
|
||||||
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
cy.get('.react-flow__renderer')
|
cy.get('.react-flow__pane')
|
||||||
.trigger('wheel', 'topLeft', { deltaY: 200 })
|
.trigger('wheel', 'topLeft', { deltaY: 200 })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeZoom).not.to.equal(styleAfterZoom);
|
expect(styleBeforeZoom).not.to.equal(styleAfterZoom);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -136,12 +136,12 @@ describe('Interaction Flow Rendering', () => {
|
|||||||
|
|
||||||
it('zooms by double click', () => {
|
it('zooms by double click', () => {
|
||||||
cy.get('.react-flow__controls-zoomout').click();
|
cy.get('.react-flow__controls-zoomout').click();
|
||||||
const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleBeforeZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
|
|
||||||
cy.get('.react-flow__renderer')
|
cy.get('.react-flow__pane')
|
||||||
.dblclick()
|
.dblclick()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform');
|
const styleAfterZoom = Cypress.$('.react-flow__viewport').css('transform');
|
||||||
expect(styleBeforeZoom).not.to.equal(styleAfterZoom);
|
expect(styleBeforeZoom).not.to.equal(styleAfterZoom);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ describe('Minimap Testing', () => {
|
|||||||
const viewBoxBeforeZoom = Cypress.$('.react-flow__minimap').attr('viewBox');
|
const viewBoxBeforeZoom = Cypress.$('.react-flow__minimap').attr('viewBox');
|
||||||
const maskPathBeforeZoom = Cypress.$('.react-flow__minimap-mask').attr('d');
|
const maskPathBeforeZoom = Cypress.$('.react-flow__minimap-mask').attr('d');
|
||||||
|
|
||||||
cy.get('.react-flow__renderer')
|
cy.get('.react-flow__pane')
|
||||||
.trigger('wheel', 'topLeft', { deltaY: -200 })
|
.trigger('wheel', 'topLeft', { deltaY: -200 })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const viewBoxAfterZoom = Cypress.$('.react-flow__minimap').attr('viewBox');
|
const viewBoxAfterZoom = Cypress.$('.react-flow__minimap').attr('viewBox');
|
||||||
@@ -53,7 +53,7 @@ describe('Minimap Testing', () => {
|
|||||||
// for d3 we have to pass the window to the event
|
// for d3 we have to pass the window to the event
|
||||||
// https://github.com/cypress-io/cypress/issues/3441
|
// https://github.com/cypress-io/cypress/issues/3441
|
||||||
cy.window().then((win) => {
|
cy.window().then((win) => {
|
||||||
cy.get('.react-flow__renderer')
|
cy.get('.react-flow__pane')
|
||||||
.trigger('mousedown', 'topLeft', { which: 1, view: win })
|
.trigger('mousedown', 'topLeft', { which: 1, view: win })
|
||||||
.trigger('mousemove', 'bottomLeft')
|
.trigger('mousemove', 'bottomLeft')
|
||||||
.trigger('mouseup', { force: true, view: win })
|
.trigger('mouseup', { force: true, view: win })
|
||||||
|
|||||||
+17
-115
@@ -1,130 +1,49 @@
|
|||||||
import { useState, MouseEvent, useCallback } from 'react';
|
import { useState, MouseEvent } from 'react';
|
||||||
|
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
addEdge,
|
addEdge,
|
||||||
Background,
|
Background,
|
||||||
MiniMap,
|
BackgroundVariant,
|
||||||
Controls,
|
FlowElement,
|
||||||
Node,
|
Node,
|
||||||
Edge,
|
Edge,
|
||||||
ReactFlowInstance,
|
|
||||||
Connection,
|
Connection,
|
||||||
MarkerType,
|
|
||||||
useNodesState,
|
useNodesState,
|
||||||
useEdgesState,
|
useEdgesState,
|
||||||
|
ReactFlowInstance,
|
||||||
} from 'react-flow-renderer';
|
} from 'react-flow-renderer';
|
||||||
import DebugNode from './DebugNode';
|
|
||||||
|
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||||
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
const onNodeClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
|
||||||
const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
|
||||||
|
|
||||||
const initialNodes: Node[] = [
|
const initialNodes: Node[] = [
|
||||||
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
|
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
data: { label: 'Node 4' },
|
|
||||||
position: { x: 100, y: 200 },
|
|
||||||
className: 'light',
|
|
||||||
style: { backgroundColor: 'rgba(255,50, 50, 0.5)', width: 500, height: 300 },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4a',
|
|
||||||
data: { label: 'Node 4a' },
|
|
||||||
position: { x: 15, y: 15 },
|
|
||||||
className: 'light',
|
|
||||||
parentNode: '4',
|
|
||||||
extent: 'parent',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4b',
|
|
||||||
data: { label: 'Node 4b' },
|
|
||||||
position: { x: 150, y: 50 },
|
|
||||||
className: 'light',
|
|
||||||
style: { backgroundColor: 'rgba(50, 50, 255, 0.5)', height: 200, width: 300 },
|
|
||||||
parentNode: '4',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4b1',
|
|
||||||
data: { label: 'Node 4b1' },
|
|
||||||
position: { x: 20, y: 20 },
|
|
||||||
className: 'light',
|
|
||||||
parentNode: '4b',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4b2',
|
|
||||||
data: { label: 'Node 4b2' },
|
|
||||||
position: { x: 100, y: 100 },
|
|
||||||
className: 'light',
|
|
||||||
parentNode: '4b',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5',
|
|
||||||
data: { label: 'Node 5' },
|
|
||||||
position: { x: 650, y: 250 },
|
|
||||||
className: 'light',
|
|
||||||
style: { backgroundColor: 'rgba(20 ,200, 255, 1.5)', width: 400, height: 150 },
|
|
||||||
zIndex: 1000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5a',
|
|
||||||
data: { label: 'Node 5a' },
|
|
||||||
position: { x: 25, y: 50 },
|
|
||||||
className: 'light',
|
|
||||||
parentNode: '5',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5b',
|
|
||||||
data: { label: 'Node 5b' },
|
|
||||||
position: { x: 225, y: 50 },
|
|
||||||
className: 'light',
|
|
||||||
parentNode: '5',
|
|
||||||
},
|
|
||||||
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
|
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
|
||||||
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
|
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
|
||||||
|
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const initialEdges: Edge[] = [
|
const initialEdges: Edge[] = [
|
||||||
{
|
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
||||||
id: 'e1-2',
|
|
||||||
source: '1',
|
|
||||||
target: '2',
|
|
||||||
markerEnd: { type: MarkerType.Arrow, strokeWidth: 2, width: 15, height: 15, color: '#f00' },
|
|
||||||
},
|
|
||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
{ id: 'e3-4', source: '3', target: '4', zIndex: 100 },
|
|
||||||
{ id: 'e3-4b', source: '3', target: '4b' },
|
|
||||||
{ id: 'e4a-4b1', source: '4a', target: '4b1' },
|
|
||||||
{ id: 'e4a-4b2', source: '4a', target: '4b2', zIndex: 100 },
|
|
||||||
{ id: 'e4b1-4b2', source: '4b1', target: '4b2' },
|
|
||||||
{ id: '3-5', source: '3', target: '5' },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const nodeTypes = {
|
|
||||||
default: DebugNode,
|
|
||||||
};
|
|
||||||
|
|
||||||
const BasicFlow = () => {
|
const BasicFlow = () => {
|
||||||
const [rfInstance, setRfInstance] = useState<ReactFlowInstance | null>(null);
|
const [rfInstance, setRfInstance] = useState<ReactFlowInstance | null>(null);
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||||
|
const onConnect = (params: Edge | Connection) => setEdges((els) => addEdge(params, els));
|
||||||
const onConnect = useCallback((connection: Connection) => {
|
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => setRfInstance(reactFlowInstance);
|
||||||
setEdges((eds) => {
|
|
||||||
return addEdge(connection, eds);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
const onPaneReady = useCallback((reactFlowInstance: ReactFlowInstance) => setRfInstance(reactFlowInstance), []);
|
|
||||||
|
|
||||||
const updatePos = () => {
|
const updatePos = () => {
|
||||||
setNodes((nds) => {
|
setNodes((nds) => {
|
||||||
return nds.map((n) => {
|
return nds.map((node) => {
|
||||||
n.position = {
|
node.position = {
|
||||||
x: Math.random() * 400,
|
x: Math.random() * 400,
|
||||||
y: Math.random() * 400,
|
y: Math.random() * 400,
|
||||||
};
|
};
|
||||||
|
|
||||||
return n;
|
return node;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -134,18 +53,10 @@ const BasicFlow = () => {
|
|||||||
|
|
||||||
const toggleClassnames = () => {
|
const toggleClassnames = () => {
|
||||||
setNodes((nds) => {
|
setNodes((nds) => {
|
||||||
return nds.map((n) => {
|
return nds.map((node) => {
|
||||||
n.className = n.className === 'light' ? 'dark' : 'light';
|
node.className = node.className === 'light' ? 'dark' : 'light';
|
||||||
return n;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleChildNodes = () => {
|
return node;
|
||||||
setNodes((nds) => {
|
|
||||||
return nds.map((n) => {
|
|
||||||
n.hidden = !!n.parentNode && !n.hidden;
|
|
||||||
return n;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -154,24 +65,18 @@ const BasicFlow = () => {
|
|||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
onPaneReady={onPaneReady}
|
|
||||||
onNodesChange={onNodesChange}
|
onNodesChange={onNodesChange}
|
||||||
onEdgesChange={onEdgesChange}
|
onEdgesChange={onEdgesChange}
|
||||||
|
onPaneReady={onPaneReady}
|
||||||
onNodeClick={onNodeClick}
|
onNodeClick={onNodeClick}
|
||||||
onEdgeClick={onEdgeClick}
|
|
||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
className="react-flow-basic-example"
|
className="react-flow-basic-example"
|
||||||
defaultZoom={1.5}
|
defaultZoom={1.5}
|
||||||
minZoom={0.2}
|
minZoom={0.2}
|
||||||
maxZoom={4}
|
maxZoom={4}
|
||||||
onlyRenderVisibleElements={false}
|
|
||||||
nodeTypes={nodeTypes}
|
|
||||||
fitViewOnInit
|
|
||||||
>
|
>
|
||||||
<MiniMap />
|
<Background variant={BackgroundVariant.Lines} />
|
||||||
<Controls />
|
|
||||||
<Background />
|
|
||||||
|
|
||||||
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||||
<button onClick={resetTransform} style={{ marginRight: 5 }}>
|
<button onClick={resetTransform} style={{ marginRight: 5 }}>
|
||||||
@@ -183,9 +88,6 @@ const BasicFlow = () => {
|
|||||||
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
|
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
|
||||||
toggle classnames
|
toggle classnames
|
||||||
</button>
|
</button>
|
||||||
<button style={{ marginRight: 5 }} onClick={toggleChildNodes}>
|
|
||||||
toggleChildNodes
|
|
||||||
</button>
|
|
||||||
<button onClick={logToObject}>toObject</button>
|
<button onClick={logToObject}>toObject</button>
|
||||||
</div>
|
</div>
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import ReactFlow, { Node, Edge, useNodesState, useEdgesState } from 'react-flow-renderer';
|
||||||
|
|
||||||
|
import DragHandleNode from './DragHandleNode';
|
||||||
|
|
||||||
|
const nodeTypes = {
|
||||||
|
dragHandleNode: DragHandleNode,
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialNodes: Node[] = [
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
type: 'dragHandleNode',
|
||||||
|
dragHandle: '.custom-drag-handle',
|
||||||
|
style: { border: '1px solid #ddd', padding: '20px 40px' },
|
||||||
|
position: { x: 200, y: 200 },
|
||||||
|
data: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const initialEdges: Edge[] = [];
|
||||||
|
|
||||||
|
const DragHandleFlow = () => {
|
||||||
|
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||||
|
const [edges] = useEdgesState(initialEdges);
|
||||||
|
|
||||||
|
return <ReactFlow nodes={nodes} onNodesChange={onNodesChange} edges={edges} nodeTypes={nodeTypes} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DragHandleFlow;
|
||||||
@@ -1,52 +1,51 @@
|
|||||||
import React, { useState, MouseEvent, CSSProperties } from 'react';
|
import { MouseEvent, CSSProperties } from 'react';
|
||||||
|
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
removeElements,
|
|
||||||
addEdge,
|
addEdge,
|
||||||
MiniMap,
|
|
||||||
Controls,
|
Controls,
|
||||||
Background,
|
Background,
|
||||||
OnLoadParams,
|
|
||||||
Elements,
|
|
||||||
ElementId,
|
|
||||||
Node,
|
Node,
|
||||||
FlowElement,
|
|
||||||
BackgroundVariant,
|
BackgroundVariant,
|
||||||
Connection,
|
Connection,
|
||||||
Edge,
|
Edge,
|
||||||
|
useNodesState,
|
||||||
|
useEdgesState,
|
||||||
|
ReactFlowInstance,
|
||||||
} from 'react-flow-renderer';
|
} from 'react-flow-renderer';
|
||||||
|
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => console.log('flow loaded:', reactFlowInstance);
|
const onPaneReady = (reactFlowInstance: ReactFlowInstance) => console.log('flow loaded:', reactFlowInstance);
|
||||||
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
|
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||||
|
|
||||||
const buttonStyle: CSSProperties = { position: 'absolute', left: 10, top: 10, zIndex: 4 };
|
const buttonStyle: CSSProperties = { position: 'absolute', left: 10, top: 10, zIndex: 4 };
|
||||||
|
|
||||||
const EmptyFlow = () => {
|
const EmptyFlow = () => {
|
||||||
const [elements, setElements] = useState<Elements>([]);
|
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
||||||
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
|
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
||||||
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
|
|
||||||
|
const onConnect = (params: Connection | Edge) => setEdges((els) => addEdge(params, els));
|
||||||
const addRandomNode = () => {
|
const addRandomNode = () => {
|
||||||
const nodeId: ElementId = (elements.length + 1).toString();
|
const nodeId = (nodes.length + 1).toString();
|
||||||
const newNode: Node = {
|
const newNode: Node = {
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
data: { label: `Node: ${nodeId}` },
|
data: { label: `Node: ${nodeId}` },
|
||||||
position: { x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight },
|
position: { x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight },
|
||||||
};
|
};
|
||||||
setElements((els) => els.concat(newNode));
|
setNodes((nds) => nds.concat(newNode));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
elements={elements}
|
nodes={nodes}
|
||||||
onLoad={onLoad}
|
edges={edges}
|
||||||
onElementClick={onElementClick}
|
onPaneReady={onPaneReady}
|
||||||
onElementsRemove={onElementsRemove}
|
onNodesChange={onNodesChange}
|
||||||
|
onEdgesChange={onEdgesChange}
|
||||||
|
onNodeClick={onNodeClick}
|
||||||
onConnect={(p) => onConnect(p)}
|
onConnect={(p) => onConnect(p)}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
onlyRenderVisibleElements={false}
|
onlyRenderVisibleElements={false}
|
||||||
>
|
>
|
||||||
<MiniMap />
|
|
||||||
<Controls />
|
<Controls />
|
||||||
<Background variant={BackgroundVariant.Lines} />
|
<Background variant={BackgroundVariant.Lines} />
|
||||||
|
|
||||||
@@ -1,37 +1,42 @@
|
|||||||
import React, { useState, MouseEvent, WheelEvent } from 'react';
|
import { useState, MouseEvent, WheelEvent } from 'react';
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
addEdge,
|
addEdge,
|
||||||
MiniMap,
|
MiniMap,
|
||||||
Controls,
|
Controls,
|
||||||
Elements,
|
|
||||||
Node,
|
Node,
|
||||||
FlowElement,
|
|
||||||
Connection,
|
Connection,
|
||||||
Edge,
|
Edge,
|
||||||
PanOnScrollMode,
|
PanOnScrollMode,
|
||||||
FlowTransform,
|
FlowTransform,
|
||||||
|
useNodesState,
|
||||||
|
useEdgesState,
|
||||||
} from 'react-flow-renderer';
|
} from 'react-flow-renderer';
|
||||||
|
|
||||||
const initialElements: Elements = [
|
const initialNodes: Node[] = [
|
||||||
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
|
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
|
||||||
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
|
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
|
||||||
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } },
|
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } },
|
||||||
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } },
|
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } },
|
||||||
|
];
|
||||||
|
|
||||||
|
const initialEdges: Edge[] = [
|
||||||
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const onNodeDragStart = (_: MouseEvent, node: Node) => console.log('drag start', node);
|
const onNodeDragStart = (_: MouseEvent, node: Node) => console.log('drag start', node);
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||||
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
|
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
||||||
|
const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
||||||
const onPaneClick = (event: MouseEvent) => console.log('onPaneClick', event);
|
const onPaneClick = (event: MouseEvent) => console.log('onPaneClick', event);
|
||||||
const onPaneScroll = (event?: WheelEvent) => console.log('onPaneScroll', event);
|
const onPaneScroll = (event?: WheelEvent) => console.log('onPaneScroll', event);
|
||||||
const onPaneContextMenu = (event: MouseEvent) => console.log('onPaneContextMenu', event);
|
const onPaneContextMenu = (event: MouseEvent) => console.log('onPaneContextMenu', event);
|
||||||
const onMoveEnd = (flowTranasform?: FlowTransform) => console.log('onMoveEnd', flowTranasform);
|
const onMoveEnd = (flowTranasform?: FlowTransform) => console.log('onMoveEnd', flowTranasform);
|
||||||
|
|
||||||
const InteractionFlow = () => {
|
const InteractionFlow = () => {
|
||||||
const [elements, setElements] = useState<Elements>(initialElements);
|
const [nodes, , onNodesChange] = useNodesState(initialNodes);
|
||||||
const onConnect = (params: Connection | Edge) => setElements((els) => addEdge(params, els));
|
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||||
|
const onConnect = (params: Connection | Edge) => setEdges((els) => addEdge(params, els));
|
||||||
|
|
||||||
const [isSelectable, setIsSelectable] = useState<boolean>(false);
|
const [isSelectable, setIsSelectable] = useState<boolean>(false);
|
||||||
const [isDraggable, setIsDraggable] = useState<boolean>(false);
|
const [isDraggable, setIsDraggable] = useState<boolean>(false);
|
||||||
@@ -46,9 +51,14 @@ const InteractionFlow = () => {
|
|||||||
const [captureZoomScroll, setCaptureZoomScroll] = useState<boolean>(false);
|
const [captureZoomScroll, setCaptureZoomScroll] = useState<boolean>(false);
|
||||||
const [captureElementClick, setCaptureElementClick] = useState<boolean>(false);
|
const [captureElementClick, setCaptureElementClick] = useState<boolean>(false);
|
||||||
|
|
||||||
|
console.log(11, captureElementClick);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
elements={elements}
|
nodes={nodes}
|
||||||
|
edges={edges}
|
||||||
|
onNodesChange={onNodesChange}
|
||||||
|
onEdgesChange={onEdgesChange}
|
||||||
elementsSelectable={isSelectable}
|
elementsSelectable={isSelectable}
|
||||||
nodesConnectable={isConnectable}
|
nodesConnectable={isConnectable}
|
||||||
nodesDraggable={isDraggable}
|
nodesDraggable={isDraggable}
|
||||||
@@ -58,7 +68,8 @@ const InteractionFlow = () => {
|
|||||||
panOnScrollMode={panOnScrollMode}
|
panOnScrollMode={panOnScrollMode}
|
||||||
zoomOnDoubleClick={zoomOnDoubleClick}
|
zoomOnDoubleClick={zoomOnDoubleClick}
|
||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
onElementClick={captureElementClick ? onElementClick : undefined}
|
onNodeClick={captureElementClick ? onNodeClick : undefined}
|
||||||
|
onEdgeClick={captureElementClick ? onEdgeClick : undefined}
|
||||||
onNodeDragStart={onNodeDragStart}
|
onNodeDragStart={onNodeDragStart}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
paneMoveable={paneMoveable}
|
paneMoveable={paneMoveable}
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
import { useState, MouseEvent, useCallback } from 'react';
|
||||||
|
|
||||||
|
import ReactFlow, {
|
||||||
|
addEdge,
|
||||||
|
Background,
|
||||||
|
MiniMap,
|
||||||
|
Controls,
|
||||||
|
Node,
|
||||||
|
Edge,
|
||||||
|
ReactFlowInstance,
|
||||||
|
Connection,
|
||||||
|
MarkerType,
|
||||||
|
useNodesState,
|
||||||
|
useEdgesState,
|
||||||
|
} from 'react-flow-renderer';
|
||||||
|
import DebugNode from './DebugNode';
|
||||||
|
|
||||||
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||||
|
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
||||||
|
const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
||||||
|
|
||||||
|
const initialNodes: Node[] = [
|
||||||
|
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
|
||||||
|
{
|
||||||
|
id: '4',
|
||||||
|
data: { label: 'Node 4' },
|
||||||
|
position: { x: 100, y: 200 },
|
||||||
|
className: 'light',
|
||||||
|
style: { backgroundColor: 'rgba(255,50, 50, 0.5)', width: 500, height: 300 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4a',
|
||||||
|
data: { label: 'Node 4a' },
|
||||||
|
position: { x: 15, y: 15 },
|
||||||
|
className: 'light',
|
||||||
|
parentNode: '4',
|
||||||
|
extent: 'parent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4b',
|
||||||
|
data: { label: 'Node 4b' },
|
||||||
|
position: { x: 150, y: 50 },
|
||||||
|
className: 'light',
|
||||||
|
style: { backgroundColor: 'rgba(50, 50, 255, 0.5)', height: 200, width: 300 },
|
||||||
|
parentNode: '4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4b1',
|
||||||
|
data: { label: 'Node 4b1' },
|
||||||
|
position: { x: 20, y: 20 },
|
||||||
|
className: 'light',
|
||||||
|
parentNode: '4b',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4b2',
|
||||||
|
data: { label: 'Node 4b2' },
|
||||||
|
position: { x: 100, y: 100 },
|
||||||
|
className: 'light',
|
||||||
|
parentNode: '4b',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5',
|
||||||
|
data: { label: 'Node 5' },
|
||||||
|
position: { x: 650, y: 250 },
|
||||||
|
className: 'light',
|
||||||
|
style: { backgroundColor: 'rgba(20 ,200, 255, 1.5)', width: 400, height: 150 },
|
||||||
|
zIndex: 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5a',
|
||||||
|
data: { label: 'Node 5a' },
|
||||||
|
position: { x: 25, y: 50 },
|
||||||
|
className: 'light',
|
||||||
|
parentNode: '5',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5b',
|
||||||
|
data: { label: 'Node 5b' },
|
||||||
|
position: { x: 225, y: 50 },
|
||||||
|
className: 'light',
|
||||||
|
parentNode: '5',
|
||||||
|
},
|
||||||
|
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
|
||||||
|
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const initialEdges: Edge[] = [
|
||||||
|
{
|
||||||
|
id: 'e1-2',
|
||||||
|
source: '1',
|
||||||
|
target: '2',
|
||||||
|
markerEnd: { type: MarkerType.Arrow, strokeWidth: 2, width: 15, height: 15, color: '#f00' },
|
||||||
|
},
|
||||||
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
|
{ id: 'e3-4', source: '3', target: '4', zIndex: 100 },
|
||||||
|
{ id: 'e3-4b', source: '3', target: '4b' },
|
||||||
|
{ id: 'e4a-4b1', source: '4a', target: '4b1' },
|
||||||
|
{ id: 'e4a-4b2', source: '4a', target: '4b2', zIndex: 100 },
|
||||||
|
{ id: 'e4b1-4b2', source: '4b1', target: '4b2' },
|
||||||
|
{ id: '3-5', source: '3', target: '5' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const nodeTypes = {
|
||||||
|
default: DebugNode,
|
||||||
|
};
|
||||||
|
|
||||||
|
const BasicFlow = () => {
|
||||||
|
const [rfInstance, setRfInstance] = useState<ReactFlowInstance | null>(null);
|
||||||
|
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||||
|
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||||
|
|
||||||
|
const onConnect = useCallback((connection: Connection) => {
|
||||||
|
setEdges((eds) => {
|
||||||
|
return addEdge(connection, eds);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
const onPaneReady = useCallback((reactFlowInstance: ReactFlowInstance) => setRfInstance(reactFlowInstance), []);
|
||||||
|
|
||||||
|
const updatePos = () => {
|
||||||
|
setNodes((nds) => {
|
||||||
|
return nds.map((n) => {
|
||||||
|
n.position = {
|
||||||
|
x: Math.random() * 400,
|
||||||
|
y: Math.random() * 400,
|
||||||
|
};
|
||||||
|
|
||||||
|
return n;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const logToObject = () => console.log(rfInstance?.toObject());
|
||||||
|
const resetTransform = () => rfInstance?.setTransform({ x: 0, y: 0, zoom: 1 });
|
||||||
|
|
||||||
|
const toggleClassnames = () => {
|
||||||
|
setNodes((nds) => {
|
||||||
|
return nds.map((n) => {
|
||||||
|
n.className = n.className === 'light' ? 'dark' : 'light';
|
||||||
|
return n;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleChildNodes = () => {
|
||||||
|
setNodes((nds) => {
|
||||||
|
return nds.map((n) => {
|
||||||
|
n.hidden = !!n.parentNode && !n.hidden;
|
||||||
|
return n;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactFlow
|
||||||
|
nodes={nodes}
|
||||||
|
edges={edges}
|
||||||
|
onPaneReady={onPaneReady}
|
||||||
|
onNodesChange={onNodesChange}
|
||||||
|
onEdgesChange={onEdgesChange}
|
||||||
|
onNodeClick={onNodeClick}
|
||||||
|
onEdgeClick={onEdgeClick}
|
||||||
|
onConnect={onConnect}
|
||||||
|
onNodeDragStop={onNodeDragStop}
|
||||||
|
className="react-flow-basic-example"
|
||||||
|
defaultZoom={1.5}
|
||||||
|
minZoom={0.2}
|
||||||
|
maxZoom={4}
|
||||||
|
onlyRenderVisibleElements={false}
|
||||||
|
nodeTypes={nodeTypes}
|
||||||
|
fitViewOnInit
|
||||||
|
>
|
||||||
|
<MiniMap />
|
||||||
|
<Controls />
|
||||||
|
<Background />
|
||||||
|
|
||||||
|
<div style={{ position: 'absolute', right: 10, top: 10, zIndex: 4 }}>
|
||||||
|
<button onClick={resetTransform} style={{ marginRight: 5 }}>
|
||||||
|
reset transform
|
||||||
|
</button>
|
||||||
|
<button onClick={updatePos} style={{ marginRight: 5 }}>
|
||||||
|
change pos
|
||||||
|
</button>
|
||||||
|
<button onClick={toggleClassnames} style={{ marginRight: 5 }}>
|
||||||
|
toggle classnames
|
||||||
|
</button>
|
||||||
|
<button style={{ marginRight: 5 }} onClick={toggleChildNodes}>
|
||||||
|
toggleChildNodes
|
||||||
|
</button>
|
||||||
|
<button onClick={logToObject}>toObject</button>
|
||||||
|
</div>
|
||||||
|
</ReactFlow>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BasicFlow;
|
||||||
@@ -13,6 +13,10 @@ import NestedNodes from './NestedNodes';
|
|||||||
import Hidden from './Hidden';
|
import Hidden from './Hidden';
|
||||||
import UpdatableEdge from './UpdatableEdge';
|
import UpdatableEdge from './UpdatableEdge';
|
||||||
import TouchDevice from './TouchDevice';
|
import TouchDevice from './TouchDevice';
|
||||||
|
import Subflow from './Subflow';
|
||||||
|
import Interaction from './Interaction';
|
||||||
|
import Empty from './Empty';
|
||||||
|
import DragHandle from './DragHandle';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@@ -61,6 +65,22 @@ const routes = [
|
|||||||
path: '/touch-device',
|
path: '/touch-device',
|
||||||
component: TouchDevice,
|
component: TouchDevice,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/subflow',
|
||||||
|
component: Subflow,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/interaction',
|
||||||
|
component: Interaction,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/empty',
|
||||||
|
component: Empty,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/draghandle',
|
||||||
|
component: DragHandle,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const Header = withRouter(({ history, location }) => {
|
const Header = withRouter(({ history, location }) => {
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
import ReactFlow from 'react-flow-renderer';
|
|
||||||
|
|
||||||
import DragHandleNode from './DragHandleNode';
|
|
||||||
|
|
||||||
const nodeTypes = {
|
|
||||||
dragHandleNode: DragHandleNode,
|
|
||||||
};
|
|
||||||
|
|
||||||
const elements = [
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
type: 'dragHandleNode',
|
|
||||||
dragHandle: '.custom-drag-handle',
|
|
||||||
style: { border: '1px solid #ddd', padding: '20px 40px' },
|
|
||||||
position: { x: 200, y: 200 },
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const DragHandleFlow = () => <ReactFlow elements={elements} nodeTypes={nodeTypes} />;
|
|
||||||
|
|
||||||
export default DragHandleFlow;
|
|
||||||
Reference in New Issue
Block a user