@@ -19,6 +19,7 @@ React Flow is a library for building node-based graphs. You can easily implement
|
|||||||
- [Background](#background)
|
- [Background](#background)
|
||||||
- [Minimap](#minimap)
|
- [Minimap](#minimap)
|
||||||
- [Controls](#controls)
|
- [Controls](#controls)
|
||||||
|
- [ReactFlowProvider](#reactflowprovider)
|
||||||
- [Styling](#styling)
|
- [Styling](#styling)
|
||||||
- [Helper Functions](#helper-functions)
|
- [Helper Functions](#helper-functions)
|
||||||
- [Access Internal State](#access-internal-state)
|
- [Access Internal State](#access-internal-state)
|
||||||
@@ -132,7 +133,7 @@ Fits view port so that all nodes are visible
|
|||||||
|
|
||||||
# Nodes
|
# Nodes
|
||||||
|
|
||||||
There are three different [node types](#node-types--custom-nodes) (`default`, `input`, `output`) you can use. The node types differ in the number and types of handles. An input node has only a source handle, a default node has a source and a target and an output node has only a target handle. You create nodes by adding them to the `elements` array of the React Flow component.
|
There are three different [node types](#node-types--custom-nodes) (`default`, `input`, `output`) you can use. The node types differ in the number and types of handles. An input node has only a source handle, a default node has a source and a target and an output node has only a target handle. You create nodes by adding them to the `elements` array of the `ReactFlow` component.
|
||||||
|
|
||||||
Node example: `{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }`
|
Node example: `{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }`
|
||||||
|
|
||||||
@@ -160,7 +161,7 @@ The standard node types are `input`, `default` and `output`. The default node ty
|
|||||||
```
|
```
|
||||||
|
|
||||||
The keys represent the type names and the values are the components that get rendered.
|
The keys represent the type names and the values are the components that get rendered.
|
||||||
If you want to introduce a new type you can pass a `nodeTypes` object to the React Flow component:
|
If you want to introduce a new type you can pass a `nodeTypes` object to the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
nodeTypes={{
|
nodeTypes={{
|
||||||
@@ -222,7 +223,7 @@ You can find an example of how to implement a custom node with multiple handles
|
|||||||
|
|
||||||
# Edges
|
# Edges
|
||||||
|
|
||||||
React Flow comes with three [edge types](#edge-types--custom-edges) (`straight`, `default`, `step`). As the names indicate, the edges differ in the representation. The default type is a bezier edge. You create edges by adding them to your `elements` array of the React Flow component.
|
React Flow comes with three [edge types](#edge-types--custom-edges) (`straight`, `default`, `step`). As the names indicate, the edges differ in the representation. The default type is a bezier edge. You create edges by adding them to your `elements` array of the `ReactFlow` component.
|
||||||
|
|
||||||
Edge example: `{ id: 'e1-2', type: 'straight', source: '1', target: '2', animated: true, label: 'edge label' }`
|
Edge example: `{ id: 'e1-2', type: 'straight', source: '1', target: '2', animated: true, label: 'edge label' }`
|
||||||
|
|
||||||
@@ -256,7 +257,7 @@ The basic edge types are `straight`, `default` and `step`. The default `edgeType
|
|||||||
```
|
```
|
||||||
|
|
||||||
The keys represent the type names and the values are the edge components.
|
The keys represent the type names and the values are the edge components.
|
||||||
If you want to introduce a new edge type you can pass an `edgeTypes` object to the React Flow component:
|
If you want to introduce a new edge type you can pass an `edgeTypes` object to the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
edgeTypes={{
|
edgeTypes={{
|
||||||
@@ -272,7 +273,7 @@ There is an implementation of a custom edge in the [edges example](/example/src/
|
|||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
React Flow comes with two background variants: **dots** and **lines**. You can use it by passing it as a children to the React Flow component:
|
React Flow comes with two background variants: **dots** and **lines**. You can use it by passing it as a children to the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import ReactFlow, { Background } from 'react-flow-renderer';
|
import ReactFlow, { Background } from 'react-flow-renderer';
|
||||||
@@ -299,7 +300,7 @@ const FlowWithBackground = () => (
|
|||||||
|
|
||||||
## MiniMap
|
## MiniMap
|
||||||
|
|
||||||
You can use the mini map plugin by passing it as a children to the React Flow component:
|
You can use the mini map plugin by passing it as a children to the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import ReactFlow, { MiniMap } from 'react-flow-renderer';
|
import ReactFlow, { MiniMap } from 'react-flow-renderer';
|
||||||
@@ -330,7 +331,7 @@ const FlowWithMiniMap = () => (
|
|||||||
|
|
||||||
## Controls
|
## Controls
|
||||||
|
|
||||||
The control panel contains a zoom-in, zoom-out, fit-view and a lock/unlock button. You can use it by passing it as a children to the React Flow component:
|
The control panel contains a zoom-in, zoom-out, fit-view and a lock/unlock button. You can use it by passing it as a children to the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import ReactFlow, { Controls } from 'react-flow-renderer';
|
import ReactFlow, { Controls } from 'react-flow-renderer';
|
||||||
@@ -350,6 +351,25 @@ const FlowWithControls = () => (
|
|||||||
- `style`: css properties
|
- `style`: css properties
|
||||||
- `className`: additional class name
|
- `className`: additional class name
|
||||||
|
|
||||||
|
## ReactFlowProvider
|
||||||
|
|
||||||
|
If you need access to the internal state and action of React Flow outside of the `ReactFlow` component you can wrap it with the `ReactFlowProvider` component:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import ReactFlow, { ReactFlowProvider } from 'react-flow-renderer';
|
||||||
|
|
||||||
|
const FlowWithOwnProvider = () => (
|
||||||
|
<ReactFlowProvider>
|
||||||
|
<ReactFlow
|
||||||
|
elements={elements}
|
||||||
|
onElementClick={onElementClick}
|
||||||
|
onConnect={onConnect}
|
||||||
|
/>
|
||||||
|
</ReactFlowProvider>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# Styling
|
# Styling
|
||||||
|
|
||||||
There are two ways how you can style the graph pane and the elements.
|
There are two ways how you can style the graph pane and the elements.
|
||||||
@@ -401,7 +421,7 @@ The React Flow wrapper has the className `react-flow`. If you want to change the
|
|||||||
|
|
||||||
## Using Properties
|
## Using Properties
|
||||||
|
|
||||||
You could achieve the same effect by passing a style prop to the React Flow component:
|
You could achieve the same effect by passing a style prop to the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const FlowWithRedBg = (
|
const FlowWithRedBg = (
|
||||||
@@ -450,7 +470,7 @@ You can use these function as seen in [this example](/example/src/Overview/index
|
|||||||
# Access Internal State
|
# Access Internal State
|
||||||
|
|
||||||
Under the hood React Flow uses [Easy Peasy](https://easy-peasy.now.sh/) for state handling.
|
Under the hood React Flow uses [Easy Peasy](https://easy-peasy.now.sh/) for state handling.
|
||||||
If you need to access the internal state you can use the `useStoreState` hook inside a child component of the React Flow component:
|
If you need to access the internal state you can use the `useStoreState` hook inside a child component of the `ReactFlow` component:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import ReactFlow, { useStoreState } from 'react-flow-renderer';
|
import ReactFlow, { useStoreState } from 'react-flow-renderer';
|
||||||
@@ -470,6 +490,8 @@ const Flow = () => (
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you need more control you can wrap the `ReactFlow` component with the `ReactFlowProvider` component in order to be able to call `useStoreState` outside of the `ReactFlow` component.
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
You can find all examples in the [example](example) folder or check out the live versions:
|
You can find all examples in the [example](example) folder or check out the live versions:
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import ReactFlow, { addEdge, ReactFlowProvider } from 'react-flow-renderer';
|
||||||
|
|
||||||
|
const onElementClick = element => console.log('click', element);
|
||||||
|
|
||||||
|
const initialElements = [
|
||||||
|
{ 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: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 } },
|
||||||
|
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 } },
|
||||||
|
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
||||||
|
{ id: 'e1-3', source: '1', target: '3' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const ProviderFlow = () => {
|
||||||
|
const [elements, setElements] = useState(initialElements);
|
||||||
|
const onConnect = (params) => setElements(els => addEdge(params, els));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactFlowProvider>
|
||||||
|
<ReactFlow
|
||||||
|
elements={elements}
|
||||||
|
onElementClick={onElementClick}
|
||||||
|
onConnect={onConnect}
|
||||||
|
/>
|
||||||
|
</ReactFlowProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProviderFlow;
|
||||||
@@ -11,6 +11,7 @@ import Empty from './Empty';
|
|||||||
import Edges from './Edges';
|
import Edges from './Edges';
|
||||||
import Validation from './Validation';
|
import Validation from './Validation';
|
||||||
import Horizontal from './Horizontal';
|
import Horizontal from './Horizontal';
|
||||||
|
import Provider from './Provider';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@@ -19,9 +20,9 @@ const routes = [{
|
|||||||
component: Overview,
|
component: Overview,
|
||||||
label: 'Overview'
|
label: 'Overview'
|
||||||
}, {
|
}, {
|
||||||
path: '/basic',
|
path: '/provider',
|
||||||
component: Basic,
|
component: Provider,
|
||||||
label: 'Basic'
|
label: 'Provider'
|
||||||
}, {
|
}, {
|
||||||
path: '/edges',
|
path: '/edges',
|
||||||
component: Edges,
|
component: Edges,
|
||||||
@@ -42,6 +43,9 @@ const routes = [{
|
|||||||
path: '/stress',
|
path: '/stress',
|
||||||
component: Stress,
|
component: Stress,
|
||||||
label: 'Stress'
|
label: 'Stress'
|
||||||
|
}, {
|
||||||
|
path: '/basic',
|
||||||
|
component: Basic
|
||||||
}, {
|
}, {
|
||||||
path: '/empty',
|
path: '/empty',
|
||||||
component: Empty
|
component: Empty
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export default [
|
|||||||
}),
|
}),
|
||||||
replace({
|
replace({
|
||||||
'process.env.NODE_ENV': JSON.stringify(processEnv),
|
'process.env.NODE_ENV': JSON.stringify(processEnv),
|
||||||
|
__REACT_FLOW_VERSION__: JSON.stringify(pkg.version),
|
||||||
}),
|
}),
|
||||||
svgr(),
|
svgr(),
|
||||||
typescript({
|
typescript({
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import React, { useMemo, FC } from 'react';
|
||||||
|
import { StoreProvider, createStore } from 'easy-peasy';
|
||||||
|
|
||||||
|
import { storeModel } from '../../store';
|
||||||
|
|
||||||
|
const ReactFlowProvider: FC = ({ children }) => {
|
||||||
|
const store = useMemo(() => {
|
||||||
|
return createStore(storeModel);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <StoreProvider store={store}>{children}</StoreProvider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactFlowProvider.displayName = 'ReactFlowProvider';
|
||||||
|
|
||||||
|
export default ReactFlowProvider;
|
||||||
@@ -4,3 +4,4 @@
|
|||||||
export { default as MiniMap } from './MiniMap';
|
export { default as MiniMap } from './MiniMap';
|
||||||
export { default as Controls } from './Controls';
|
export { default as Controls } from './Controls';
|
||||||
export { default as Background } from './Background';
|
export { default as Background } from './Background';
|
||||||
|
export { default as ReactFlowProvider } from './ReactFlowProvider';
|
||||||
|
|||||||
@@ -2,10 +2,20 @@ import React, { useEffect, useRef, useState, memo, ComponentType, CSSProperties
|
|||||||
import { DraggableCore } from 'react-draggable';
|
import { DraggableCore } from 'react-draggable';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { ResizeObserver } from 'resize-observer';
|
import { ResizeObserver } from 'resize-observer';
|
||||||
|
import { useStoreActions } from '../../store/hooks';
|
||||||
|
|
||||||
import { Provider } from '../../contexts/NodeIdContext';
|
import { Provider } from '../../contexts/NodeIdContext';
|
||||||
import store from '../../store';
|
import {
|
||||||
import { Node, XYPosition, Transform, ElementId, NodeComponentProps, WrapNodeProps } from '../../types';
|
Node,
|
||||||
|
XYPosition,
|
||||||
|
Transform,
|
||||||
|
ElementId,
|
||||||
|
NodeComponentProps,
|
||||||
|
WrapNodeProps,
|
||||||
|
Elements,
|
||||||
|
Edge,
|
||||||
|
NodePosUpdate,
|
||||||
|
} from '../../types';
|
||||||
|
|
||||||
const getMouseEvent = (evt: MouseEvent | TouchEvent) =>
|
const getMouseEvent = (evt: MouseEvent | TouchEvent) =>
|
||||||
typeof TouchEvent !== 'undefined' && evt instanceof TouchEvent ? evt.touches[0] : (evt as MouseEvent);
|
typeof TouchEvent !== 'undefined' && evt instanceof TouchEvent ? evt.touches[0] : (evt as MouseEvent);
|
||||||
@@ -19,6 +29,7 @@ interface OnDragStartParams {
|
|||||||
setOffset: (pos: XYPosition) => void;
|
setOffset: (pos: XYPosition) => void;
|
||||||
transform: Transform;
|
transform: Transform;
|
||||||
position: XYPosition;
|
position: XYPosition;
|
||||||
|
setSelectedElements: (elms: Elements | Node | Edge) => void;
|
||||||
onNodeDragStart?: (node: Node) => void;
|
onNodeDragStart?: (node: Node) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +43,7 @@ const onStart = ({
|
|||||||
setOffset,
|
setOffset,
|
||||||
transform,
|
transform,
|
||||||
position,
|
position,
|
||||||
|
setSelectedElements,
|
||||||
}: OnDragStartParams): false | void => {
|
}: OnDragStartParams): false | void => {
|
||||||
const startEvt = getMouseEvent(evt);
|
const startEvt = getMouseEvent(evt);
|
||||||
|
|
||||||
@@ -51,7 +63,7 @@ const onStart = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selectNodesOnDrag) {
|
if (selectNodesOnDrag) {
|
||||||
store.dispatch.setSelectedElements({ id, type } as Node);
|
setSelectedElements({ id, type } as Node);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -61,9 +73,10 @@ interface OnDragParams {
|
|||||||
id: ElementId;
|
id: ElementId;
|
||||||
offset: XYPosition;
|
offset: XYPosition;
|
||||||
transform: Transform;
|
transform: Transform;
|
||||||
|
updateNodePos: (params: NodePosUpdate) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onDrag = ({ evt, setDragging, id, offset, transform }: OnDragParams): void => {
|
const onDrag = ({ evt, setDragging, id, offset, transform, updateNodePos }: OnDragParams): void => {
|
||||||
const dragEvt = getMouseEvent(evt);
|
const dragEvt = getMouseEvent(evt);
|
||||||
|
|
||||||
const scaledClient = {
|
const scaledClient = {
|
||||||
@@ -72,7 +85,7 @@ const onDrag = ({ evt, setDragging, id, offset, transform }: OnDragParams): void
|
|||||||
};
|
};
|
||||||
|
|
||||||
setDragging(true);
|
setDragging(true);
|
||||||
store.dispatch.updateNodePos({
|
updateNodePos({
|
||||||
id,
|
id,
|
||||||
pos: {
|
pos: {
|
||||||
x: scaledClient.x - transform[0] - offset.x,
|
x: scaledClient.x - transform[0] - offset.x,
|
||||||
@@ -89,6 +102,7 @@ interface OnDragStopParams {
|
|||||||
position: XYPosition;
|
position: XYPosition;
|
||||||
data: any;
|
data: any;
|
||||||
selectNodesOnDrag: boolean;
|
selectNodesOnDrag: boolean;
|
||||||
|
setSelectedElements: (elms: Elements | Node | Edge) => void;
|
||||||
onNodeDragStop?: (node: Node) => void;
|
onNodeDragStop?: (node: Node) => void;
|
||||||
onClick?: (node: Node) => void;
|
onClick?: (node: Node) => void;
|
||||||
}
|
}
|
||||||
@@ -103,6 +117,7 @@ const onStop = ({
|
|||||||
selectNodesOnDrag,
|
selectNodesOnDrag,
|
||||||
onNodeDragStop,
|
onNodeDragStop,
|
||||||
onClick,
|
onClick,
|
||||||
|
setSelectedElements,
|
||||||
}: OnDragStopParams): void => {
|
}: OnDragStopParams): void => {
|
||||||
const node = {
|
const node = {
|
||||||
id,
|
id,
|
||||||
@@ -113,7 +128,7 @@ const onStop = ({
|
|||||||
|
|
||||||
if (!isDragging) {
|
if (!isDragging) {
|
||||||
if (!selectNodesOnDrag) {
|
if (!selectNodesOnDrag) {
|
||||||
store.dispatch.setSelectedElements({ id, type } as Node);
|
setSelectedElements({ id, type } as Node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onClick) {
|
if (onClick) {
|
||||||
@@ -148,6 +163,10 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
sourcePosition,
|
sourcePosition,
|
||||||
targetPosition,
|
targetPosition,
|
||||||
}: WrapNodeProps) => {
|
}: WrapNodeProps) => {
|
||||||
|
const updateNodeDimensions = useStoreActions((a) => a.updateNodeDimensions);
|
||||||
|
const setSelectedElements = useStoreActions((a) => a.setSelectedElements);
|
||||||
|
const updateNodePos = useStoreActions((a) => a.updateNodePos);
|
||||||
|
|
||||||
const nodeElement = useRef<HTMLDivElement>(null);
|
const nodeElement = useRef<HTMLDivElement>(null);
|
||||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||||
const [isDragging, setDragging] = useState(false);
|
const [isDragging, setDragging] = useState(false);
|
||||||
@@ -163,11 +182,11 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (nodeElement.current) {
|
if (nodeElement.current) {
|
||||||
store.dispatch.updateNodeDimensions({ id, nodeElement: nodeElement.current });
|
updateNodeDimensions({ id, nodeElement: nodeElement.current });
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
for (let _ of entries) {
|
for (let _ of entries) {
|
||||||
store.dispatch.updateNodeDimensions({ id, nodeElement: nodeElement.current! });
|
updateNodeDimensions({ id, nodeElement: nodeElement.current! });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -196,11 +215,23 @@ export default (NodeComponent: ComponentType<NodeComponentProps>) => {
|
|||||||
setOffset,
|
setOffset,
|
||||||
transform,
|
transform,
|
||||||
position,
|
position,
|
||||||
|
setSelectedElements,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
onDrag={(evt) => onDrag({ evt: evt as MouseEvent, setDragging, id, offset, transform })}
|
onDrag={(evt) => onDrag({ evt: evt as MouseEvent, setDragging, id, offset, transform, updateNodePos })}
|
||||||
onStop={() =>
|
onStop={() =>
|
||||||
onStop({ onNodeDragStop, selectNodesOnDrag, onClick, isDragging, setDragging, id, type, position, data })
|
onStop({
|
||||||
|
onNodeDragStop,
|
||||||
|
selectNodesOnDrag,
|
||||||
|
onClick,
|
||||||
|
isDragging,
|
||||||
|
setDragging,
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
position,
|
||||||
|
data,
|
||||||
|
setSelectedElements,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
scale={transform[2]}
|
scale={transform[2]}
|
||||||
disabled={!isInteractive}
|
disabled={!isInteractive}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import React, { FC } from 'react';
|
||||||
|
import { StoreProvider, useStore } from 'easy-peasy';
|
||||||
|
|
||||||
|
import store, { StoreModel } from '../../store';
|
||||||
|
|
||||||
|
const Wrapper: FC = ({ children }) => {
|
||||||
|
const easyPeasyStore = useStore<StoreModel>();
|
||||||
|
const isWrapepdWithReactFlowProvider = easyPeasyStore?.getState()?.reactFlowVersion;
|
||||||
|
|
||||||
|
if (isWrapepdWithReactFlowProvider) {
|
||||||
|
// we need to wrap it with a fragment because t's not allowed for children to be a ReactNode
|
||||||
|
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <StoreProvider store={store}>{children}</StoreProvider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Wrapper.displayName = 'ReactFlowWrapper';
|
||||||
|
|
||||||
|
export default Wrapper;
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import React, { useMemo, CSSProperties, HTMLAttributes } from 'react';
|
import React, { useMemo, CSSProperties, HTMLAttributes } from 'react';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { StoreProvider } from 'easy-peasy';
|
|
||||||
|
|
||||||
const nodeEnv: string = process.env.NODE_ENV as string;
|
const nodeEnv: string = process.env.NODE_ENV as string;
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ import BezierEdge from '../../components/Edges/BezierEdge';
|
|||||||
import StraightEdge from '../../components/Edges/StraightEdge';
|
import StraightEdge from '../../components/Edges/StraightEdge';
|
||||||
import StepEdge from '../../components/Edges/StepEdge';
|
import StepEdge from '../../components/Edges/StepEdge';
|
||||||
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
||||||
import store from '../../store';
|
import Wrapper from './Wrapper';
|
||||||
import {
|
import {
|
||||||
Elements,
|
Elements,
|
||||||
NodeTypesType,
|
NodeTypesType,
|
||||||
@@ -92,7 +91,7 @@ const ReactFlow = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={style} className={cx('react-flow', className)}>
|
<div style={style} className={cx('react-flow', className)}>
|
||||||
<StoreProvider store={store}>
|
<Wrapper>
|
||||||
<GraphView
|
<GraphView
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
onMove={onMove}
|
onMove={onMove}
|
||||||
@@ -119,7 +118,7 @@ const ReactFlow = ({
|
|||||||
/>
|
/>
|
||||||
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
{onSelectionChange && <SelectionListener onSelectionChange={onSelectionChange} />}
|
||||||
{children}
|
{children}
|
||||||
</StoreProvider>
|
</Wrapper>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
+3
-2
@@ -3,8 +3,7 @@ declare module '*.css' {
|
|||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SvgrComponent
|
interface SvgrComponent extends React.StatelessComponent<React.SVGAttributes<SVGElement>> {}
|
||||||
extends React.StatelessComponent<React.SVGAttributes<SVGElement>> {}
|
|
||||||
|
|
||||||
declare module '*.svg' {
|
declare module '*.svg' {
|
||||||
const svgUrl: string;
|
const svgUrl: string;
|
||||||
@@ -12,3 +11,5 @@ declare module '*.svg' {
|
|||||||
export default svgUrl;
|
export default svgUrl;
|
||||||
export { svgComponent as ReactComponent };
|
export { svgComponent as ReactComponent };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare var __REACT_FLOW_VERSION__: string;
|
||||||
|
|||||||
+6
-6
@@ -19,6 +19,7 @@ import {
|
|||||||
SelectionRect,
|
SelectionRect,
|
||||||
HandleType,
|
HandleType,
|
||||||
SetConnectionId,
|
SetConnectionId,
|
||||||
|
NodePosUpdate,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
type TransformXYK = {
|
type TransformXYK = {
|
||||||
@@ -27,11 +28,6 @@ type TransformXYK = {
|
|||||||
k: number;
|
k: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type NodePosUpdate = {
|
|
||||||
id: ElementId;
|
|
||||||
pos: XYPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
type NodeDimensionUpdate = {
|
type NodeDimensionUpdate = {
|
||||||
id: ElementId;
|
id: ElementId;
|
||||||
nodeElement: HTMLDivElement;
|
nodeElement: HTMLDivElement;
|
||||||
@@ -87,6 +83,8 @@ export interface StoreModel {
|
|||||||
|
|
||||||
isInteractive: boolean;
|
isInteractive: boolean;
|
||||||
|
|
||||||
|
reactFlowVersion: string;
|
||||||
|
|
||||||
onConnect: OnConnectFunc;
|
onConnect: OnConnectFunc;
|
||||||
|
|
||||||
setOnConnect: Action<StoreModel, OnConnectFunc>;
|
setOnConnect: Action<StoreModel, OnConnectFunc>;
|
||||||
@@ -126,7 +124,7 @@ export interface StoreModel {
|
|||||||
unsetUserSelection: Action<StoreModel>;
|
unsetUserSelection: Action<StoreModel>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeModel: StoreModel = {
|
export const storeModel: StoreModel = {
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
transform: [0, 0, 1],
|
transform: [0, 0, 1],
|
||||||
@@ -163,6 +161,8 @@ const storeModel: StoreModel = {
|
|||||||
|
|
||||||
isInteractive: true,
|
isInteractive: true,
|
||||||
|
|
||||||
|
reactFlowVersion: __REACT_FLOW_VERSION__,
|
||||||
|
|
||||||
onConnect: () => {},
|
onConnect: () => {},
|
||||||
|
|
||||||
setOnConnect: action((state, onConnect) => {
|
setOnConnect: action((state, onConnect) => {
|
||||||
|
|||||||
@@ -203,3 +203,8 @@ export interface EdgeTextProps {
|
|||||||
labelShowBg?: boolean;
|
labelShowBg?: boolean;
|
||||||
labelBgStyle?: CSSProperties;
|
labelBgStyle?: CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type NodePosUpdate = {
|
||||||
|
id: ElementId;
|
||||||
|
pos: XYPosition;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user