feat: Create examples directory and add some examples
* Add svg plugins for vite & rollup update: more bundle stuff
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
import { computed, defineComponent } from 'vue';
|
||||||
|
import Header from './Header';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
Header
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const route = useRoute();
|
||||||
|
const key = computed(() => route.fullPath);
|
||||||
|
return () => (
|
||||||
|
<>
|
||||||
|
<Header />
|
||||||
|
<router-view ref="view" key={key.value} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,7 +1,17 @@
|
|||||||
import { Connection, Edge, Elements, FlowElement, Node, OnLoadParams } from './types';
|
import RevueFlow, {
|
||||||
import { addEdge, isNode, removeElements } from './utils/graph';
|
MiniMap,
|
||||||
import RevueFlow from './container/RevueFlow';
|
Controls,
|
||||||
import { MiniMap, Controls, Background } from './additional-components';
|
Background,
|
||||||
|
Connection,
|
||||||
|
Edge,
|
||||||
|
Elements,
|
||||||
|
FlowElement,
|
||||||
|
Node,
|
||||||
|
OnLoadParams,
|
||||||
|
addEdge,
|
||||||
|
isNode,
|
||||||
|
removeElements
|
||||||
|
} from '../../src';
|
||||||
import { defineComponent, ref } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
|
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { defineComponent, PropType } from 'vue';
|
||||||
|
import { ConnectionLineComponentProps } from '../../src';
|
||||||
|
|
||||||
|
const ConnectionLine = defineComponent({
|
||||||
|
props: {
|
||||||
|
sourceX: {
|
||||||
|
type: Number as PropType<ConnectionLineComponentProps['sourceX']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
sourceY: {
|
||||||
|
type: Number as PropType<ConnectionLineComponentProps['sourceY']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
targetX: {
|
||||||
|
type: Number as PropType<ConnectionLineComponentProps['targetX']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
targetY: {
|
||||||
|
type: Number as PropType<ConnectionLineComponentProps['targetY']>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return () => (
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
fill="none"
|
||||||
|
stroke="#222"
|
||||||
|
stroke-width={1.5}
|
||||||
|
class="animated"
|
||||||
|
d={`M${props.sourceX},${props.sourceY} C ${props.sourceX} ${props.targetY} ${props.sourceX} ${props.targetY} ${props.targetX},${props.targetY}`}
|
||||||
|
/>
|
||||||
|
<circle cx={props.targetX} cy={props.targetY} fill="#fff" r={3} stroke="#222" stroke-width={1.5} />
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ConnectionLine;
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import RevueFlow, { removeElements, addEdge, Background, BackgroundVariant, Elements, Connection, Edge } from '../../src';
|
||||||
|
|
||||||
|
import ConnectionLine from './ConnectionLine';
|
||||||
|
import { defineComponent, ref } from 'vue';
|
||||||
|
|
||||||
|
const initialElements: Elements = [{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }];
|
||||||
|
|
||||||
|
const ConnectionLineFlow = defineComponent({
|
||||||
|
components: { Background },
|
||||||
|
setup() {
|
||||||
|
const elements = ref(initialElements);
|
||||||
|
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value));
|
||||||
|
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value));
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<RevueFlow
|
||||||
|
elements={elements.value}
|
||||||
|
connectionLineComponent={ConnectionLine as any}
|
||||||
|
onElementsRemove={onElementsRemove}
|
||||||
|
onConnect={onConnect}
|
||||||
|
>
|
||||||
|
<Background variant={BackgroundVariant.Lines} />
|
||||||
|
</RevueFlow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ConnectionLineFlow;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { CSSProperties, defineComponent } from 'vue';
|
||||||
|
import { Handle, Position, Connection, Edge } from '../../src';
|
||||||
|
|
||||||
|
const targetHandleStyle: CSSProperties = { background: '#555' };
|
||||||
|
const sourceHandleStyleA: CSSProperties = { ...targetHandleStyle, top: 10 };
|
||||||
|
const sourceHandleStyleB: CSSProperties = { ...targetHandleStyle, bottom: 10, top: 'auto' };
|
||||||
|
|
||||||
|
const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params);
|
||||||
|
|
||||||
|
const ColorSelectorNode = defineComponent({
|
||||||
|
props: {
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return () => (
|
||||||
|
<>
|
||||||
|
<Handle type="target" position={Position.Left} style={targetHandleStyle} onConnect={onConnect} />
|
||||||
|
<div>
|
||||||
|
Custom Color Picker Node: <strong>{props.data.color}</strong>
|
||||||
|
</div>
|
||||||
|
<input class="nodrag" type="color" onInput={props.data.onChange} v-model={props.data.color} />
|
||||||
|
<Handle type="source" position={Position.Right} id="a" style={sourceHandleStyleA} />
|
||||||
|
<Handle type="source" position={Position.Right} id="b" style={sourceHandleStyleB} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ColorSelectorNode;
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import { defineComponent, onMounted, ref } from 'vue';
|
||||||
|
import RevueFlow, {
|
||||||
|
isEdge,
|
||||||
|
removeElements,
|
||||||
|
addEdge,
|
||||||
|
MiniMap,
|
||||||
|
Controls,
|
||||||
|
Node,
|
||||||
|
FlowElement,
|
||||||
|
OnLoadParams,
|
||||||
|
Elements,
|
||||||
|
Position,
|
||||||
|
SnapGrid,
|
||||||
|
Connection,
|
||||||
|
Edge
|
||||||
|
} from '../../src';
|
||||||
|
import ColorSelectorNode from './ColorSelectorNode';
|
||||||
|
|
||||||
|
const onLoad = (reactFlowInstance: OnLoadParams) => console.log('flow loaded:', reactFlowInstance);
|
||||||
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||||
|
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
|
||||||
|
|
||||||
|
const initBgColor = '#1A192B';
|
||||||
|
|
||||||
|
const connectionLineStyle = { stroke: '#fff' };
|
||||||
|
const snapGrid: SnapGrid = [16, 16];
|
||||||
|
const nodeTypes = {
|
||||||
|
selectorNode: ColorSelectorNode
|
||||||
|
};
|
||||||
|
|
||||||
|
const CustomNodeFlow = defineComponent({
|
||||||
|
components: { RevueFlow, MiniMap, Controls },
|
||||||
|
setup() {
|
||||||
|
const elements = ref<Elements>([]);
|
||||||
|
const bgColor = ref(initBgColor);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const onChange = (event: Event) => {
|
||||||
|
elements.value = elements.value.map((e) => {
|
||||||
|
if (isEdge(e) || e.id !== '2') {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = (event.target as HTMLInputElement).value;
|
||||||
|
|
||||||
|
bgColor.value = color;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
data: {
|
||||||
|
...e.data,
|
||||||
|
color
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.value = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
type: 'input',
|
||||||
|
data: { label: 'An input node' },
|
||||||
|
position: { x: 0, y: 50 },
|
||||||
|
sourcePosition: Position.Right
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
type: 'selectorNode',
|
||||||
|
data: { onChange: onChange, color: initBgColor },
|
||||||
|
style: { border: '1px solid #777', padding: 10 },
|
||||||
|
position: { x: 250, y: 50 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
type: 'output',
|
||||||
|
data: { label: 'Output A' },
|
||||||
|
position: { x: 550, y: 25 },
|
||||||
|
targetPosition: Position.Left
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '4',
|
||||||
|
type: 'output',
|
||||||
|
data: { label: 'Output B' },
|
||||||
|
position: { x: 550, y: 100 },
|
||||||
|
targetPosition: Position.Left
|
||||||
|
},
|
||||||
|
|
||||||
|
{ id: 'e1-2', source: '1', target: '2', animated: true, style: { stroke: '#fff' } },
|
||||||
|
{ id: 'e2a-3', source: '2', sourceHandle: 'a', target: '3', animated: true, style: { stroke: '#fff' } },
|
||||||
|
{ id: 'e2b-4', source: '2', sourceHandle: 'b', target: '4', animated: true, style: { stroke: '#fff' } }
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value));
|
||||||
|
const onConnect = (params: Connection | Edge) =>
|
||||||
|
(elements.value = addEdge({ ...params, animated: true, style: { stroke: '#fff' } }, elements.value));
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<RevueFlow
|
||||||
|
elements={elements.value}
|
||||||
|
onElementClick={onElementClick}
|
||||||
|
onElementsRemove={onElementsRemove}
|
||||||
|
onConnect={onConnect}
|
||||||
|
onNodeDragStop={onNodeDragStop}
|
||||||
|
style={{ background: bgColor.value }}
|
||||||
|
onLoad={onLoad}
|
||||||
|
nodeTypes={nodeTypes}
|
||||||
|
connectionLineStyle={connectionLineStyle}
|
||||||
|
snapToGrid={true}
|
||||||
|
snapGrid={snapGrid}
|
||||||
|
defaultZoom={1.5}
|
||||||
|
>
|
||||||
|
<MiniMap
|
||||||
|
nodeStrokeColor={(n: Node): string => {
|
||||||
|
if (n.type === 'input') return '#0041d0';
|
||||||
|
if (n.type === 'selectorNode') return bgColor.value;
|
||||||
|
if (n.type === 'output') return '#ff0072';
|
||||||
|
|
||||||
|
return '#eee';
|
||||||
|
}}
|
||||||
|
nodeColor={(n: Node): string => {
|
||||||
|
if (n.type === 'selectorNode') return bgColor.value;
|
||||||
|
|
||||||
|
return '#fff';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Controls />
|
||||||
|
</RevueFlow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default CustomNodeFlow;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { routes } from './router';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const Header = defineComponent({
|
||||||
|
setup() {
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const onChange = async (event: any) => {
|
||||||
|
await router.push(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<header>
|
||||||
|
<a class="logo" href="https://github.com/wbkd/react-flow">
|
||||||
|
Revue Flow Dev
|
||||||
|
</a>
|
||||||
|
<select v-model={route.path} onChange={onChange}>
|
||||||
|
{routes.map((route) => (
|
||||||
|
<option value={route.path} key={route.path}>
|
||||||
|
{route.path === '/' ? 'overview' : route.path.substr(1, route.path.length)}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Header;
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#root {
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
font-weight: 700;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
header a,
|
||||||
|
header a:focus,
|
||||||
|
header a:active,
|
||||||
|
header a:visited {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
header a:hover {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
header select {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overview-example__add {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revue-flow__node a {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revue-flow__node.dark-node {
|
||||||
|
background: #0041d0;
|
||||||
|
color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revue-flow__node.dark {
|
||||||
|
background: #557;
|
||||||
|
color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revue-flow__node-selectorNode {
|
||||||
|
font-size: 12px;
|
||||||
|
background: #f0f2f3;
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revue-flow__node-selectorNode .revue-flow__handle {
|
||||||
|
border-color: #f0f2f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.overview-example__add {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import './index.css';
|
||||||
|
import App from './App';
|
||||||
|
import { router } from './router';
|
||||||
|
const app = createApp(App);
|
||||||
|
|
||||||
|
app.config.performance = true;
|
||||||
|
app.use(router);
|
||||||
|
app.mount('#root');
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { createRouter, createWebHashHistory } from 'vue-router';
|
||||||
|
|
||||||
|
export const routes = [
|
||||||
|
{
|
||||||
|
path: '/basic',
|
||||||
|
component: () => import('./Basic')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/custom-connectionline',
|
||||||
|
component: () => import('./CustomConnectionLine')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/custom-node',
|
||||||
|
component: () => import('./CustomNode')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const router = createRouter({
|
||||||
|
history: createWebHashHistory(),
|
||||||
|
routes
|
||||||
|
});
|
||||||
+3
-4
@@ -2,12 +2,11 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" href="/favicon.ico" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite App</title>
|
<title>Revue Flow Examples</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/examples/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+6
-3
@@ -33,7 +33,8 @@
|
|||||||
"d3-selection": "^3.0.0",
|
"d3-selection": "^3.0.0",
|
||||||
"d3-zoom": "^3.0.0",
|
"d3-zoom": "^3.0.0",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"pinia": "^2.0.0-beta.3"
|
"pinia": "^2.0.0-beta.3",
|
||||||
|
"vue": "^3.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.14.6",
|
"@babel/core": "^7.14.6",
|
||||||
@@ -41,7 +42,6 @@
|
|||||||
"@rollup/plugin-commonjs": "^19.0.0",
|
"@rollup/plugin-commonjs": "^19.0.0",
|
||||||
"@rollup/plugin-node-resolve": "^13.0.0",
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||||
"@rollup/plugin-replace": "^2.4.2",
|
"@rollup/plugin-replace": "^2.4.2",
|
||||||
"@svgr/rollup": "^5.5.0",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^4.28.1",
|
"@typescript-eslint/eslint-plugin": "^4.28.1",
|
||||||
"@typescript-eslint/parser": "^4.28.1",
|
"@typescript-eslint/parser": "^4.28.1",
|
||||||
"@vitejs/plugin-vue": "^1.2.3",
|
"@vitejs/plugin-vue": "^1.2.3",
|
||||||
@@ -64,12 +64,15 @@
|
|||||||
"rollup": "^2.52.2",
|
"rollup": "^2.52.2",
|
||||||
"rollup-plugin-postcss": "^4.0.0",
|
"rollup-plugin-postcss": "^4.0.0",
|
||||||
"rollup-plugin-serve": "^1.1.0",
|
"rollup-plugin-serve": "^1.1.0",
|
||||||
|
"rollup-plugin-svg": "^2.0.0",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"rollup-plugin-typescript2": "^0.30.0",
|
"rollup-plugin-typescript2": "^0.30.0",
|
||||||
|
"rollup-plugin-vue-inline-svg": "^1.1.2",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"typescript": "^4.3.5",
|
"typescript": "^4.3.5",
|
||||||
"vite": "^2.3.8",
|
"vite": "^2.3.8",
|
||||||
"vue": "^3.0.5",
|
"vite-svg-loader": "^2.1.0",
|
||||||
|
"vue-router": "4",
|
||||||
"vue-tsc": "^0.0.24"
|
"vue-tsc": "^0.0.24"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
+6
-13
@@ -7,6 +7,7 @@ import pascalcase from 'pascalcase';
|
|||||||
import pkg from './package.json';
|
import pkg from './package.json';
|
||||||
import postcss from 'rollup-plugin-postcss';
|
import postcss from 'rollup-plugin-postcss';
|
||||||
import babel from '@rollup/plugin-babel';
|
import babel from '@rollup/plugin-babel';
|
||||||
|
import svg from 'rollup-plugin-svg';
|
||||||
import { DEFAULT_EXTENSIONS as DEFAULT_BABEL_EXTENSIONS } from '@babel/core';
|
import { DEFAULT_EXTENSIONS as DEFAULT_BABEL_EXTENSIONS } from '@babel/core';
|
||||||
|
|
||||||
const name = pkg.name;
|
const name = pkg.name;
|
||||||
@@ -44,14 +45,6 @@ const outputConfigs = {
|
|||||||
file: pkg.main,
|
file: pkg.main,
|
||||||
format: 'cjs'
|
format: 'cjs'
|
||||||
},
|
},
|
||||||
'global-vue-3': {
|
|
||||||
file: pkg.unpkg.replace('2', '3'),
|
|
||||||
format: 'iife'
|
|
||||||
},
|
|
||||||
'global-vue-2': {
|
|
||||||
file: pkg.unpkg,
|
|
||||||
format: 'iife'
|
|
||||||
},
|
|
||||||
esm: {
|
esm: {
|
||||||
file: pkg.browser,
|
file: pkg.browser,
|
||||||
format: 'es'
|
format: 'es'
|
||||||
@@ -113,8 +106,6 @@ function createConfig(format, output, plugins = []) {
|
|||||||
|
|
||||||
const external = ['vue'];
|
const external = ['vue'];
|
||||||
|
|
||||||
const nodePlugins = [resolve(), commonjs({ include: 'node_modules/**' })];
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
input: 'src/index.ts',
|
input: 'src/index.ts',
|
||||||
// Global and Browser ESM builds inlines everything so that they can be
|
// Global and Browser ESM builds inlines everything so that they can be
|
||||||
@@ -130,8 +121,9 @@ function createConfig(format, output, plugins = []) {
|
|||||||
isGlobalBuild,
|
isGlobalBuild,
|
||||||
isNodeBuild
|
isNodeBuild
|
||||||
),
|
),
|
||||||
...nodePlugins,
|
svg(),
|
||||||
...plugins,
|
resolve(),
|
||||||
|
commonjs({ include: 'node_modules/**' }),
|
||||||
postcss({
|
postcss({
|
||||||
minimize: true,
|
minimize: true,
|
||||||
inject: true
|
inject: true
|
||||||
@@ -140,7 +132,8 @@ function createConfig(format, output, plugins = []) {
|
|||||||
extensions: [...DEFAULT_BABEL_EXTENSIONS, '.ts', '.tsx'],
|
extensions: [...DEFAULT_BABEL_EXTENSIONS, '.ts', '.tsx'],
|
||||||
exclude: 'node_modules/**',
|
exclude: 'node_modules/**',
|
||||||
babelHelpers: 'inline'
|
babelHelpers: 'inline'
|
||||||
})
|
}),
|
||||||
|
...plugins
|
||||||
],
|
],
|
||||||
output
|
output
|
||||||
// onwarn: (msg, warn) => {
|
// onwarn: (msg, warn) => {
|
||||||
|
|||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div id="app">
|
|
||||||
<h1>Revue Flow</h1>
|
|
||||||
<Basic style="height: 75vh; background: #1a192b" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import Basic from './Basic';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'App',
|
|
||||||
components: {
|
|
||||||
Basic
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
elements: [
|
|
||||||
{ 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: 'e1-2', source: '1', target: '2', animated: true }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#app {
|
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
text-align: center;
|
|
||||||
color: #2c3e50;
|
|
||||||
margin-top: 60px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
|
import { defineComponent, HTMLAttributes, onMounted, PropType, ref } from 'vue';
|
||||||
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
|
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
|
||||||
import { FitViewParams } from '../../types';
|
import { FitViewParams } from '../../types';
|
||||||
import { defineComponent, HTMLAttributes, onMounted, PropType, ref } from 'vue';
|
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
|
import PlusIcon from '../../../assets/icons/plus.svg';
|
||||||
|
import MinusIcon from '../../../assets/icons/minus.svg';
|
||||||
|
import Fitview from '../../../assets/icons/fitview.svg';
|
||||||
|
import Lock from '../../../assets/icons/lock.svg';
|
||||||
|
import Unlock from '../../../assets/icons/unlock.svg';
|
||||||
|
|
||||||
export interface ControlProps extends HTMLAttributes {
|
export interface ControlProps extends HTMLAttributes {
|
||||||
showZoom?: boolean;
|
showZoom?: boolean;
|
||||||
@@ -123,25 +128,21 @@ const Controls = defineComponent({
|
|||||||
{props.showZoom && (
|
{props.showZoom && (
|
||||||
<>
|
<>
|
||||||
<ControlButton onClick={onZoomInHandler} class="revue-flow__controls-zoomin">
|
<ControlButton onClick={onZoomInHandler} class="revue-flow__controls-zoomin">
|
||||||
<img src={'../../../assets/icons/plus.svg'} alt="Plus" />
|
<PlusIcon />
|
||||||
</ControlButton>
|
</ControlButton>
|
||||||
<ControlButton onClick={onZoomOutHandler} class="revue-flow__controls-zoomout">
|
<ControlButton onClick={onZoomOutHandler} class="revue-flow__controls-zoomout">
|
||||||
<img src={'../../../assets/icons/minus.svg'} alt="Minus" />
|
<MinusIcon />
|
||||||
</ControlButton>
|
</ControlButton>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{props.showFitView && (
|
{props.showFitView && (
|
||||||
<ControlButton class="revue-flow__controls-fitview" onClick={onFitViewHandler}>
|
<ControlButton class="revue-flow__controls-fitview" onClick={onFitViewHandler}>
|
||||||
<img src={'../../../assets/icons/fitview.svg'} alt="FitView" />
|
<Fitview />
|
||||||
</ControlButton>
|
</ControlButton>
|
||||||
)}
|
)}
|
||||||
{props.showInteractive && (
|
{props.showInteractive && (
|
||||||
<ControlButton class="revue-flow__controls-interactive" onClick={onInteractiveChangeHandler}>
|
<ControlButton class="revue-flow__controls-interactive" onClick={onInteractiveChangeHandler}>
|
||||||
{isInteractive ? (
|
{isInteractive ? <Unlock /> : <Lock />}
|
||||||
<img src={'../../../assets/icons/unlock.svg'} alt="Unlock" />
|
|
||||||
) : (
|
|
||||||
<img src={'../../../assets/icons/lock.svg'} alt="Lock" />
|
|
||||||
)}
|
|
||||||
</ControlButton>
|
</ControlButton>
|
||||||
)}
|
)}
|
||||||
{slots.default ? slots.default() : ''}
|
{slots.default ? slots.default() : ''}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { defineComponent, PropType } from 'vue';
|
import { computed, defineComponent, PropType } from 'vue';
|
||||||
|
|
||||||
interface MiniMapNodeProps {
|
interface MiniMapNodeProps {
|
||||||
x: number;
|
x: number;
|
||||||
@@ -62,19 +62,19 @@ const MiniMapNode = defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props, { attrs }: { attrs: Record<string, any> }) {
|
setup(props, { attrs }: { attrs: Record<string, any> }) {
|
||||||
const { background, backgroundColor } = attrs.style || {};
|
const styles = attrs.style || {};
|
||||||
const fill = (props.color || background || backgroundColor) as string;
|
const fill = computed(() => (props.color || styles.value.background || styles.value.backgroundColor) as string);
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<rect
|
<rect
|
||||||
class={['revue-flow__minimap-node']}
|
class="revue-flow__minimap-node"
|
||||||
x={props.x}
|
x={props.x}
|
||||||
y={props.y}
|
y={props.y}
|
||||||
rx={props.borderRadius}
|
rx={props.borderRadius}
|
||||||
ry={props.borderRadius}
|
ry={props.borderRadius}
|
||||||
width={props.width}
|
width={props.width}
|
||||||
height={props.height}
|
height={props.height}
|
||||||
fill={fill}
|
fill={fill.value}
|
||||||
stroke={props.strokeColor}
|
stroke={props.strokeColor}
|
||||||
stroke-width={props.strokeWidth}
|
stroke-width={props.strokeWidth}
|
||||||
shape-rendering={props.shapeRendering}
|
shape-rendering={props.shapeRendering}
|
||||||
|
|||||||
@@ -24,17 +24,17 @@ const MiniMap = defineComponent({
|
|||||||
name: 'MiniMap',
|
name: 'MiniMap',
|
||||||
props: {
|
props: {
|
||||||
nodeStrokeColor: {
|
nodeStrokeColor: {
|
||||||
type: (String || Function) as PropType<MiniMapProps['nodeStrokeColor']>,
|
type: [String, Function] as PropType<MiniMapProps['nodeStrokeColor']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: '#555'
|
default: '#555'
|
||||||
},
|
},
|
||||||
nodeColor: {
|
nodeColor: {
|
||||||
type: (String || Function) as PropType<MiniMapProps['nodeColor']>,
|
type: [String, Function] as PropType<MiniMapProps['nodeColor']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: '#fff'
|
default: '#fff'
|
||||||
},
|
},
|
||||||
nodeClassName: {
|
nodeClassName: {
|
||||||
type: (String || Function) as PropType<MiniMapProps['nodeClassName']>,
|
type: [String, Function] as PropType<MiniMapProps['nodeClassName']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
@@ -57,17 +57,15 @@ const MiniMap = defineComponent({
|
|||||||
setup(props, { attrs }: { attrs: Record<string, any> }) {
|
setup(props, { attrs }: { attrs: Record<string, any> }) {
|
||||||
const pinia = store();
|
const pinia = store();
|
||||||
const transform = computed(() => pinia.transform);
|
const transform = computed(() => pinia.transform);
|
||||||
|
|
||||||
const mapClasses = ['revue-flow__minimap'];
|
|
||||||
const elementWidth = computed(() => (attrs.style?.width || defaultWidth)! as number);
|
const elementWidth = computed(() => (attrs.style?.width || defaultWidth)! as number);
|
||||||
const elementHeight = computed(() => (attrs.style?.height || defaultHeight)! as number);
|
const elementHeight = computed(() => (attrs.style?.height || defaultHeight)! as number);
|
||||||
const nodeColorFunc = (props.nodeColor instanceof Function ? props.nodeColor : () => props.nodeColor) as StringFunc;
|
const nodeColorFunc = computed(() => (props.nodeColor instanceof Function ? props.nodeColor : () => props.nodeColor) as StringFunc);
|
||||||
const nodeStrokeColorFunc = (
|
const nodeStrokeColorFunc = computed(
|
||||||
props.nodeStrokeColor instanceof Function ? props.nodeStrokeColor : () => props.nodeStrokeColor
|
() => (props.nodeStrokeColor instanceof Function ? props.nodeStrokeColor : () => props.nodeStrokeColor) as StringFunc
|
||||||
) as StringFunc;
|
);
|
||||||
const nodeClassNameFunc = (
|
const nodeClassNameFunc = computed(
|
||||||
props.nodeClassName instanceof Function ? props.nodeClassName : () => props.nodeClassName
|
() => (props.nodeClassName instanceof Function ? props.nodeClassName : () => props.nodeClassName) as StringFunc
|
||||||
) as StringFunc;
|
);
|
||||||
const hasNodes = computed(() => pinia.nodes && pinia.nodes.length);
|
const hasNodes = computed(() => pinia.nodes && pinia.nodes.length);
|
||||||
const bb = computed(() => getRectOfNodes(pinia.nodes));
|
const bb = computed(() => getRectOfNodes(pinia.nodes));
|
||||||
const viewBB = computed<Rect>(() => ({
|
const viewBB = computed<Rect>(() => ({
|
||||||
@@ -94,7 +92,7 @@ const MiniMap = defineComponent({
|
|||||||
width={elementWidth.value}
|
width={elementWidth.value}
|
||||||
height={elementHeight.value}
|
height={elementHeight.value}
|
||||||
viewBox={`${x.value} ${y.value} ${width.value} ${height.value}`}
|
viewBox={`${x.value} ${y.value} ${width.value} ${height.value}`}
|
||||||
class={mapClasses}
|
class="revue-flow__minimap"
|
||||||
>
|
>
|
||||||
{pinia.nodes
|
{pinia.nodes
|
||||||
.filter((node) => !node.isHidden)
|
.filter((node) => !node.isHidden)
|
||||||
@@ -106,10 +104,10 @@ const MiniMap = defineComponent({
|
|||||||
width={node.__rf.width}
|
width={node.__rf.width}
|
||||||
height={node.__rf.height}
|
height={node.__rf.height}
|
||||||
style={node.style}
|
style={node.style}
|
||||||
class={nodeClassNameFunc(node)}
|
class={nodeClassNameFunc.value(node)}
|
||||||
color={nodeColorFunc(node)}
|
color={nodeColorFunc.value(node)}
|
||||||
borderRadius={props.nodeBorderRadius}
|
borderRadius={props.nodeBorderRadius}
|
||||||
strokeColor={nodeStrokeColorFunc(node)}
|
strokeColor={nodeStrokeColorFunc.value(node)}
|
||||||
strokeWidth={props.nodeStrokeWidth}
|
strokeWidth={props.nodeStrokeWidth}
|
||||||
shapeRendering={shapeRendering}
|
shapeRendering={shapeRendering}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -35,10 +35,13 @@ export function getBezierPath({
|
|||||||
let path = `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${targetY}`;
|
let path = `M${sourceX},${sourceY} C${sourceX},${cY} ${targetX},${cY} ${targetX},${targetY}`;
|
||||||
|
|
||||||
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
if (leftAndRight.includes(sourcePosition) && leftAndRight.includes(targetPosition)) {
|
||||||
|
console.log('foo');
|
||||||
path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`;
|
path = `M${sourceX},${sourceY} C${cX},${sourceY} ${cX},${targetY} ${targetX},${targetY}`;
|
||||||
} else if (leftAndRight.includes(targetPosition)) {
|
} else if (leftAndRight.includes(targetPosition)) {
|
||||||
|
console.log('bar');
|
||||||
path = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;
|
path = `M${sourceX},${sourceY} C${sourceX},${targetY} ${sourceX},${targetY} ${targetX},${targetY}`;
|
||||||
} else if (leftAndRight.includes(sourcePosition)) {
|
} else if (leftAndRight.includes(sourcePosition)) {
|
||||||
|
console.log('baz');
|
||||||
path = `M${sourceX},${sourceY} C${targetX},${sourceY} ${targetX},${sourceY} ${targetX},${targetY}`;
|
path = `M${sourceX},${sourceY} C${targetX},${sourceY} ${targetX},${sourceY} ${targetX},${targetY}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,9 +85,9 @@ const BezierEdge = defineComponent({
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
labelStyle: {
|
labelStyle: {
|
||||||
type: Object as PropType<any>,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
default: () => ({})
|
default: undefined
|
||||||
},
|
},
|
||||||
labelShowBg: {
|
labelShowBg: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -153,11 +156,11 @@ const BezierEdge = defineComponent({
|
|||||||
/>
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
const markerEnd = getMarkerEnd(props.arrowHeadType, props.markerEndId);
|
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId));
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<>
|
<>
|
||||||
<path style={props.style} d={path.value} class="revue-flow__edge-path" marker-end={markerEnd} />
|
<path style={props.style} d={path.value} class="revue-flow__edge-path" marker-end={markerEnd.value} />
|
||||||
{text}
|
{text}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Position } from '../../types';
|
import { Position } from '../../types';
|
||||||
import { defineComponent, HTMLAttributes, PropType } from 'vue';
|
import { computed, defineComponent, HTMLAttributes, PropType } from 'vue';
|
||||||
|
|
||||||
const shiftX = (x: number, shift: number, position: Position): number => {
|
const shiftX = (x: number, shift: number, position: Position): number => {
|
||||||
if (position === Position.Left) return x - shift;
|
if (position === Position.Left) return x - shift;
|
||||||
@@ -41,13 +41,13 @@ export const EdgeAnchor = defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const radius = props.radius || 10;
|
const radius = computed(() => props.radius || 10);
|
||||||
return () => (
|
return () => (
|
||||||
<circle
|
<circle
|
||||||
class="revue-flow__edgeupdater"
|
class="revue-flow__edgeupdater"
|
||||||
cx={shiftX(props.centerX, radius, props.position)}
|
cx={shiftX(props.centerX, radius.value, props.position)}
|
||||||
cy={shiftY(props.centerY, radius, props.position)}
|
cy={shiftY(props.centerY, radius.value, props.position)}
|
||||||
r={radius}
|
r={radius.value}
|
||||||
stroke="transparent"
|
stroke="transparent"
|
||||||
fill="transparent"
|
fill="transparent"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ const EdgeText = defineComponent({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
labelBgPadding: {
|
labelBgPadding: {
|
||||||
/* @ts-ignore */
|
type: Array as unknown as PropType<[number, number]>,
|
||||||
type: Array as PropType<[number, number]>,
|
|
||||||
default: () => [2, 4]
|
default: () => [2, 4]
|
||||||
},
|
},
|
||||||
labelBgBorderRadius: {
|
labelBgBorderRadius: {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, computed, defineComponent, ref } from 'vue';
|
import { Component, computed, defineComponent, PropType, ref } from 'vue';
|
||||||
|
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
import { Edge, EdgeProps, Position, WrapEdgeProps } from '../../types';
|
import { Edge, EdgeProps, Position, WrapEdgeProps } from '../../types';
|
||||||
@@ -8,11 +8,188 @@ import { EdgeAnchor } from './EdgeAnchor';
|
|||||||
export default (EdgeComponent: any): Component<EdgeProps> => {
|
export default (EdgeComponent: any): Component<EdgeProps> => {
|
||||||
return defineComponent({
|
return defineComponent({
|
||||||
components: { EdgeComponent },
|
components: { EdgeComponent },
|
||||||
props: WrapEdgeProps,
|
props: {
|
||||||
|
id: {
|
||||||
|
type: String as PropType<WrapEdgeProps['id']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String as PropType<WrapEdgeProps['type']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: String as PropType<WrapEdgeProps['data']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onClick: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onClick']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onEdgeDoubleClick: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onEdgeDoubleClick']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
type: Boolean as PropType<WrapEdgeProps['selected']>,
|
||||||
|
required: true,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
animated: {
|
||||||
|
type: Boolean as PropType<WrapEdgeProps['animated']>,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: Object as PropType<WrapEdgeProps['label']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
labelStyle: {
|
||||||
|
type: Object as PropType<WrapEdgeProps['labelStyle']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
labelShowBg: {
|
||||||
|
type: Boolean as PropType<WrapEdgeProps['labelShowBg']>,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
labelBgStyle: {
|
||||||
|
type: Object as PropType<WrapEdgeProps['labelBgStyle']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
labelBgPadding: {
|
||||||
|
type: Array as unknown as PropType<WrapEdgeProps['labelBgPadding']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
labelBgBorderRadius: {
|
||||||
|
type: Number as PropType<WrapEdgeProps['labelBgBorderRadius']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
type: Object as PropType<WrapEdgeProps['style']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
arrowHeadType: {
|
||||||
|
type: String as PropType<WrapEdgeProps['arrowHeadType']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
type: String as PropType<WrapEdgeProps['source']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
type: String as PropType<WrapEdgeProps['target']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
sourceHandleId: {
|
||||||
|
type: String as PropType<WrapEdgeProps['sourceHandleId']>,
|
||||||
|
required: true,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
targetHandleId: {
|
||||||
|
type: String as PropType<WrapEdgeProps['targetHandleId']>,
|
||||||
|
required: true,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
sourceX: {
|
||||||
|
type: Number as PropType<WrapEdgeProps['sourceX']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
sourceY: {
|
||||||
|
type: Number as PropType<WrapEdgeProps['sourceY']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
targetX: {
|
||||||
|
type: Number as PropType<WrapEdgeProps['targetX']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
targetY: {
|
||||||
|
type: Number as PropType<WrapEdgeProps['targetY']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
sourcePosition: {
|
||||||
|
type: String as PropType<WrapEdgeProps['sourcePosition']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
targetPosition: {
|
||||||
|
type: String as PropType<WrapEdgeProps['targetPosition']>,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
elementsSelectable: {
|
||||||
|
type: Boolean as PropType<WrapEdgeProps['elementsSelectable']>,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
markerEndId: {
|
||||||
|
type: String as PropType<WrapEdgeProps['markerEndId']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
isHidden: {
|
||||||
|
type: Boolean as PropType<WrapEdgeProps['isHidden']>,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
handleEdgeUpdate: {
|
||||||
|
type: Boolean as PropType<WrapEdgeProps['handleEdgeUpdate']>,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
onConnectEdge: {
|
||||||
|
type: Function as PropType<WrapEdgeProps['onConnectEdge']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onContextMenu: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onContextMenu']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onMouseEnter: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onMouseEnter']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onMouseMove: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onMouseMove']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onMouseLeave: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onMouseLeave']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
edgeUpdaterRadius: {
|
||||||
|
type: Number as PropType<WrapEdgeProps['edgeUpdaterRadius']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onEdgeUpdateStart: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onEdgeUpdateStart']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
onEdgeUpdateEnd: {
|
||||||
|
type: Function as unknown as PropType<WrapEdgeProps['onEdgeUpdateEnd']>,
|
||||||
|
required: false,
|
||||||
|
default: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const pinia = store();
|
const pinia = store();
|
||||||
const updating = ref<boolean>(false);
|
const updating = ref<boolean>(false);
|
||||||
const inactive = !props.elementsSelectable && !props.onClick;
|
const inactive = computed(() => !props.elementsSelectable && !props.onClick);
|
||||||
const edgeClasses = computed(() => [
|
const edgeClasses = computed(() => [
|
||||||
'revue-flow__edge',
|
'revue-flow__edge',
|
||||||
`revue-flow__edge-${props.type}`,
|
`revue-flow__edge-${props.type}`,
|
||||||
@@ -21,9 +198,9 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
|
|||||||
|
|
||||||
const edgeElement = computed<Edge>(() => {
|
const edgeElement = computed<Edge>(() => {
|
||||||
const el: Edge = {
|
const el: Edge = {
|
||||||
id: props.id || '',
|
id: props.id as string,
|
||||||
source: props.source || '',
|
source: props.source,
|
||||||
target: props.target || '',
|
target: props.target,
|
||||||
type: props.type
|
type: props.type
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,23 +225,23 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
|
|||||||
pinia.addSelectedElements(edgeElement.value as any);
|
pinia.addSelectedElements(edgeElement.value as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.onClick) props.onClick?.(event, edgeElement.value);
|
if (typeof props.onClick === 'function') props.onClick(event, edgeElement.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEdgeContextMenu = (event: MouseEvent) => {
|
const onEdgeContextMenu = (event: MouseEvent) => {
|
||||||
if (typeof props.onContextMenu === 'function') props.onContextMenu?.(event, edgeElement.value);
|
if (typeof props.onContextMenu === 'function') props.onContextMenu(event, edgeElement.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEdgeMouseEnter = (event: MouseEvent) => {
|
const onEdgeMouseEnter = (event: MouseEvent) => {
|
||||||
if (typeof props.onMouseEnter === 'function') props.onMouseEnter?.(event, edgeElement.value);
|
if (typeof props.onMouseEnter === 'function') props.onMouseEnter(event, edgeElement.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEdgeMouseMove = (event: MouseEvent) => {
|
const onEdgeMouseMove = (event: MouseEvent) => {
|
||||||
if (typeof props.onMouseMove === 'function') props.onMouseMove?.(event, edgeElement.value);
|
if (typeof props.onMouseMove === 'function') props.onMouseMove(event, edgeElement.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEdgeMouseLeave = (event: MouseEvent) => {
|
const onEdgeMouseLeave = (event: MouseEvent) => {
|
||||||
if (typeof props.onMouseLeave === 'function') props.onMouseLeave?.(event, edgeElement.value);
|
if (typeof props.onMouseLeave === 'function') props.onMouseLeave(event, edgeElement.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
|
const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
|
||||||
@@ -84,7 +261,7 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
|
|||||||
onMouseDown(
|
onMouseDown(
|
||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
nodeId || '',
|
nodeId,
|
||||||
pinia.setConnectionNodeId,
|
pinia.setConnectionNodeId,
|
||||||
pinia.setConnectionPosition,
|
pinia.setConnectionPosition,
|
||||||
props.onConnectEdge as any,
|
props.onConnectEdge as any,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
} from '../../types';
|
} from '../../types';
|
||||||
import { computed, CSSProperties, defineComponent, PropType } from 'vue';
|
import { computed, CSSProperties, defineComponent, PropType } from 'vue';
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
|
import MarkerDefinitions from './MarkerDefinitions';
|
||||||
|
|
||||||
interface EdgeRendererProps {
|
interface EdgeRendererProps {
|
||||||
edgeTypes: any;
|
edgeTypes: any;
|
||||||
@@ -101,8 +102,6 @@ const EdgeCmp = defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const sourceHandleId = computed(() => props.edge.sourceHandle || null);
|
|
||||||
const targetHandleId = computed(() => props.edge.targetHandle || null);
|
|
||||||
const nodes = computed(() => getSourceTargetNodes(props.edge, props.nodes));
|
const nodes = computed(() => getSourceTargetNodes(props.edge, props.nodes));
|
||||||
|
|
||||||
const onConnectEdge = (connection: Connection) => {
|
const onConnectEdge = (connection: Connection) => {
|
||||||
@@ -119,20 +118,20 @@ const EdgeCmp = defineComponent({
|
|||||||
return () => null;
|
return () => null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const edgeType = props.edge.type || 'default';
|
const EdgeComponent: any = props.props.edgeTypes[props.edge.type as string] || props.props.edgeTypes.default;
|
||||||
const EdgeComponent: any = props.props.edgeTypes[edgeType] || props.props.edgeTypes.default;
|
const targetNodeBounds = computed(() => nodes.value.targetNode?.__rf.handleBounds);
|
||||||
const targetNodeBounds = nodes.value.targetNode.__rf.handleBounds;
|
|
||||||
// when connection type is loose we can define all handles as sources
|
// when connection type is loose we can define all handles as sources
|
||||||
const targetNodeHandles =
|
const targetNodeHandles = computed(() =>
|
||||||
props.connectionMode === ConnectionMode.Strict
|
props.connectionMode === ConnectionMode.Strict
|
||||||
? targetNodeBounds.target
|
? targetNodeBounds.value?.target
|
||||||
: targetNodeBounds.target || targetNodeBounds.source;
|
: targetNodeBounds.value?.target || targetNodeBounds.value?.source
|
||||||
const sourceHandle = computed(
|
|
||||||
() => nodes.value.sourceNode && getHandle(nodes.value.sourceNode.__rf.handleBounds.source, sourceHandleId.value)
|
|
||||||
);
|
);
|
||||||
const targetHandle = computed(() => getHandle(targetNodeHandles, targetHandleId.value));
|
const sourceHandle = computed(
|
||||||
const sourcePosition = sourceHandle.value ? sourceHandle.value.position : Position.Bottom;
|
() => nodes.value.sourceNode && getHandle(nodes.value.sourceNode.__rf.handleBounds.source, props.edge.sourceHandle || null)
|
||||||
const targetPosition = targetHandle.value ? targetHandle.value.position : Position.Top;
|
);
|
||||||
|
const targetHandle = computed(() => getHandle(targetNodeHandles.value, props.edge.targetHandle || null));
|
||||||
|
const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom));
|
||||||
|
const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top));
|
||||||
|
|
||||||
const edgePositions = computed(() => {
|
const edgePositions = computed(() => {
|
||||||
return (
|
return (
|
||||||
@@ -140,11 +139,11 @@ const EdgeCmp = defineComponent({
|
|||||||
nodes.value.targetNode &&
|
nodes.value.targetNode &&
|
||||||
getEdgePositions(
|
getEdgePositions(
|
||||||
nodes.value.sourceNode,
|
nodes.value.sourceNode,
|
||||||
sourceHandle,
|
sourceHandle.value,
|
||||||
sourcePosition,
|
sourcePosition.value,
|
||||||
nodes.value.targetNode,
|
nodes.value.targetNode,
|
||||||
targetHandle,
|
targetHandle.value,
|
||||||
targetPosition
|
targetPosition.value
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -188,8 +187,8 @@ const EdgeCmp = defineComponent({
|
|||||||
arrowHeadType={props.edge.arrowHeadType}
|
arrowHeadType={props.edge.arrowHeadType}
|
||||||
source={props.edge.source}
|
source={props.edge.source}
|
||||||
target={props.edge.target}
|
target={props.edge.target}
|
||||||
sourceHandleId={sourceHandleId}
|
sourceHandleId={props.edge.sourceHandle}
|
||||||
targetHandleId={targetHandleId}
|
targetHandleId={props.edge.targetHandle}
|
||||||
sourceX={edgePositions.value?.sourceX}
|
sourceX={edgePositions.value?.sourceX}
|
||||||
sourceY={edgePositions.value?.sourceY}
|
sourceY={edgePositions.value?.sourceY}
|
||||||
targetX={edgePositions.value?.targetX}
|
targetX={edgePositions.value?.targetX}
|
||||||
@@ -218,7 +217,8 @@ const EdgeRenderer = defineComponent({
|
|||||||
name: 'EdgeRenderer',
|
name: 'EdgeRenderer',
|
||||||
components: {
|
components: {
|
||||||
EdgeCmp,
|
EdgeCmp,
|
||||||
ConnectionLine
|
ConnectionLine,
|
||||||
|
MarkerDefinitions
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
edgeTypes: {
|
edgeTypes: {
|
||||||
@@ -247,12 +247,12 @@ const EdgeRenderer = defineComponent({
|
|||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onElementClick: {
|
onElementClick: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onElementClick']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onElementClick']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeDoubleClick: {
|
onEdgeDoubleClick: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeDoubleClick']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeDoubleClick']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
@@ -272,37 +272,37 @@ const EdgeRenderer = defineComponent({
|
|||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeUpdate: {
|
onEdgeUpdate: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeUpdate']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeUpdate']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeContextMenu: {
|
onEdgeContextMenu: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeContextMenu']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeContextMenu']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeMouseEnter: {
|
onEdgeMouseEnter: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeMouseEnter']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeMouseEnter']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeMouseMove: {
|
onEdgeMouseMove: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeMouseMove']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeMouseMove']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeMouseLeave: {
|
onEdgeMouseLeave: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeMouseLeave']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeMouseLeave']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeUpdateStart: {
|
onEdgeUpdateStart: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeUpdateStart']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeUpdateStart']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
onEdgeUpdateEnd: {
|
onEdgeUpdateEnd: {
|
||||||
type: Function() as PropType<EdgeRendererProps['onEdgeUpdateEnd']>,
|
type: Function as unknown as PropType<EdgeRendererProps['onEdgeUpdateEnd']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined
|
default: undefined
|
||||||
},
|
},
|
||||||
@@ -314,11 +314,15 @@ const EdgeRenderer = defineComponent({
|
|||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const pinia = store();
|
const pinia = store();
|
||||||
const transformStyle = computed(() => `translate(${pinia.transform[0]},${pinia.transform[1]}) scale(${pinia.transform[2]})`);
|
const transform = computed(() => pinia.transform);
|
||||||
|
const transformStyle = computed(() => {
|
||||||
|
return `translate(${transform.value[0]},${transform.value[1]}) scale(${transform.value[2]})`;
|
||||||
|
});
|
||||||
const renderConnectionLine = computed(() => pinia.connectionNodeId && pinia.connectionHandleType);
|
const renderConnectionLine = computed(() => pinia.connectionNodeId && pinia.connectionHandleType);
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<svg width={pinia.width} height={pinia.height} class="revue-flow__edges">
|
<svg width={pinia.width} height={pinia.height} class="revue-flow__edges">
|
||||||
|
<MarkerDefinitions color={props.arrowHeadColor || ''} />
|
||||||
<g transform={transformStyle.value}>
|
<g transform={transformStyle.value}>
|
||||||
{pinia.edges.map((edge: Edge) => (
|
{pinia.edges.map((edge: Edge) => (
|
||||||
<EdgeCmp
|
<EdgeCmp
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export function getHandlePosition(position: Position, node: Node, handle: any |
|
|||||||
const width = handle?.width || node.__rf.width;
|
const width = handle?.width || node.__rf.width;
|
||||||
const height = handle?.height || node.__rf.height;
|
const height = handle?.height || node.__rf.height;
|
||||||
|
|
||||||
|
console.log(handle?.x, handle?.y);
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case Position.Top:
|
case Position.Top:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { computed, CSSProperties, defineComponent, HTMLAttributes, onUpdated, PropType } from 'vue';
|
import { computed, CSSProperties, defineComponent, HTMLAttributes, onBeforeUnmount, onUpdated, PropType } from 'vue';
|
||||||
import GraphView from '../GraphView';
|
import GraphView from '../GraphView';
|
||||||
import DefaultNode from '../../components/Nodes/DefaultNode';
|
import DefaultNode from '../../components/Nodes/DefaultNode';
|
||||||
import InputNode from '../../components/Nodes/InputNode';
|
import InputNode from '../../components/Nodes/InputNode';
|
||||||
@@ -27,7 +27,6 @@ import {
|
|||||||
OnEdgeUpdateFunc,
|
OnEdgeUpdateFunc,
|
||||||
NodeExtent
|
NodeExtent
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import '../../style.css';
|
import '../../style.css';
|
||||||
import '../../theme-default.css';
|
import '../../theme-default.css';
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
@@ -259,7 +258,7 @@ const RevueFlow = defineComponent({
|
|||||||
connectionLineStyle: {
|
connectionLineStyle: {
|
||||||
type: Object as PropType<RevueFlowProps['connectionLineStyle']>,
|
type: Object as PropType<RevueFlowProps['connectionLineStyle']>,
|
||||||
required: false,
|
required: false,
|
||||||
default: () => ({} as CSSProperties)
|
default: undefined
|
||||||
},
|
},
|
||||||
connectionLineComponent: {
|
connectionLineComponent: {
|
||||||
type: Object as PropType<RevueFlowProps['connectionLineComponent']>,
|
type: Object as PropType<RevueFlowProps['connectionLineComponent']>,
|
||||||
@@ -459,12 +458,15 @@ const RevueFlow = defineComponent({
|
|||||||
pinia.setElements(props.elements);
|
pinia.setElements(props.elements);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
pinia.setElements([]);
|
||||||
|
});
|
||||||
|
|
||||||
const nodeTypesParsed = computed(() => props.nodeTypes && createNodeTypes(props.nodeTypes));
|
const nodeTypesParsed = computed(() => props.nodeTypes && createNodeTypes(props.nodeTypes));
|
||||||
const edgeTypesParsed = computed(() => props.edgeTypes && createEdgeTypes(props.edgeTypes));
|
const edgeTypesParsed = computed(() => props.edgeTypes && createEdgeTypes(props.edgeTypes));
|
||||||
const reactFlowClasses = ['revue-flow'];
|
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class={reactFlowClasses}>
|
<div class="revue-flow">
|
||||||
<GraphView
|
<GraphView
|
||||||
onLoad={props.onLoad}
|
onLoad={props.onLoad}
|
||||||
onMove={props.onMove}
|
onMove={props.onMove}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import { createApp } from 'vue';
|
|
||||||
import App from './App.vue';
|
|
||||||
|
|
||||||
const app = createApp(App);
|
|
||||||
app.config.performance = true;
|
|
||||||
app.mount('#app');
|
|
||||||
Vendored
+6
@@ -4,3 +4,9 @@ declare module '*.vue' {
|
|||||||
const component: DefineComponent<{}, {}, any>;
|
const component: DefineComponent<{}, {}, any>;
|
||||||
export default component;
|
export default component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare namespace JSX {
|
||||||
|
export interface IntrinsicElements {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { setActivePinia, createPinia, defineStore, StoreDefinition } from 'pinia';
|
import { setActivePinia, createPinia, defineStore, StoreDefinition, Pinia } from 'pinia';
|
||||||
|
import { inject } from 'vue';
|
||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { Edge, Node, NodeDiffUpdate, ReactFlowState, RevueFlowActionsTree, XYPosition } from '../types';
|
import { Edge, Node, NodeDiffUpdate, ReactFlowState, RevueFlowActionsTree, XYPosition } from '../types';
|
||||||
import { getConnectedEdges, getNodesInside, getRectOfNodes, isEdge, isNode, parseEdge, parseNode } from '../utils/graph';
|
import { getConnectedEdges, getNodesInside, getRectOfNodes, isEdge, isNode, parseEdge, parseNode } from '../utils/graph';
|
||||||
@@ -10,12 +11,12 @@ type NextElements = {
|
|||||||
nextEdges: Edge[];
|
nextEdges: Edge[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const pinia = createPinia();
|
|
||||||
setActivePinia(pinia);
|
|
||||||
|
|
||||||
export default function configureStore(
|
export default function configureStore(
|
||||||
preloadedState: ReactFlowState
|
preloadedState: ReactFlowState
|
||||||
): StoreDefinition<'revue-flow', ReactFlowState, any, RevueFlowActionsTree> {
|
): StoreDefinition<'revue-flow', ReactFlowState, any, RevueFlowActionsTree> {
|
||||||
|
const pinia = inject<Pinia>(Symbol('pinia')) ?? createPinia();
|
||||||
|
setActivePinia(pinia);
|
||||||
|
|
||||||
return defineStore({
|
return defineStore({
|
||||||
id: 'revue-flow',
|
id: 'revue-flow',
|
||||||
state: () => preloadedState,
|
state: () => preloadedState,
|
||||||
|
|||||||
+1
-1
@@ -58,6 +58,6 @@ export const initialState: ReactFlowState = {
|
|||||||
|
|
||||||
const store = configureStore(initialState);
|
const store = configureStore(initialState);
|
||||||
|
|
||||||
export type ReactFlowDispatch = RevueFlowActionsTree;
|
export type RevueFlowDispatch = RevueFlowActionsTree;
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|||||||
Vendored
+1
@@ -1 +1,2 @@
|
|||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="vite-svg-loader" />
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,7 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
|
import svgLoader from 'vite-svg-loader';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -11,6 +12,7 @@ export default defineConfig({
|
|||||||
vue(),
|
vue(),
|
||||||
vueJsx({
|
vueJsx({
|
||||||
// options are passed on to @vue/babel-plugin-jsx
|
// options are passed on to @vue/babel-plugin-jsx
|
||||||
})
|
}),
|
||||||
|
svgLoader()
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user