update(docs): Add all examples

This commit is contained in:
Braks
2021-11-06 08:54:35 +01:00
parent 61779638ac
commit e99dfc3dd2
54 changed files with 2582 additions and 285 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<Header />
<div class="h-full flex flex-row">
<div class="flex h-full">
<Sidebar />
<div id="vue-flow-docs" class="flex-1">
<NuxtPage />
+13 -2
View File
@@ -16,10 +16,17 @@ body,
margin: 0;
height: 100%;
color: #111;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
background-image: url('./polygon-scatter.svg');
}
#__nuxt {
position: relative;
}
.backround-img {
background-position: center;
background-size: cover;
background-repeat: no-repeat;
@@ -42,7 +49,7 @@ header {
}
header a:hover {
color: whitesmoke;
color: #c9c9c9;
}
header select {
@@ -95,7 +102,11 @@ header select {
}
#vue-flow-docs {
height: 100%;
display: flex;
margin:0;
background: #fff;
}
.button {
@apply bg-gray-200 hover:bg-gray-300 focus:outline-none font-bold mr-2 border-2 p-2 rounded-xl;
}
+80
View File
@@ -0,0 +1,80 @@
<script lang="ts" setup>
import {
useHooks,
useStore,
getEdgeCenter,
getBezierPath,
getMarkerEnd,
ArrowHeadType,
EdgeProps,
ElementId,
Position,
} from '@braks/vue-flow'
interface CustomEdgeProps<T = any> extends EdgeProps<T> {
id: ElementId
sourceX: number
sourceY: number
targetX: number
targetY: number
sourcePosition: Position
targetPosition: Position
arrowHeadType?: ArrowHeadType
markerEndId?: string
data?: T
}
const props = defineProps<CustomEdgeProps>()
const store = useStore()
const hooks = useHooks()
const onEdgeClick = (evt: Event, id: string) => {
const edge = store.edges.find((edge) => edge.id === id)
if (edge) {
hooks.elementsRemove.trigger([edge])
}
evt.stopPropagation()
alert(`remove ${id}`)
}
const foreignObjectSize = 40
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId))
const center = computed(() =>
getEdgeCenter({
sourceX: props.sourceX,
sourceY: props.sourceY,
targetX: props.targetX,
targetY: props.targetY,
}),
)
</script>
<template>
<path :id="props.id" :style="props.style" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<foreignObject
:width="foreignObjectSize"
:height="foreignObjectSize"
:x="center[0] - foreignObjectSize / 2"
:y="center[1] - foreignObjectSize / 2"
class="edgebutton-foreignobject"
requiredExtensions="http://www.w3.org/1999/xhtml"
>
<body class="p-1">
<button class="edgebutton bg-gray-500 p-[4px] h-full w-full" @click="(event) => onEdgeClick(event, props.id)">×</button>
</body>
</foreignObject>
</template>
<style scoped>
body {
background: unset;
}
</style>
+38
View File
@@ -0,0 +1,38 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { Handle, Position, Connection, Edge, NodeProps } from '@braks/vue-flow'
interface ColorSelectorNodeProps extends NodeProps {
data: {
color: string
onChange: (event: any) => void
}
type: string
selected?: boolean
connectable?: boolean
xPos?: number
yPos?: number
targetPosition?: Position
sourcePosition?: Position
dragging?: boolean
}
const props = defineProps<ColorSelectorNodeProps>()
const targetHandleStyle: CSSProperties = { background: '#555' }
const sourceHandleStyleA: CSSProperties = { ...targetHandleStyle, top: '10px' }
const sourceHandleStyleB: CSSProperties = { ...targetHandleStyle, bottom: '10px', top: 'auto' }
const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params)
</script>
<template>
<div class="py-1 px-1 flex flex-col gap-1 justify-center items-center">
<Handle type="target" :position="Position.Left" :style="targetHandleStyle" :on-connect="onConnect" />
<div class="text-md font-bold">Custom Color Picker Node</div>
<div :style="{ color: data.color }" class="text-md font-semibold">
{{ data.color }}
</div>
<input class="nodrag" type="color" :value="data.color" @input="props.data.onChange" />
<Handle id="a" type="source" :position="Position.Right" :style="sourceHandleStyleA" />
<Handle id="b" type="source" :position="Position.Right" :style="sourceHandleStyleB" />
</div>
</template>
+23
View File
@@ -0,0 +1,23 @@
<script lang="ts" setup>
import { ConnectionLineComponentProps } from '@braks/vue-flow'
interface ConnectionLineProps extends ConnectionLineComponentProps {
sourceX: number
sourceY: number
targetX: number
targetY: number
}
const props = defineProps<ConnectionLineProps>()
</script>
<template>
<g>
<path
class="animated"
fill="none"
stroke="#222"
:stroke-width="1.5"
: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>
</template>
+41
View File
@@ -0,0 +1,41 @@
<script lang="ts" setup>
import { ArrowHeadType, ElementId, getBezierPath, getMarkerEnd, Position, EdgeProps } from '@braks/vue-flow'
interface CustomEdgeProps<T = any> extends EdgeProps<T> {
source: ElementId
target: ElementId
sourceHandleId?: ElementId
targetHandleId?: ElementId
id: ElementId
sourceX: number
sourceY: number
targetX: number
targetY: number
sourcePosition: Position
targetPosition: Position
arrowHeadType?: ArrowHeadType
markerEndId?: string
data?: T
}
const props = defineProps<CustomEdgeProps>()
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId))
</script>
<template>
<path :id="props.id" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<text>
<textPath :href="`#${props.id}`" :style="{ fontSize: '12px' }" startOffset="50%" text-anchor="middle">
{{ props.data.text }}
</textPath>
</text>
</template>
+65
View File
@@ -0,0 +1,65 @@
<script lang="ts" setup>
import {
getBezierPath,
getMarkerEnd,
ArrowHeadType,
EdgeProps,
ElementId,
getEdgeCenter,
Position,
EdgeText,
} from '@braks/vue-flow'
interface CustomEdgeProps<T = any> extends EdgeProps<T> {
source: ElementId
target: ElementId
sourceHandleId?: ElementId
targetHandleId?: ElementId
id: ElementId
sourceX: number
sourceY: number
targetX: number
targetY: number
sourcePosition: Position
targetPosition: Position
arrowHeadType?: ArrowHeadType
markerEndId?: string
data?: T
}
const props = defineProps<CustomEdgeProps>()
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const markerEnd = computed(() => getMarkerEnd(props.arrowHeadType, props.markerEndId))
const center = computed(() =>
getEdgeCenter({
sourceX: props.sourceX,
sourceY: props.sourceY,
targetX: props.targetX,
targetY: props.targetY,
}),
)
</script>
<template>
<path :id="props.id" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<EdgeText
:x="center[0]"
:y="center[1]"
:label="props.data?.text"
:label-style="{ fill: 'white' }"
:label-show-bg="true"
:label-bg-style="{ fill: 'red' }"
:label-bg-padding="[2, 4]"
:label-bg-border-radius="2"
@click="() => console.log(props.data)"
/>
</template>
+10
View File
@@ -0,0 +1,10 @@
<script lang="ts" setup>
interface CustomLabelProps {
text: string
}
const props = defineProps<CustomLabelProps>()
</script>
<template>
<tspan dy="10" x="0">{{ props.text }}</tspan>
</template>
+47
View File
@@ -0,0 +1,47 @@
<script lang="ts" setup>
const onDragStart = (event: DragEvent, nodeType: string) => {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', nodeType)
event.dataTransfer.effectAllowed = 'move'
}
}
</script>
<template>
<aside class="md:(w-[30%] max-w-[200px])">
<div class="mb-6">You can drag these nodes to the pane on the left.</div>
<div
class="droppable-node vue-flow__node-input"
:draggable="true"
@dragstart="(event: DragEvent) => onDragStart(event, 'input')"
>
Input Node
</div>
<div
class="droppable-node vue-flow__node-default"
:draggable="true"
@dragstart="(event: DragEvent) => onDragStart(event, 'default')"
>
Default Node
</div>
<div
class="droppable-node vue-flow__node-output"
:draggable="true"
@dragstart="(event: DragEvent) => onDragStart(event, 'output')"
>
Output Node
</div>
</aside>
</template>
<style scoped>
aside {
border-right: 1px solid #eee;
padding: 15px 10px;
font-size: 12px;
background: #fcfcfc;
}
.droppable-node {
@apply mb-6;
cursor: grab;
}
</style>
+20
View File
@@ -0,0 +1,20 @@
<script lang="ts" setup>
import Flow, { Background, Connection, Elements, Edge, removeElements, addEdge } from '@braks/vue-flow'
const initialElements: Elements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, class: 'light' },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, class: 'light' },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, class: 'light' },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, class: 'light' },
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' },
]
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
</script>
<template>
<Flow :elements="elements" @elements-remove="onElementsRemove" @connect="onConnect">
<Background />
</Flow>
</template>
+1 -1
View File
@@ -11,6 +11,6 @@
<div class="flex-1">
<router-link to="/examples"> Examples </router-link>
</div>
<div class="flex-1">Github</div>
<div class="flex-1"><a href="https://github.com/bcakmakoglu/vue-flow">Github</a></div>
</header>
</template>
+11
View File
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { NodeProps } from '@braks/vue-flow'
interface NodeAProps extends NodeProps {
nodeStyles: Record<string, any>
}
const props = defineProps<NodeAProps>()
</script>
<template>
<div :style="props.nodeStyles">A</div>
</template>
+11
View File
@@ -0,0 +1,11 @@
<script lang="ts" setup>
import { NodeProps } from '@braks/vue-flow'
interface NodeBPro extends NodeProps {
nodeStyles: Record<string, any>
}
const props = defineProps<NodeBPro>()
</script>
<template>
<div :style="props.nodeStyles">B</div>
</template>
+27
View File
@@ -0,0 +1,27 @@
<script lang="ts" setup>
import { useStore } from '@braks/vue-flow'
const store = useStore()
const nodes = computed(() => store.nodes)
const transform = computed(() => store.transform)
const selectAll = () => {
store.selectedElements = nodes.value
store.unsetUserSelection()
}
</script>
<template>
<aside>
<div class="description">This is an example of how you can access the internal state outside of the Vue Flow component.</div>
<div class="title">Zoom & pan transform</div>
<div class="transform">{{ [transform[0].toFixed(2), transform[1].toFixed(2), transform[2].toFixed(2)] }}</div>
<div class="title">Nodes</div>
<div v-for="node of nodes" :key="node.id">
Node {{ node.id }} - x: {{ node.__rf.position.x.toFixed(2) }}, y: {{ node.__rf.position.y.toFixed(2) }}
</div>
<div class="selectall">
<button class="button" @click="selectAll">select all nodes</button>
</div>
</aside>
</template>
+60
View File
@@ -0,0 +1,60 @@
<script lang="ts" setup>
import localforage from 'localforage'
import { useZoomPanHelper, FlowInstance, FlowExportObject, Node } from '@braks/vue-flow'
localforage.config({
name: 'vue-flow',
storeName: 'flows',
})
const flowKey = 'example-flow'
const getNodeId = () => `randomnode_${+new Date()}`
const { transform } = useZoomPanHelper()
type ControlsProps = {
flowInstance?: FlowInstance
}
const props = defineProps<ControlsProps>()
const emit = defineEmits(['restore', 'add'])
const onSave = () => {
if (props.flowInstance) {
const flow = props.flowInstance.toObject()
localforage.setItem(flowKey, flow)
}
}
const onRestore = () => {
const restoreFlow = async () => {
const flow: FlowExportObject | null = await localforage.getItem(flowKey)
console.log(flow)
if (flow) {
const [x = 0, y = 0] = flow.position
emit('restore', flow.elements ?? [])
transform({ x, y, zoom: flow.zoom || 0 })
}
}
restoreFlow()
}
const onAdd = () => {
const newNode = {
id: `random_node-${getNodeId()}`,
data: { label: 'Added node' },
position: { x: Math.random() * window.innerWidth - 100, y: Math.random() * window.innerHeight },
} as Node
emit('add', newNode)
}
</script>
<template>
<div class="save__controls">
<button class="button" @click="onSave">save</button>
<button class="button" @click="onRestore">restore</button>
<button class="button" @click="onAdd">add node</button>
</div>
</template>
+2 -2
View File
@@ -81,7 +81,7 @@ const examples = [
label: 'Unidirectional',
},
{
path: '/updateable-edge',
path: '/updatable-edge',
label: 'Updatable Edge',
},
{
@@ -119,7 +119,7 @@ const examples = [
</template>
<style>
.example-link {
@apply text-md text-white hover:text-black mt-2 p-2 underline;
@apply text-lg text-white hover:text-black py-2 underline;
}
aside {
border-right: 1px solid #eee;
@@ -0,0 +1,19 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { Handle, NodeProps, Position } from '@braks/vue-flow'
interface CustomNodeProps extends NodeProps {
id: string
}
const props = defineProps<CustomNodeProps>()
const nodeStyles: CSSProperties = { padding: '10px 15px', border: '1px solid #ddd' }
</script>
<template>
<div :style="nodeStyles">
<div>node {{ props.id }}</div>
<Handle id="left" type="source" :position="Position.Left" />
<Handle id="right" type="source" :position="Position.Right" />
<Handle id="top" type="source" :position="Position.Top" />
<Handle id="bottom" type="source" :position="Position.Bottom" />
</div>
</template>
@@ -0,0 +1,25 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import { Handle, Position, NodeProps } from '@braks/vue-flow'
interface CustomNodeProps extends NodeProps {
data: any
}
const nodeStyles: CSSProperties = { padding: 10, border: '1px solid #ddd' }
const props = defineProps<CustomNodeProps>()
</script>
<template>
<div :style="nodeStyles">
<Handle type="target" :position="Position.Left" />
<div>output handle count: {{ props.data.handleCount }}</div>
<Handle
v-for="i of props.data.handleCount"
:id="`handle-${i}`"
:key="`handle-${i}`"
type="source"
:position="Position.Right"
:style="{ top: 10 * i + props.data.handlePosition * 10 }"
/>
</div>
</template>
@@ -0,0 +1,9 @@
<script lang="ts" setup>
import { Position, Handle, Connection } from '@braks/vue-flow'
const isValidConnection = (connection: Connection) => connection.target === 'B'
</script>
<template>
<div>Only connectable with B</div>
<Handle type="source" :position="Position.Right" :is-valid-connection="isValidConnection" />
</template>
+16
View File
@@ -0,0 +1,16 @@
<script lang="ts" setup>
import { Position, Handle, Connection, NodeProps } from '@braks/vue-flow'
interface CustomNodeProps extends NodeProps {
id: string
}
const props = defineProps<CustomNodeProps>()
const isValidConnection = (connection: Connection) => connection.target === 'B'
</script>
<template>
<Handle type="target" :position="Position.Left" :is-valid-connection="isValidConnection" />
<div>{{ props.id }}</div>
<Handle type="source" :position="Position.Right" :is-valid-connection="isValidConnection" />
</template>
+3 -3
View File
@@ -7,11 +7,11 @@
},
"dependencies": {
"@braks/vue-flow": "link:..",
"@pinia/nuxt": "^0.0.9",
"add": "^2.0.6",
"pinia": "^2.0.0-rc.14"
"dagre": "^0.8.5",
"localforage": "^1.10.0"
},
"devDependencies": {
"@types/dagre": "^0.7.46",
"nuxt-windicss": "^2.0.4",
"nuxt3": "latest"
}
+19 -7
View File
@@ -26,7 +26,10 @@ const elements = ref<Elements>([
])
const rfInstance = ref<FlowInstance | null>(null)
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onConnect = (params: Edge | Connection) => (elements.value = addEdge(params, elements.value))
const onConnect = (params: Edge | Connection) => {
elements.value = addEdge(params, elements.value)
console.log(params)
}
const onLoad = (flowInstance: FlowInstance) => {
flowInstance.fitView({ padding: 0.1 })
rfInstance.value = flowInstance
@@ -49,7 +52,7 @@ const resetTransform = () => rfInstance.value?.setTransform({ x: 0, y: 0, zoom:
const toggleClassnames = () => {
elements.value = elements.value.map((el: FlowElement) => {
if (isNode(el)) el.class = el.class === 'light' ? 'dark' : 'light'
if (isNode(el)) el.class = el.class === 'dark' ? 'light' : 'dark'
return el
})
}
@@ -71,11 +74,20 @@ const toggleClassnames = () => {
<MiniMap />
<Controls />
<Background color="#aaa" :gap="8" />
<div style="position: absolute; right: 10px; top: 10px; z-index: 4">
<button style="margin-right: 5px" @click="resetTransform">reset transform</button>
<button style="margin-right: 5px" @click="updatePos">change pos</button>
<button style="margin-right: 5px" @click="toggleClassnames">toggle classnames</button>
<button @click="logToObject">toObject</button>
<div class="absolute right-[10px] top-[10px] z-4">
<button class="button" @click="resetTransform">reset transform</button>
<button class="button" @click="updatePos">change pos</button>
<button class="button" @click="toggleClassnames">toggle classnames</button>
<button class="button" @click="logToObject">toObject</button>
</div>
</Flow>
</template>
<style>
.vue-flow--node .light {
@apply bg-white;
}
.vue-flow--node .dark {
@apply bg-black;
}
</style>
+54
View File
@@ -0,0 +1,54 @@
<script lang="ts" setup>
import Flow, {
addEdge,
Background,
Connection,
Controls,
Edge,
EdgeType,
Elements,
MiniMap,
FlowInstance,
removeElements,
} from '@braks/vue-flow'
import ButtonEdge from '../../components/ButtonEdge.vue'
const edgeTypes = {
buttonedge: ButtonEdge as EdgeType,
}
const elements = ref<Elements>([
{
id: 'ewb-1',
type: 'input',
data: { label: 'Input 1' },
position: { x: 250, y: 0 },
},
{ id: 'ewb-2', data: { label: 'Node 2' }, position: { x: 250, y: 300 } },
{
id: 'edge-1-2',
source: 'ewb-1',
target: 'ewb-2',
type: 'buttonedge',
},
])
const onLoad = (flowInstance: FlowInstance) => flowInstance.fitView()
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onConnect = (params: Connection | Edge) =>
(elements.value = addEdge({ ...params, type: 'buttonedge' } as Edge, elements.value))
</script>
<template>
<Flow
key="edge-with-button"
:elements="elements"
:snap-to-grid="true"
:edge-types="edgeTypes"
@load="onLoad"
@elementsRemove="onElementsRemove"
@connect="onConnect"
>
<MiniMap />
<Controls />
<Background />
</Flow>
</template>
@@ -0,0 +1,23 @@
<script lang="ts" setup>
import Flow, { removeElements, addEdge, Background, BackgroundVariant, Elements, Connection, Edge } from '@braks/vue-flow'
import CustomConnectionLine from '../../components/CustomConnectionLine.vue'
const elements = ref<Elements>([
{
id: '1',
type: 'input',
data: { label: 'Node 1' },
position: { x: 250, y: 5 },
},
])
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
</script>
<template>
<Flow :elements="elements" @elements-remove="onElementsRemove" @connect="onConnect">
<template #custom-connection-line="props">
<CustomConnectionLine v-bind="props" />
</template>
<Background :variant="BackgroundVariant.Lines" />
</Flow>
</template>
+131
View File
@@ -0,0 +1,131 @@
<script lang="ts" setup>
import Flow, {
isEdge,
removeElements,
addEdge,
MiniMap,
Controls,
Node,
FlowElement,
FlowInstance,
Elements,
Position,
SnapGrid,
Connection,
ConnectionMode,
Edge,
} from '@braks/vue-flow'
import ColorPickerNode from '../../components/ColorPickerNode.vue'
const elements = ref<Elements>([])
const bgColor = ref('#1A192B')
const connectionLineStyle = { stroke: '#fff' }
const snapGrid: SnapGrid = [16, 16]
const nodeTypes = {
selectorNode: ColorPickerNode,
}
const onLoad = (flowInstance: FlowInstance) => {
flowInstance.fitView()
console.log('flow loaded:', flowInstance)
}
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
const nodeStroke = (n: Node): string => {
if (n.type === 'input') return '#0041d0'
if (n.type === 'selectorNode') return bgColor.value
if (n.type === 'output') return '#ff0072'
return '#eee'
}
const nodeColor = (n: Node): string => {
if (n.type === 'selectorNode') return bgColor.value
return '#fff'
}
onMounted(() => {
const onChange = (event: Event) => {
elements.value = elements.value.map((e: FlowElement) => {
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, color: bgColor.value },
style: { border: '1px solid #777', padding: '10px' },
position: { x: 250, y: 50 },
},
{
id: '3',
type: 'output',
data: { label: 'Output A' },
position: { x: 650, y: 25 },
targetPosition: Position.Left,
},
{
id: '4',
type: 'output',
data: { label: 'Output B' },
position: { x: 650, 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' },
} as Edge,
elements.value,
))
</script>
<template>
<Flow
:elements="elements"
:style="`background: ${bgColor}`"
:node-types="nodeTypes"
:connection-mode="ConnectionMode.Loose"
:connection-line-style="connectionLineStyle"
:snap-to-grid="true"
:snap-grid="snapGrid"
:default-zoom="1.5"
@element-click="onElementClick"
@elements-remove="onElementsRemove"
@connect="onConnect"
@node-drag-stop="onNodeDragStop"
@load="onLoad"
>
<MiniMap :node-stroke-color="nodeStroke" :node-color="nodeColor" />
<Controls />
</Flow>
</template>
+69
View File
@@ -0,0 +1,69 @@
<script lang="ts" setup>
import Flow, {
addEdge,
removeElements,
Controls,
MiniMap,
Background,
FlowInstance,
Elements,
Connection,
Edge,
ElementId,
} from '@braks/vue-flow'
import Sidebar from '../../components/DnDSidebar.vue'
const flowInstance = ref<FlowInstance>()
const elements = ref<Elements>([
{
id: '1',
type: 'input',
data: { label: 'input node' },
position: { x: 250, y: 5 },
},
])
let id = 0
const getId = (): ElementId => `dndnode_${id++}`
const onDragOver = (event: DragEvent) => {
event.preventDefault()
if (event.dataTransfer) {
event.dataTransfer.dropEffect = 'move'
}
}
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onLoad = (instance: FlowInstance) => (flowInstance.value = instance)
const onDrop = (event: DragEvent) => {
event.preventDefault()
if (flowInstance.value) {
console.log(event.dataTransfer?.getData('application/vueflow'))
const type = event.dataTransfer?.getData('application/vueflow')
const position = flowInstance.value.project({ x: event.clientX - 400, y: event.clientY - 40 })
const newNode = {
id: getId(),
type,
position,
data: { label: `${type} node` },
}
elements.value.push(newNode)
}
}
</script>
<template>
<div class="flex flex-col md:flex-row h-full">
<div class="flex-1 h-full" @drop="onDrop">
<Flow :elements="elements" @elements-remove="onElementsRemove" @load="onLoad" @connect="onConnect" @dragover="onDragOver">
<Controls />
<MiniMap />
<Background color="#aaa" :gap="8" />
</Flow>
</div>
<Sidebar />
</div>
</template>
+32
View File
@@ -0,0 +1,32 @@
<script lang="ts" setup>
/**
* Example for checking the different edge types and source and target positions
*/
import Flow, {
removeElements,
addEdge,
MiniMap,
Controls,
Background,
FlowInstance,
Connection,
Edge,
Elements,
} from '@braks/vue-flow'
import { getElements } from './edgeTypesUtils'
const onLoad = (flowInstance: FlowInstance) => {
flowInstance.fitView()
console.log(flowInstance.getElements())
}
const elements = ref<Elements>(getElements())
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
</script>
<template>
<Flow :elements="elements" :min-zoom="0.2" @load="onLoad" @elements-remove="onElementsRemove" @connect="onConnect">
<MiniMap />
<Controls />
</Flow>
</template>
+106
View File
@@ -0,0 +1,106 @@
import { ElementId, Elements, Position } from '@braks/vue-flow'
const nodeWidth = 80
const nodeGapWidth = nodeWidth * 2
const nodeStyle = { width: `${nodeWidth}px`, fontSize: '11px', color: 'white' }
const sourceTargetPositions = [
{ source: Position.Bottom, target: Position.Top },
{ source: Position.Right, target: Position.Left },
]
const nodeColors = [
['#1e9e99', '#4cb3ac', '#6ec9c0', '#8ddfd4'],
['#0f4c75', '#1b5d8b', '#276fa1', '#3282b8'],
]
const edgeTypes = ['default', 'step', 'smoothstep', 'straight']
const offsets = [
{
x: 0,
y: -nodeGapWidth,
},
{
x: nodeGapWidth,
y: -nodeGapWidth,
},
{
x: nodeGapWidth,
y: 0,
},
{
x: nodeGapWidth,
y: nodeGapWidth,
},
{
x: 0,
y: nodeGapWidth,
},
{
x: -nodeGapWidth,
y: nodeGapWidth,
},
{
x: -nodeGapWidth,
y: 0,
},
{
x: -nodeGapWidth,
y: -nodeGapWidth,
},
]
let id = 0
const getNodeId = (): ElementId => (id++).toString()
export function getElements(): Elements {
const initialElements = []
for (let sourceTargetIndex = 0; sourceTargetIndex < sourceTargetPositions.length; sourceTargetIndex++) {
const currSourceTargetPos = sourceTargetPositions[sourceTargetIndex]
for (let edgeTypeIndex = 0; edgeTypeIndex < edgeTypes.length; edgeTypeIndex++) {
const currEdgeType = edgeTypes[edgeTypeIndex]
for (let offsetIndex = 0; offsetIndex < offsets.length; offsetIndex++) {
const currOffset = offsets[offsetIndex]
const style = { ...nodeStyle, background: nodeColors[sourceTargetIndex][edgeTypeIndex] }
const sourcePosition = {
x: offsetIndex * nodeWidth * 4,
y: edgeTypeIndex * 300 + sourceTargetIndex * edgeTypes.length * 300,
}
const sourceId = getNodeId()
const sourceData = { label: `Source ${sourceId}` }
const sourceNode = {
id: sourceId,
style,
data: sourceData,
position: sourcePosition,
sourcePosition: currSourceTargetPos.source,
targetPosition: currSourceTargetPos.target,
}
const targetId = getNodeId()
const targetData = { label: `Target ${targetId}` }
const targetPosition = {
x: sourcePosition.x + currOffset.x,
y: sourcePosition.y + currOffset.y,
}
const targetNode = {
id: targetId,
style,
data: targetData,
position: targetPosition,
sourcePosition: currSourceTargetPos.source,
targetPosition: currSourceTargetPos.target,
}
initialElements.push(sourceNode)
initialElements.push(targetNode)
initialElements.push({ id: `${sourceId}-${targetId}`, source: sourceId, target: targetId, type: currEdgeType })
}
}
}
return initialElements
}
+105
View File
@@ -0,0 +1,105 @@
<script lang="ts" setup>
import Flow, {
MiniMap,
Controls,
Background,
Elements,
FlowInstance,
FlowElement,
removeElements,
Connection,
Edge,
addEdge,
ArrowHeadType,
} from '@braks/vue-flow'
import CustomEdge from '../../components/CustomEdge.vue'
import CustomEdge2 from '../../components/CustomEdge2.vue'
import CustomLabel from '../../components/CustomLabel.vue'
const initialElements: Elements = [
{ id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 150, y: 100 } },
{ id: '2a', data: { label: 'Node 2a' }, position: { x: 0, y: 180 } },
{ id: '3', data: { label: 'Node 3' }, position: { x: 250, y: 200 } },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 300 } },
{ id: '3a', data: { label: 'Node 3a' }, position: { x: 150, y: 300 } },
{ id: '5', data: { label: 'Node 5' }, position: { x: 250, y: 400 } },
{ id: '6', type: 'output', data: { label: 'Output 6' }, position: { x: 50, y: 550 } },
{ id: '7', type: 'output', data: { label: 'Output 7' }, position: { x: 250, y: 550 } },
{ id: '8', type: 'output', data: { label: 'Output 8' }, position: { x: 525, y: 600 } },
{ id: '9', type: 'output', data: { label: 'Output 9' }, position: { x: 675, y: 500 } },
{ id: 'e1-2', source: '1', target: '2', label: 'bezier edge (default)', class: 'normal-edge' },
{ id: 'e2-2a', source: '2', target: '2a', type: 'smoothstep', label: 'smoothstep edge' },
{ id: 'e2-3', source: '2', target: '3', type: 'step', label: 'step edge' },
{ id: 'e3-4', source: '3', target: '4', type: 'straight', label: 'straight edge' },
{ id: 'e3-3a', source: '3', target: '3a', type: 'straight', label: 'label only edge', style: { stroke: 'none' } },
{ id: 'e3-5', source: '4', target: '5', animated: true, label: 'animated styled edge', style: { stroke: 'red' } },
{
id: 'e5-6',
source: '5',
target: '6',
label: {
component: CustomLabel,
props: {
text: 'custom label text',
},
},
labelStyle: { fill: 'red', fontWeight: 700 },
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e5-7',
source: '5',
target: '7',
label: 'label with styled bg',
labelBgPadding: [8, 4],
labelBgBorderRadius: 4,
labelBgStyle: { fill: '#FFCC00', color: '#fff', fillOpacity: 0.7 },
arrowHeadType: ArrowHeadType.ArrowClosed,
},
{
id: 'e5-8',
source: '5',
target: '8',
type: 'custom',
data: { text: 'custom edge' },
arrowHeadType: ArrowHeadType.ArrowClosed,
},
{
id: 'e5-9',
source: '5',
target: '9',
type: 'custom2',
data: { text: 'custom edge 2' },
},
]
const edgeTypes: Record<string, any> = {
custom: CustomEdge,
custom2: CustomEdge2,
}
const elements = ref<Elements>(initialElements)
const onLoad = (flowInstance: FlowInstance) => flowInstance.fitView()
const onNodeDragStop = (node: Node) => console.log('drag stop', node)
const onElementClick = (element: FlowElement) => console.log('click', element)
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
</script>
<template>
<Flow
:elements="elements"
:snap-to-grid="true"
:edge-types="edgeTypes"
@element-click="onElementClick"
@elements-remove="onElementsRemove"
@connect="onConnect"
@node-drag-stop="onNodeDragStop"
@load="onLoad"
>
<MiniMap />
<Controls />
<Background />
</Flow>
</template>
+53
View File
@@ -0,0 +1,53 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import Flow, {
MiniMap,
Controls,
Background,
BackgroundVariant,
Connection,
Edge,
ElementId,
Elements,
FlowElement,
Node,
FlowInstance,
addEdge,
removeElements,
} from '@braks/vue-flow'
const elements = ref<Elements>([])
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onLoad = (flowInstance: FlowInstance) => console.log('flow loaded:', flowInstance)
const onElementClick = (element: FlowElement) => console.log('click', element)
const onNodeDragStop = (node: Node) => console.log('drag stop', node)
const buttonStyle: CSSProperties = { position: 'absolute', left: '10px', top: '10px', zIndex: 4 }
const addRandomNode = () => {
const nodeId: ElementId = (elements.value.length + 1).toString()
const newNode: Node = {
id: nodeId,
data: { label: `Node: ${nodeId}` },
position: { x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight },
} as Node
elements.value = [...elements.value, newNode]
}
</script>
<template>
<Flow
:elements="elements"
@load="onLoad"
@element-click="onElementClick"
@elements-remove="onElementsRemove"
@connect="(p) => onConnect(p)"
@node-drag-stop="onNodeDragStop"
>
<MiniMap />
<Controls />
<Background :variant="BackgroundVariant.Lines" />
<button class="button" type="button" :style="buttonStyle" @click="addRandomNode">add node</button>
</Flow>
</template>
+39
View File
@@ -0,0 +1,39 @@
<script lang="ts" setup>
import Flow, { MiniMap, Controls, Connection, Edge, Elements, addEdge } from '@braks/vue-flow'
const initialElements: 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: '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' },
{ id: 'e1-3', source: '1', target: '3' },
{ id: 'e3-4', source: '3', target: '4' },
]
const elements = ref<Elements>(initialElements)
const isHidden = ref<boolean>(false)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
watchEffect(() => {
elements.value = elements.value.map((e) => {
e.isHidden = isHidden.value
return e
})
})
</script>
<template>
<Flow :elements="elements" @connect="onConnect">
<MiniMap />
<Controls />
<div :style="{ position: 'absolute', left: '10px', top: '10px', zIndex: 4 }">
<div>
<label for="ishidden">
isHidden
<input id="ishidden" v-model="isHidden" type="checkbox" class="vue-flow__ishidden" />
</label>
</div>
</div>
</Flow>
</template>
@@ -0,0 +1,71 @@
import { Elements, XYPosition } from '@braks/vue-flow'
const position: XYPosition = { x: 0, y: 0 }
const elements: Elements = [
{
id: '1',
type: 'input',
data: { label: 'input' },
position,
},
{
id: '2',
data: { label: 'node 2' },
position,
},
{
id: '2a',
data: { label: 'node 2a' },
position,
},
{
id: '2b',
data: { label: 'node 2b' },
position,
},
{
id: '2c',
data: { label: 'node 2c' },
position,
},
{
id: '2d',
data: { label: 'node 2d' },
position,
},
{
id: '3',
data: { label: 'node 3' },
position,
},
{
id: '4',
data: { label: 'node 4' },
position,
},
{
id: '5',
data: { label: 'node 5' },
position,
},
{
id: '6',
type: 'output',
data: { label: 'output' },
position,
},
{ id: '7', type: 'output', data: { label: 'output' }, position: { x: 400, y: 450 } },
{ id: 'e12', source: '1', target: '2', type: 'smoothstep', animated: true },
{ id: 'e13', source: '1', target: '3', type: 'smoothstep', animated: true },
{ id: 'e22a', source: '2', target: '2a', type: 'smoothstep', animated: true },
{ id: 'e22b', source: '2', target: '2b', type: 'smoothstep', animated: true },
{ id: 'e22c', source: '2', target: '2c', type: 'smoothstep', animated: true },
{ id: 'e2c2d', source: '2c', target: '2d', type: 'smoothstep', animated: true },
{ id: 'e45', source: '4', target: '5', type: 'smoothstep', animated: true },
{ id: 'e56', source: '5', target: '6', type: 'smoothstep', animated: true },
{ id: 'e57', source: '5', target: '7', type: 'smoothstep', animated: true },
]
export default elements
+151
View File
@@ -0,0 +1,151 @@
<script lang="ts" setup>
import Flow, {
addEdge,
MiniMap,
Controls,
Elements,
Node,
FlowElement,
Connection,
Edge,
PanOnScrollMode,
FlowTransform,
} from '@braks/vue-flow'
const initialElements: 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: '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 onNodeDragStart = (_: MouseEvent, node: Node) => console.log('drag start', node)
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
const onPaneClick = (event: MouseEvent) => console.log('onPaneClick', event)
const onPaneScroll = (event?: WheelEvent) => console.log('onPaneScroll', event)
const onPaneContextMenu = (event: MouseEvent) => console.log('onPaneContextMenu', event)
const onMoveEnd = (flowTranasform?: FlowTransform) => console.log('onMoveEnd', flowTranasform)
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const isSelectable = ref(false)
const isDraggable = ref(false)
const isConnectable = ref(false)
const zoomOnScroll = ref(false)
const zoomOnPinch = ref(false)
const panOnScroll = ref(false)
const panOnScrollMode = ref<PanOnScrollMode>(PanOnScrollMode.Free)
const zoomOnDoubleClick = ref(false)
const paneMoveable = ref(true)
const captureZoomClick = ref(false)
const captureZoomScroll = ref(false)
const captureElementClick = ref(false)
</script>
<template>
<Flow
:elements="elements"
:elements-selectable="isSelectable"
:nodes-connectable="isConnectable"
:nodes-draggable="isDraggable"
:zoom-on-scroll="zoomOnScroll"
:zoom-on-pinch="zoomOnPinch"
:pan-on-scroll="panOnScroll"
:pan-on-scroll-mode="panOnScrollMode"
:zoom-on-double-click="zoomOnDoubleClick"
:pane-moveable="paneMoveable"
@connect="onConnect"
@element-click="captureElementClick ? onElementClick : undefined"
@node-drag-start="onNodeDragStart"
@node-drag-stop="onNodeDragStop"
@pane-click="captureZoomClick ? onPaneClick : undefined"
@pane-scroll="captureZoomScroll ? onPaneScroll : undefined"
@pane-context-menu="captureZoomClick ? onPaneContextMenu : undefined"
@move-end="onMoveEnd"
>
<MiniMap />
<Controls />
<div :style="{ position: 'absolute', left: 10, top: 10, zIndex: 4 }">
<div>
<label for="draggable">
nodesDraggable
<input id="draggable" v-model="isDraggable" type="checkbox" class="vue-flow__draggable" />
</label>
</div>
<div>
<label for="connectable">
nodesConnectable
<input id="connectable" v-model="isConnectable" type="checkbox" class="vue-flow__connectable" />
</label>
</div>
<div>
<label for="selectable">
elementsSelectable
<input id="selectable" v-model="isSelectable" type="checkbox" class="vue-flow__selectable" />
</label>
</div>
<div>
<label for="zoomonscroll">
zoomOnScroll
<input id="zoomonscroll" v-model="zoomOnScroll" type="checkbox" class="vue-flow__zoomonscroll" />
</label>
</div>
<div>
<label for="zoomonpinch">
zoomOnPinch
<input id="zoomonpinch" v-model="zoomOnPinch" type="checkbox" class="vue-flow__zoomonpinch" />
</label>
</div>
<div>
<label for="panonscroll">
panOnScroll
<input id="panonscroll" v-model="panOnScroll" type="checkbox" class="vue-flow__panonscroll" />
</label>
</div>
<div>
<label>
panOnScrollMode
<select id="panonscrollmode" v-model="panOnScrollMode" class="vue-flow__panonscrollmode">
<option value="free">free</option>
<option value="horizontal">horizontal</option>
<option value="vertical">vertical</option>
</select>
</label>
</div>
<div>
<label for="zoomondbl">
zoomOnDoubleClick
<input id="zoomondbl" v-model="zoomOnDoubleClick" type="checkbox" class="vue-flow__zoomondbl" />
</label>
</div>
<div>
<label for="panemoveable">
paneMoveable
<input id="panemoveable" v-model="paneMoveable" type="checkbox" class="vue-flow__panemoveable" />
</label>
</div>
<div>
<label for="capturezoompaneclick">
capture onPaneClick
<input id="capturezoompaneclick" v-model="captureZoomClick" type="checkbox" class="vue-flow__capturezoompaneclick" />
</label>
</div>
<div>
<label for="capturezoompanescroll">
capture onPaneScroll
<input id="capturezoompanescroll" v-model="captureZoomScroll" type="checkbox" class="vue-flow__capturezoompanescroll" />
</label>
</div>
<div>
<label for="captureelementclick">
capture onElementClick
<input id="captureelementclick" v-model="captureElementClick" type="checkbox" class="vue-flow__captureelementclick" />
</label>
</div>
</div>
</Flow>
</template>
+91
View File
@@ -0,0 +1,91 @@
<script lang="ts" setup>
import dagre from 'dagre'
import Flow, {
Controls,
addEdge,
ConnectionMode,
Connection,
Edge,
Elements,
isNode,
NodeExtent,
Position,
removeElements,
} from '@braks/vue-flow'
import initialElements from './initialLayoutingElements'
const dagreGraph = new dagre.graphlib.Graph()
dagreGraph.setDefaultEdgeLabel(() => ({}))
const nodeExtent: NodeExtent = [
[0, 0],
[1000, 1000],
]
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge({ ...params, animated: true }, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
// todo changing elements not properly updating flowchart...
const onLayout = (direction: string) => {
const isHorizontal = direction === 'LR'
dagreGraph.setGraph({ rankdir: direction })
elements.value.forEach((el) => {
if (isNode(el)) {
dagreGraph.setNode(el.id, { width: 150, height: 50 })
} else {
dagreGraph.setEdge(el.source, el.target)
}
})
dagre.layout(dagreGraph)
elements.value = elements.value.map((el) => {
if (isNode(el)) {
const nodeWithPosition = dagreGraph.node(el.id)
el.targetPosition = isHorizontal ? Position.Left : Position.Top
el.sourcePosition = isHorizontal ? Position.Right : Position.Bottom
el.position = { x: nodeWithPosition.x, y: nodeWithPosition.y }
}
return el
})
console.log(elements.value)
}
</script>
<template>
<div class="layoutflow">
<Flow
:elements="elements"
:node-extent="nodeExtent"
:connection-mode="ConnectionMode.Loose"
@connect="onConnect"
@clements-remove="onElementsRemove"
@load="() => onLayout('TB')"
>
<Controls />
</Flow>
<div class="controls">
<button class="button" :style="{ marginRight: 10 }" @click="() => onLayout('TB')">vertical layout</button>
<button class="button" @click="() => onLayout('LR')">horizontal layout</button>
</div>
</div>
</template>
<style>
.layoutflow {
flex-grow: 1;
position: relative;
}
.layoutflow .controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 10;
}
.controls button {
margin-left: 10px;
}
</style>
+24
View File
@@ -0,0 +1,24 @@
<script lang="ts" setup>
import Flow from '../../components/Flow.vue'
</script>
<template>
<div class="vue-flow__example-multiflows flex-1">
<Flow />
<Flow />
</div>
</template>
<style>
.vue-flow__example-multiflows {
display: flex;
height: 100%;
}
.vue-flow__example-multiflows .vue-flow {
width: 100%;
height: 100%;
}
.vue-flow__example-multiflows .vue-flow:first-child {
border-right: 2px solid #333;
}
</style>
+47
View File
@@ -0,0 +1,47 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import Flow, { addEdge, Connection, Edge, Elements, isEdge, FlowInstance, Position } from '@braks/vue-flow'
const initialElements: Elements = [
{
id: '1',
sourcePosition: Position.Right,
type: 'input',
data: { label: 'Input' },
position: { x: 0, y: 80 },
},
{
id: '2',
type: 'output',
sourcePosition: Position.Right,
targetPosition: Position.Left,
data: { label: 'A Node' },
position: { x: 250, y: 0 },
},
{ id: 'e1-2', source: '1', type: 'smoothstep', target: '2', animated: true },
]
const buttonStyle: CSSProperties = { position: 'absolute', right: 10, top: 30, zIndex: 4 }
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onLoad = (flowInstance: FlowInstance) => flowInstance.fitView()
const changeType = () => {
elements.value = elements.value.map((el) => {
if (isEdge(el) || el.type === 'input') return el
return {
...el,
type: el.type === 'default' ? 'output' : 'default',
}
})
}
</script>
<template>
<Flow :elements="elements" @connect="onConnect" @load="onLoad">
<button class="button mt-2" :style="buttonStyle" @click="changeType">change type</button>
</Flow>
</template>
@@ -0,0 +1,60 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import Flow, { Elements, Position, NodeType, Connection, Edge, addEdge } from '@braks/vue-flow'
import NodeA from '../../components/NodeA.vue'
import NodeB from '../../components/NodeB.vue'
const initialElements: Elements = [
{
id: '1',
sourcePosition: Position.Right,
type: 'input',
data: { label: 'Input' },
position: { x: 0, y: 80 },
},
{
id: '2',
type: 'a',
sourcePosition: Position.Right,
targetPosition: Position.Left,
data: { label: 'A Node' },
position: { x: 250, y: 0 },
},
]
const buttonStyle: CSSProperties = { position: 'absolute', right: 10, top: 30, zIndex: 4 }
const nodeStyles: CSSProperties = { padding: '10px 15px', border: '1px solid #ddd' }
type NodeTypesObject = {
[key: string]: Record<string, NodeType>
}
const nodeTypesObjects: NodeTypesObject = {
a: {
a: NodeA as NodeType,
},
b: {
b: NodeB as NodeType,
},
}
const elements = ref(initialElements)
const nodeTypesId = ref('a')
const changeType = () => {
const id = nodeTypesId.value === 'a' ? 'b' : 'a'
elements.value[1].type = id
nodeTypesId.value = id
}
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
</script>
<template>
<Flow :elements="elements" :node-types="nodeTypesObjects[nodeTypesId]" :node-types-id="nodeTypesId" @connect="onConnect">
<template #node-a>
<NodeA :node-styles="nodeStyles" />
</template>
<template #node-b>
<NodeB :node-styles="nodeStyles" />
</template>
<button class="button mt-2" :style="buttonStyle" @click="changeType">change type</button>
</Flow>
</template>
+96
View File
@@ -0,0 +1,96 @@
<script lang="ts" setup>
import Flow, {
addEdge,
removeElements,
Controls,
FlowInstance,
FlowElement,
Connection,
Edge,
Elements,
ConnectionMode,
useStore,
} from '@braks/vue-flow'
import Sidebar from '../../components/ProviderSidebar.vue'
const onElementClick = (element: FlowElement) => console.log('click', element)
const onLoad = (flowInstance: FlowInstance) => console.log('flow loaded:', flowInstance)
const initialElements: 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: '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' },
]
useStore()
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
</script>
<template>
<div class="providerflow">
<Sidebar />
<div class="vue-flow-wrapper">
<Flow
:elements="elements"
:connection-mode="ConnectionMode.Loose"
@element-click="onElementClick"
@connect="onConnect"
@elements-remove="onElementsRemove"
@load="onLoad"
>
<Controls />
</Flow>
</div>
</div>
</template>
<style>
.providerflow {
flex-direction: column;
display: flex;
height: 100%;
width: 100%;
}
.providerflow aside {
border-right: 1px solid #eee;
padding: 15px 10px;
font-size: 12px;
background: #fcfcfc;
}
.providerflow aside .description {
margin-bottom: 10px;
}
.providerflow aside .title {
font-weight: 700;
margin-bottom: 5px;
}
.providerflow aside .transform {
margin-bottom: 20px;
}
.providerflow .vue-flow-wrapper {
flex-grow: 1;
height: 100%;
}
.providerflow .selectall {
margin-top: 10px;
}
@media screen and (min-width: 768px) {
.providerflow {
flex-direction: row;
}
.providerflow aside {
max-width: 250px;
}
}
</style>
+37
View File
@@ -0,0 +1,37 @@
<script lang="ts" setup>
import Flow, { addEdge, Connection, Node, Edge, Elements, FlowInstance, removeElements } from '@braks/vue-flow'
import Controls from '../../components/SaveControls.vue'
const initialElements: Elements = [
{ id: '1', data: { label: 'Node 1' }, position: { x: 100, y: 100 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 200 } },
{ id: 'e1-2', source: '1', target: '2' },
]
const elements = ref(initialElements)
const flowInstance = ref()
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const onLoad = (instance: FlowInstance) => (flowInstance.value = instance)
const onRestore = (els: Elements) => (elements.value = els)
const onAdd = (el: Node) => (elements.value = elements.value.concat(el))
</script>
<template>
<Flow :elements="elements" @elements-remove="onElementsRemove" @connect="onConnect" @load="onLoad">
<Controls :flow-instance="flowInstance" @restore="onRestore" @add="onAdd" />
</Flow>
</template>
<style>
.save__controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 4;
font-size: 12px;
}
.save__controls button {
margin-left: 5px;
}
</style>
+89
View File
@@ -0,0 +1,89 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import Flow, {
removeElements,
addEdge,
MiniMap,
isNode,
Controls,
Background,
FlowInstance,
Elements,
Connection,
Edge,
} from '@braks/vue-flow'
function getElements(xElements = 10, yElements = 10): Elements {
const initialElements = []
let nodeId = 1
let recentNodeId = null
for (let y = 0; y < yElements; y++) {
for (let x = 0; x < xElements; x++) {
const position = { x: x * 100, y: y * 50 }
const data = { label: `Node ${nodeId}` }
const node = {
id: nodeId.toString(),
style: { width: 50, fontSize: 11 },
data,
position,
}
initialElements.push(node)
if (recentNodeId && nodeId <= xElements * yElements) {
initialElements.push({ id: `${x}-${y}`, source: recentNodeId.toString(), target: nodeId.toString() })
}
recentNodeId = nodeId
nodeId++
}
}
return initialElements
}
const buttonWrapperStyles: CSSProperties = { position: 'absolute', right: 10, top: 10, zIndex: 4 }
const onLoad = (flowInstance: FlowInstance) => {
flowInstance.fitView()
console.log(flowInstance.getElements())
}
const initialElements: Elements = getElements(10, 10)
const elements = ref(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
const updatePos = () => {
elements.value = elements.value.map((el) => {
if (isNode(el)) {
return {
...el,
position: {
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
},
}
}
return el
})
}
const updateElements = () => {
const grid = Math.ceil(Math.random() * 10)
elements.value = getElements(grid, grid)
}
</script>
<template>
<Flow :elements="elements" @load="onLoad" @elementsRemove="onElementsRemove" @connect="onConnect">
<MiniMap />
<Controls />
<Background />
<div :style="buttonWrapperStyles">
<button style="margin-right: 5px" @click="updatePos">change pos</button>
<button @click="updateElements">update elements</button>
</div>
</Flow>
</template>
+47
View File
@@ -0,0 +1,47 @@
<script lang="ts" setup>
import Flow, { removeElements, addEdge, Node, FlowElement, Elements, Connection, Edge } from '@braks/vue-flow'
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
const elementsA: Elements = [
{ id: '1a', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, class: 'light' },
{ id: '2a', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, class: 'light' },
{ id: '3a', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, class: 'light' },
{ id: '4a', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, class: 'light' },
{ id: 'e1-2', source: '1a', target: '2a' },
{ id: 'e1-3', source: '1a', target: '3a' },
]
const elementsB: Elements = [
{ id: 'inputb', type: 'input', data: { label: 'Input' }, position: { x: 300, y: 5 }, class: 'light' },
{ id: '1b', data: { label: 'Node 1' }, position: { x: 0, y: 100 }, class: 'light' },
{ id: '2b', data: { label: 'Node 2' }, position: { x: 200, y: 100 }, class: 'light' },
{ id: '3b', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, class: 'light' },
{ id: '4b', data: { label: 'Node 4' }, position: { x: 600, y: 100 }, class: 'light' },
{ id: 'e1b', source: 'inputb', target: '1b' },
{ id: 'e2b', source: 'inputb', target: '2b' },
{ id: 'e3b', source: 'inputb', target: '3b' },
{ id: 'e4b', source: 'inputb', target: '4b' },
]
const elements = ref(elementsA)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
</script>
<template>
<Flow
:elements="elements"
@element-click="onElementClick"
@elements-remove="onElementsRemove"
@connect="onConnect"
@node-drag-stop="onNodeDragStop"
>
<div :style="{ position: 'absolute', right: '10px', top: '10px', zIndex: 4 }">
<button class="button" style="margin-right: 5px" @click="() => (elements = elementsA)">flow a</button>
<button class="button" @click="() => (elements = elementsB)">flow b</button>
</div>
</Flow>
</template>
+204
View File
@@ -0,0 +1,204 @@
<script lang="ts" setup>
import Flow, {
NodeType,
addEdge,
useZoomPanHelper,
Elements,
Connection,
Edge,
ElementId,
Node,
ConnectionLineType,
ConnectionMode,
updateEdge,
ArrowHeadType,
} from '@braks/vue-flow'
import CustomNode from '../../components/UnidirectionalCustomNode.vue'
const initialElements: Elements = [
{
id: '00',
type: 'custom',
position: { x: 300, y: 250 },
},
{
id: '01',
type: 'custom',
position: { x: 100, y: 50 },
},
{
id: '02',
type: 'custom',
position: { x: 500, y: 50 },
},
{
id: '03',
type: 'custom',
position: { x: 500, y: 500 },
},
{
id: '04',
type: 'custom',
position: { x: 100, y: 500 },
},
{
id: '10',
type: 'custom',
position: { x: 300, y: 5 },
},
{
id: '20',
type: 'custom',
position: { x: 600, y: 250 },
},
{
id: '30',
type: 'custom',
position: { x: 300, y: 600 },
},
{
id: '40',
type: 'custom',
position: { x: 5, y: 250 },
},
{
id: 'e0-1a',
source: '00',
target: '01',
sourceHandle: 'left',
targetHandle: 'bottom',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-1b',
source: '00',
target: '01',
sourceHandle: 'top',
targetHandle: 'right',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-2a',
source: '00',
target: '02',
sourceHandle: 'top',
targetHandle: 'left',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-2b',
source: '00',
target: '02',
sourceHandle: 'right',
targetHandle: 'bottom',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-3a',
source: '00',
target: '03',
sourceHandle: 'right',
targetHandle: 'top',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-3b',
source: '00',
target: '03',
sourceHandle: 'bottom',
targetHandle: 'left',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-4a',
source: '00',
target: '04',
sourceHandle: 'bottom',
targetHandle: 'right',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-4b',
source: '00',
target: '04',
sourceHandle: 'left',
targetHandle: 'top',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-10',
source: '00',
target: '10',
sourceHandle: 'top',
targetHandle: 'bottom',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-20',
source: '00',
target: '20',
sourceHandle: 'right',
targetHandle: 'left',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-30',
source: '00',
target: '30',
sourceHandle: 'bottom',
targetHandle: 'top',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
{
id: 'e0-40',
source: '00',
target: '40',
sourceHandle: 'left',
targetHandle: 'right',
type: 'smoothstep',
arrowHeadType: ArrowHeadType.Arrow,
},
]
const nodeTypes: Record<string, NodeType> = {
custom: CustomNode as NodeType,
}
let id = 4
const getId = (): ElementId => `${id++}`
const elements = ref(initialElements)
const onConnect = (params: Connection | Edge) => (elements.value = addEdge({ ...params, type: 'smoothstep' }, elements.value))
const { project } = useZoomPanHelper()
const onEdgeUpdate = (oldEdge: Edge, newConnection: Connection) =>
(elements.value = updateEdge(oldEdge, newConnection, elements.value))
const onPaneClick = (evt: MouseEvent) =>
(elements.value = elements.value.concat({
id: getId(),
position: project({ x: evt.clientX, y: evt.clientY - 40 }),
type: 'custom',
} as Node))
</script>
<template>
<Flow
:elements="elements"
:node-types="nodeTypes"
:connection-line-type="ConnectionLineType.SmoothStep"
:connection-mode="ConnectionMode.Loose"
@connect="onConnect"
@pane-click="onPaneClick"
@edge-pdate="onEdgeUpdate"
/>
</template>
+88
View File
@@ -0,0 +1,88 @@
<script lang="ts" setup>
import Flow, {
Controls,
updateEdge,
addEdge,
Elements,
FlowInstance,
Connection,
Edge,
removeElements,
FlowEvents,
ConnectionMode,
} from '@braks/vue-flow'
const initialElements: Elements = [
{
id: '1',
type: 'input',
data: {
label: 'Node <strong>A</strong>',
},
position: { x: 250, y: 0 },
},
{
id: '2',
data: {
label: 'Node <strong>B</strong>',
},
position: { x: 100, y: 100 },
},
{
id: '3',
data: {
label: 'Node <strong>C</strong>',
},
position: { x: 400, y: 100 },
style: { background: '#D6D5E6', color: '#333', border: '1px solid #222138', width: 180 },
},
{ id: 'e1-2', source: '1', target: '2', label: 'Updateable edge' },
]
const elements = ref(initialElements)
const onLoad = (flowInstance: FlowInstance) => flowInstance.fitView()
const onEdgeUpdateStart = (edge: Edge) => console.log('start update', edge)
const onEdgeUpdateEnd = (edge: Edge) => console.log('end update', edge)
const onEdgeUpdate = ({ edge, connection }: FlowEvents['edgeUpdate']) =>
(elements.value = updateEdge(edge, connection, elements.value))
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
</script>
<template>
<Flow
:elements="elements"
:snap-to-grid="true"
:connection-mode="ConnectionMode.Loose"
@load="onLoad"
@edge-update="onEdgeUpdate"
@connect="onConnect"
@edge-update-start="onEdgeUpdateStart"
@elements-remove="onElementsRemove"
@edge-update-end="onEdgeUpdateEnd"
>
<Controls />
</Flow>
</template>
<style>
.updatenode__controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 4;
font-size: 12px;
}
.updatenode__controls label {
display: block;
}
.updatenode__bglabel {
margin-top: 10px;
}
.updatenode__checkboxwrapper {
margin-top: 10px;
display: flex;
align-items: center;
}
</style>
@@ -0,0 +1,82 @@
<script lang="ts" setup>
import { CSSProperties } from 'vue'
import Flow, {
NodeType,
addEdge,
useZoomPanHelper,
Node,
Elements,
Connection,
Edge,
ElementId,
Position,
isEdge,
FlowInstance,
} from '@braks/vue-flow'
import CustomNode from '../../components/UpdateNodeInternalsCustomNode.vue'
const initialHandleCount = 1
const initialElements: Elements = [
{
id: '1',
type: 'custom',
data: { label: 'Node 1', handleCount: initialHandleCount, handlePosition: 0 },
position: { x: 250, y: 5 },
},
]
const buttonWrapperStyles: CSSProperties = { position: 'absolute', right: '10px', top: '10px', zIndex: 10 }
const nodeTypes: Record<string, NodeType> = {
custom: CustomNode as NodeType,
}
let id = 5
const getId = (): ElementId => `${id++}`
const elements = ref<Elements>(initialElements)
const flowInstance = ref<FlowInstance>()
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const { project } = useZoomPanHelper()
const onPaneClick = (evt: MouseEvent) =>
(elements.value = elements.value.concat({
id: getId(),
position: project({ x: evt.clientX, y: evt.clientY - 40 }),
data: { label: 'new node' },
targetPosition: Position.Left,
sourcePosition: Position.Right,
} as Node))
const toggleHandleCount = () =>
(elements.value = elements.value.map((el) => {
if (isEdge(el)) {
return el
}
return { ...el, data: { ...el.data, handleCount: el.data?.handleCount === 1 ? 2 : 1 } }
}))
const toggleHandlePosition = () =>
(elements.value = elements.value.map((el) => {
if (isEdge(el)) return el
return { ...el, data: { ...el.data, handlePosition: el.data?.handlePosition === 0 ? 1 : 0 } }
}))
const onLoad = (instance: FlowInstance) => {
instance.fitView()
flowInstance.value = instance
}
const updateNodeInternals = () => flowInstance.value?.updateNodeInternals('1')
</script>
<template>
<Flow :elements="elements" :node-types="nodeTypes" @connect="onConnect" @pane-click="onPaneClick" @load="onLoad">
<div :style="buttonWrapperStyles">
<button class="button" @click="toggleHandleCount">toggle handle count</button>
<button class="button" @click="toggleHandlePosition">toggle handle position</button>
<button class="button" @click="updateNodeInternals">update node internals</button>
</div>
</Flow>
</template>
+73
View File
@@ -0,0 +1,73 @@
<script lang="ts" setup>
import Flow, { Elements } from '@braks/vue-flow'
const initialElements: Elements = [
{ id: '1', data: { label: '-' }, position: { x: 100, y: 100 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 200 } },
{ id: 'e1-2', source: '1', target: '2' },
]
const elements = ref<Elements>(initialElements)
const nodeName = ref<string>('Node 1')
const nodeBg = ref<string>('#eee')
const nodeHidden = ref<boolean>(false)
const updateNode = () => {
elements.value = elements.value.map((el) => {
if (el.id === '1') {
// it's important that you create a new object here in order to notify react flow about the change
el.data = {
...el.data,
label: nodeName.value,
}
el.style = { backgroundColor: nodeBg.value }
el.isHidden = nodeHidden.value
}
return el
})
}
watchEffect(() => {
updateNode()
})
</script>
<template>
<Flow :elements="elements" :default-zoom="1.5" :min-zoom="0.2" :max-zoom="4">
<div class="updatenode__controls p-4 bg-gray-300 rounded-xl">
<label>label:</label>
<input v-model="nodeName" />
<label class="updatenode__bglabel">background:</label>
<input v-model="nodeBg" type="color" />
<div class="updatenode__checkboxwrapper">
<label>hidden:</label>
<input v-model="nodeHidden" type="checkbox" />
</div>
</div>
</Flow>
</template>
<style>
.updatenode__controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 4;
font-size: 12px;
}
.updatenode__controls label {
display: block;
}
.updatenode__bglabel {
margin-top: 10px;
}
.updatenode__checkboxwrapper {
margin-top: 10px;
display: flex;
align-items: center;
}
</style>
+83
View File
@@ -0,0 +1,83 @@
<script lang="ts" setup>
import Flow, {
addEdge,
Handle,
Connection,
Position,
Elements,
Edge,
OnConnectStartParams,
NodeProps,
FlowInstance,
NodeType,
} from '@braks/vue-flow'
import CustomInput from '../../components/ValidationCustomInput.vue'
import CustomNode from '../../components/ValidationCustomNode.vue'
const initialElements: Elements = [
{ id: '0', type: 'custominput', position: { x: 0, y: 150 } },
{ id: 'A', type: 'customnode', position: { x: 250, y: 0 } },
{ id: 'B', type: 'customnode', position: { x: 250, y: 150 } },
{ id: 'C', type: 'customnode', position: { x: 250, y: 300 } },
]
const onLoad = (reactFlowInstance: FlowInstance) => reactFlowInstance.fitView()
const onConnectStart = ({ nodeId, handleType }: OnConnectStartParams) => console.log('on connect start', { nodeId, handleType })
const onConnectStop = (event: MouseEvent) => console.log('on connect stop', event)
const onConnectEnd = (event: MouseEvent) => console.log('on connect end', event)
const elements = ref<Elements>(initialElements)
const onConnect = (params: Connection | Edge) => {
console.log('on connect', params)
elements.value = addEdge(params, elements.value)
}
const nodeTypes: Record<string, NodeType> = {
custominput: CustomInput as NodeType,
customnode: CustomNode as NodeType,
}
</script>
<template>
<Flow
:elements="elements"
:select-nodes-on-drag="false"
class="validationflow"
:node-types="nodeTypes"
@connect="onConnect"
@oad="onLoad"
@connect-start="onConnectStart"
@connect-stop="onConnectStop"
@connect-end="onConnectEnd"
/>
</template>
<style>
.validationflow .vue-flow__node {
width: 150px;
border-radius: 5px;
padding: 10px;
color: #555;
border: 1px solid #ddd;
text-align: center;
font-size: 12px;
}
.validationflow .vue-flow__node-customnode {
background: #e6e6e9;
border: 1px solid #ddd;
}
.vue-flow__node-custominput .vue-flow__handle {
background: #e6e6e9;
}
.validationflow .vue-flow__node-custominput {
background: #fff;
}
.validationflow .vue-flow__handle-connecting {
background: #ff6060;
}
.validationflow .vue-flow__handle-valid {
background: #55dd99;
}
</style>
+50
View File
@@ -0,0 +1,50 @@
<script lang="ts" setup>
import Flow, {
removeElements,
addEdge,
Background,
MiniMap,
useZoomPanHelper,
Elements,
ElementId,
Connection,
Edge,
Node,
} from '@braks/vue-flow'
const initialElements: Elements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, class: 'light' },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, class: 'light' },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, class: 'light' },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, class: 'light' },
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' },
]
let id = 5
const getId = (): ElementId => `${id++}`
const { project } = useZoomPanHelper()
const elements = ref(initialElements)
const onPaneClick = (evt: MouseEvent) => {
const projectedPosition = project({ x: evt.clientX, y: evt.clientY - 40 })
elements.value = elements.value.concat({
id: getId(),
position: projectedPosition,
data: {
label: `${projectedPosition.x}-${projectedPosition.y}`,
},
} as Node)
}
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
</script>
<template>
<Flow :elements="elements" @elements-remove="onElementsRemove" @connect="onConnect" @pane-click="onPaneClick">
<Background />
<MiniMap />
</Flow>
</template>
+128 -99
View File
@@ -2,21 +2,21 @@ lockfileVersion: 5.3
specifiers:
'@braks/vue-flow': link:..
'@pinia/nuxt': ^0.0.9
add: ^2.0.6
'@types/dagre': ^0.7.46
dagre: ^0.8.5
localforage: ^1.10.0
nuxt-windicss: ^2.0.4
nuxt3: latest
pinia: ^2.0.0-rc.14
dependencies:
'@braks/vue-flow': link:..
'@pinia/nuxt': 0.0.9_pinia@2.0.0-rc.14
add: 2.0.6
pinia: 2.0.0-rc.14
dagre: 0.8.5
localforage: 1.10.0
devDependencies:
'@types/dagre': 0.7.46
nuxt-windicss: 2.0.4
nuxt3: 3.0.0-27248503.1e69bc5
nuxt3: 3.0.0-27249038.8f119ab
packages:
@@ -347,10 +347,12 @@ packages:
dependencies:
'@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0
dev: true
/@nodelib/fs.stat/2.0.5:
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
dev: true
/@nodelib/fs.walk/1.2.8:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
@@ -358,6 +360,7 @@ packages:
dependencies:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.13.0
dev: true
/@nuxt/design/0.1.4:
resolution: {integrity: sha512-wOoN69vUcKGuoUS5p5EqX6VPY+9QD9zhNfLLnlkiooxKsEIaSsiUCmuc+itKR5rKzCKGdLuxyiH5Ug7C1htQQg==}
@@ -380,8 +383,8 @@ packages:
webpack: 5.59.1
dev: true
/@nuxt/kit-edge/3.0.0-27248503.1e69bc5:
resolution: {integrity: sha512-Xvrji75bQeG6mU8JepBpQpxRFP/qudNTiNAxU7n8/4r4oEaQOcwHsMlz0zBWlpKIIi1/zuGiL/LvVc0YPc83dQ==}
/@nuxt/kit-edge/3.0.0-27249038.8f119ab:
resolution: {integrity: sha512-MLjphaZd+GuNfecC1lf+6gO4Qo5DaWeMkkW9VUBY7KP/uA2t5MLn+wZ3kkhxP9luGt1DXNzk3NMlAS5M+XXMoQ==}
engines: {node: ^14.16.0 || ^16.11.0}
dependencies:
consola: 2.15.3
@@ -403,21 +406,17 @@ packages:
ufo: 0.7.9
unctx: 1.0.2
untyped: 0.2.9
dev: true
/@nuxt/nitro-edge/3.0.0-27248503.1e69bc5_vue@3.2.20:
resolution: {integrity: sha512-Rkri3P7gXzZFjVTW6knS2Fr8sI/IuNz8NH7qRiMqq1iwG3YaryOgMWVbYDfQ57Ial/CmCTkpPyMm9JQzEjX8tg==}
/@nuxt/nitro-edge/3.0.0-27249038.8f119ab:
resolution: {integrity: sha512-7/0VuLeWNju3Fieff0jsNsLOAk069JPbhDZzDWq1HFOujtLUfP3AHD3QAFnqeoBNWF763CfmQbnM0oontcvGIg==}
engines: {node: ^14.16.0 || ^16.11.0}
peerDependencies:
vue: 3.2.20
peerDependenciesMeta:
vue:
optional: true
dependencies:
'@cloudflare/kv-asset-handler': 0.1.3
'@netlify/functions': 0.7.2
'@nuxt/design': 0.1.4
'@nuxt/devalue': 2.0.0
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27248503.1e69bc5
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27249038.8f119ab
'@rollup/plugin-alias': 3.1.8_rollup@2.58.0
'@rollup/plugin-commonjs': 21.0.1_rollup@2.58.0
'@rollup/plugin-inject': 4.0.3_rollup@2.58.0
@@ -452,7 +451,7 @@ packages:
mime: 2.5.2
mlly: 0.3.1
node-fetch: 3.0.0
ohmyfetch: 0.3.2
ohmyfetch: 0.4.2
ora: 6.0.1
p-debounce: 4.0.0
pathe: 0.2.0
@@ -465,9 +464,8 @@ packages:
std-env: 2.3.1
table: 6.7.2
ufo: 0.7.9
unenv: 0.3.10
unstorage: 0.2.9
vue: 3.2.20
unenv: 0.4.0
unstorage: 0.3.0
vue-bundle-renderer: 0.3.2
vue-server-renderer: 2.6.14
transitivePeerDependencies:
@@ -477,13 +475,13 @@ packages:
- utf-8-validate
dev: true
/@nuxt/vite-builder-edge/3.0.0-27248503.1e69bc5_vue@3.2.20:
resolution: {integrity: sha512-B+dvI1H1ltJO7pDmTqHWiK914G61VTrwgUC1fnyoZjz792hVdDJUY0igTTtDQHWbwPdneCS+BOLbVhc1MdqB/g==}
/@nuxt/vite-builder-edge/3.0.0-27249038.8f119ab_vue@3.2.20:
resolution: {integrity: sha512-zExaNWeV1YjFvQv5u9MVsQV5reGCwNxSV40/hgEZO7qjNrTXP3RwTqChUwuJU4oIeZPt/rnnDFlSf8aURBXi7A==}
engines: {node: ^14.16.0 || ^16.11.0}
peerDependencies:
vue: 3.2.20
dependencies:
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27248503.1e69bc5
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27249038.8f119ab
'@vitejs/plugin-vue': 1.9.3_vite@2.6.10
'@vitejs/plugin-vue-jsx': 1.2.0
autoprefixer: 10.3.7
@@ -512,15 +510,15 @@ packages:
- supports-color
dev: true
/@nuxt/webpack-builder-edge/3.0.0-27248503.1e69bc5_vue@3.2.20:
resolution: {integrity: sha512-UVF9Cj7Lr2+o57LVv90sgt/4tXY3Uae3L+2lW/dojI/VCB94zdiJFeZetdSGX/xheMgLl6SwUBirz5nJ1qzKIg==}
/@nuxt/webpack-builder-edge/3.0.0-27249038.8f119ab_vue@3.2.20:
resolution: {integrity: sha512-HTz/ZFgA5eHTkiD2ADTxe3xWNrC3fLzLBEteIyN2H9WmDo0NUXsNxzyzQWr1ERRNzKX+28z66x8SwdIJhVFCnw==}
engines: {node: ^14.16.0 || ^16.11.0}
peerDependencies:
vue: 3.2.20
dependencies:
'@babel/core': 7.15.8
'@nuxt/friendly-errors-webpack-plugin': 2.5.2_webpack@5.59.1
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27248503.1e69bc5
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27249038.8f119ab
'@vue/babel-preset-jsx': 1.2.4_@babel+core@7.15.8
autoprefixer: 10.3.7_postcss@8.3.11
babel-loader: 8.2.3_c444cf13e6678c57cc8afd2aacdd011d
@@ -569,19 +567,6 @@ packages:
- webpack-cli
dev: true
/@pinia/nuxt/0.0.9_pinia@2.0.0-rc.14:
resolution: {integrity: sha512-cs/ut+sABrfXUmHo5Va7fSrPA2ySvKzs25JOfKW1+6eGheFNng45s4IwGmSp48dNczHuW3upYcOwe4mEuJBWhA==}
peerDependencies:
pinia: ^2.0.0-0
dependencies:
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27248503.1e69bc5
pinia: 2.0.0-rc.14
vue-demi: 0.11.4
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@polka/url/1.0.0-next.21:
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
dev: true
@@ -699,6 +684,10 @@ packages:
engines: {node: '>=10.13.0'}
dev: true
/@types/dagre/0.7.46:
resolution: {integrity: sha512-ku3y+F8sPqmiB5Ugl22NpukI2dLAViJiWwdtueXLeuF4fxZozl+bytPSFVlLu/gDgaKiwobu3LBXXRWktIMiIA==}
dev: true
/@types/eslint-scope/3.7.1:
resolution: {integrity: sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==}
dependencies:
@@ -961,6 +950,7 @@ packages:
/@vue/devtools-api/6.0.0-beta.19:
resolution: {integrity: sha512-ObzQhgkoVeoyKv+e8+tB/jQBL2smtk/NmC9OmFK8UqdDpoOdv/Kf9pyDWL+IFyM7qLD2C75rszJujvGSPSpGlw==}
dev: true
/@vue/reactivity/3.2.20:
resolution: {integrity: sha512-nSmoLojUTk+H8HNTAkrUduB4+yIUBK2HPihJo2uXVSH4Spry6oqN6lFzE5zpLK+F27Sja+UqR9R1+/kIOsHV5w==}
@@ -1205,10 +1195,6 @@ packages:
hasBin: true
dev: true
/add/2.0.6:
resolution: {integrity: sha1-JI8Kn25aUo7yKV2+7DBTITCuIjU=}
dev: false
/agent-base/6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
@@ -1371,6 +1357,7 @@ packages:
/array-union/2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
dev: true
/astral-regex/2.0.0:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
@@ -1487,6 +1474,7 @@ packages:
engines: {node: '>=8'}
dependencies:
fill-range: 7.0.1
dev: true
/browserslist/4.17.4:
resolution: {integrity: sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==}
@@ -1655,6 +1643,7 @@ packages:
/ci-info/3.2.0:
resolution: {integrity: sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==}
dev: true
/cli-cursor/4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
@@ -1777,6 +1766,7 @@ packages:
/consola/2.15.3:
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
dev: true
/console-control-strings/1.1.0:
resolution: {integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=}
@@ -1822,6 +1812,7 @@ packages:
/create-require/1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
dev: true
/cross-spawn/6.0.5:
resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==}
@@ -1995,6 +1986,13 @@ packages:
resolution: {integrity: sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=}
dev: true
/dagre/0.8.5:
resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==}
dependencies:
graphlib: 2.1.8
lodash: 4.17.21
dev: false
/data-uri-to-buffer/3.0.1:
resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==}
engines: {node: '>= 6'}
@@ -2060,9 +2058,11 @@ packages:
/defu/2.0.4:
resolution: {integrity: sha512-G9pEH1UUMxShy6syWk01VQSRVs3CDWtlxtZu7A+NyqjxaCA4gSlWAKDBx6QiUEKezqS8+DUlXLI14Fp05Hmpwg==}
dev: true
/defu/5.0.0:
resolution: {integrity: sha512-VHg73EDeRXlu7oYWRmmrNp/nl7QkdXUxkQQKig0Zk8daNmm84AbGoC8Be6/VVLJEKxn12hR0UBmz8O+xQiAPKQ==}
dev: true
/delegates/1.0.0:
resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=}
@@ -2080,6 +2080,7 @@ packages:
/destr/1.1.0:
resolution: {integrity: sha512-Ev/sqS5AzzDwlpor/5wFCDu0dYMQu/0x2D6XfAsQ0E7uQmamIgYJ6Dppo2T2EOFVkeVYWjc+PCLKaqZZ57qmLg==}
dev: true
/destroy/1.0.4:
resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=}
@@ -2096,6 +2097,7 @@ packages:
engines: {node: '>=8'}
dependencies:
path-type: 4.0.0
dev: true
/dom-serializer/1.3.2:
resolution: {integrity: sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==}
@@ -2134,6 +2136,7 @@ packages:
/dotenv/10.0.0:
resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==}
engines: {node: '>=10'}
dev: true
/duplexer/0.1.2:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
@@ -2526,6 +2529,7 @@ packages:
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.4
dev: true
/fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
@@ -2535,6 +2539,7 @@ packages:
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
dependencies:
reusify: 1.0.4
dev: true
/fetch-blob/3.1.2:
resolution: {integrity: sha512-hunJbvy/6OLjCD0uuhLdp0mMPzP/yd2ssd1t2FCJsaA7wkWhpbp9xfuNVpv7Ll4jFhzp6T4LAupSiV9uOeg0VQ==}
@@ -2570,6 +2575,7 @@ packages:
engines: {node: '>=8'}
dependencies:
to-regex-range: 5.0.1
dev: true
/finalhandler/1.1.2:
resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
@@ -2604,6 +2610,7 @@ packages:
/flat/5.0.2:
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
hasBin: true
dev: true
/follow-redirects/1.14.4:
resolution: {integrity: sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==}
@@ -2750,6 +2757,7 @@ packages:
engines: {node: '>= 6'}
dependencies:
is-glob: 4.0.3
dev: true
/glob-to-regexp/0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
@@ -2781,11 +2789,18 @@ packages:
ignore: 5.1.8
merge2: 1.4.1
slash: 3.0.0
dev: true
/graceful-fs/4.2.8:
resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
dev: true
/graphlib/2.1.8:
resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==}
dependencies:
lodash: 4.17.21
dev: false
/gzip-size/6.0.0:
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
engines: {node: '>=10'}
@@ -2793,10 +2808,6 @@ packages:
duplexer: 0.1.2
dev: true
/h3/0.2.12:
resolution: {integrity: sha512-M3Ot1J5emIyafibkzGtqlZMQimTf3OMgSR2tv3TSbOHlssEktp3HlzuzWGvRCaX7XhpbmgDjgYpOC/ml9h5xug==}
dev: true
/h3/0.3.3:
resolution: {integrity: sha512-ammvVddtZArv6pnCkl0tEekY8owWPZNZCW4teePYzGwfN2w7kb0wnraLIFnB20mqUU2kCAV5bvI+2mjmGztS3w==}
dev: true
@@ -2851,6 +2862,7 @@ packages:
/hash-sum/2.0.0:
resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
dev: true
/hasha/5.2.2:
resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==}
@@ -2867,6 +2879,7 @@ packages:
/hookable/5.0.0:
resolution: {integrity: sha512-IqoJ8oXCNTUtNfqwbUQvLd+6ebVXk5qqGpSMOe4BS514vd4bEEH+hd9lva48mbbbe9q4eFKmsOViTZkr7ludHg==}
dev: true
/html-entities/2.3.2:
resolution: {integrity: sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==}
@@ -2957,6 +2970,11 @@ packages:
/ignore/5.1.8:
resolution: {integrity: sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==}
engines: {node: '>= 4'}
dev: true
/immediate/3.0.6:
resolution: {integrity: sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=}
dev: false
/import-fresh/3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
@@ -3074,6 +3092,7 @@ packages:
/is-extglob/2.1.1:
resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
engines: {node: '>=0.10.0'}
dev: true
/is-fullwidth-code-point/1.0.0:
resolution: {integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=}
@@ -3104,6 +3123,7 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
is-extglob: 2.1.1
dev: true
/is-interactive/2.0.0:
resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==}
@@ -3129,6 +3149,7 @@ packages:
/is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
dev: true
/is-obj/2.0.0:
resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
@@ -3248,6 +3269,7 @@ packages:
/jiti/1.12.9:
resolution: {integrity: sha512-TdcJywkQtcwLxogc4rSMAi479G2eDPzfW0fLySks7TPhgZZ4s/tM6stnzayIh3gS/db3zExWJyUx4cNWrwAmoQ==}
hasBin: true
dev: true
/joycon/3.0.1:
resolution: {integrity: sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==}
@@ -3297,6 +3319,7 @@ packages:
/jsonc-parser/3.0.0:
resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==}
dev: true
/jsonfile/6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
@@ -3318,6 +3341,12 @@ packages:
readable-stream: 2.3.7
dev: true
/lie/3.1.1:
resolution: {integrity: sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=}
dependencies:
immediate: 3.0.6
dev: false
/lilconfig/2.0.3:
resolution: {integrity: sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg==}
engines: {node: '>=10'}
@@ -3362,6 +3391,12 @@ packages:
json5: 2.2.0
dev: true
/localforage/1.10.0:
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
dependencies:
lie: 3.1.1
dev: false
/locate-path/5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@@ -3375,6 +3410,7 @@ packages:
/lodash._reinterpolate/3.0.0:
resolution: {integrity: sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=}
dev: true
/lodash.clonedeep/4.5.0:
resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=}
@@ -3413,11 +3449,13 @@ packages:
dependencies:
lodash._reinterpolate: 3.0.0
lodash.templatesettings: 4.2.0
dev: true
/lodash.templatesettings/4.2.0:
resolution: {integrity: sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==}
dependencies:
lodash._reinterpolate: 3.0.0
dev: true
/lodash.truncate/4.4.2:
resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=}
@@ -3433,7 +3471,6 @@ packages:
/lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true
/log-symbols/5.0.0:
resolution: {integrity: sha512-zBsSKauX7sM0kcqrf8VpMRPqcWzU6a/Wi7iEl0QlVSCiIZ4CctaLdfVdiZUn6q2/nenyt392qJqpw9FhNAwqxQ==}
@@ -3448,6 +3485,7 @@ packages:
engines: {node: '>=10'}
dependencies:
yallist: 4.0.0
dev: true
/magic-string/0.25.7:
resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==}
@@ -3488,6 +3526,7 @@ packages:
/merge2/1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
dev: true
/micromatch/4.0.4:
resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==}
@@ -3495,6 +3534,7 @@ packages:
dependencies:
braces: 3.0.2
picomatch: 2.3.0
dev: true
/mime-db/1.50.0:
resolution: {integrity: sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==}
@@ -3588,6 +3628,7 @@ packages:
/mlly/0.3.1:
resolution: {integrity: sha512-dtEsZue7NJy5Hhk6dsMoBjmJoZIZwyWvdN+X61cEtqjDFVRUskhWDBmn5EofDUWOkPrwur6GgpCRkXOAB4ISVw==}
dev: true
/mri/1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
@@ -3773,8 +3814,8 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/nuxi-edge/3.0.0-27248503.1e69bc5:
resolution: {integrity: sha512-v6wLaKdNXSMBvvqT4pXPjIE14T9rdES6R/O+Wp5wD2DRBVYZXyD4SqoVymh9rXdoMSmYoCmgxjKXAgF1rITidA==}
/nuxi-edge/3.0.0-27249038.8f119ab:
resolution: {integrity: sha512-tL9J/UeSEG0oMcdd2sTM5WJebRXNskeI20ejheXqguR03GZMZFAjd1ldk01nLACy/MYpFPy1ToMfNhMreFJ/8Q==}
engines: {node: ^14.16.0 || ^16.11.0}
hasBin: true
dependencies:
@@ -3786,7 +3827,7 @@ packages:
/nuxt-windicss/2.0.4:
resolution: {integrity: sha512-HCG5jKqvm8tKWfqTnzXvBlv0IuhUj+ONFLb9Qb6bDwvp07/di4JbBxFFtsM7aiyqw/JZLdbTMKPBZ10TT2Oinw==}
dependencies:
'@nuxt/kit-edge': 3.0.0-27248503.1e69bc5
'@nuxt/kit-edge': 3.0.0-27249038.8f119ab
defu: 5.0.0
h3: 0.3.3
listhen: 0.2.5
@@ -3802,16 +3843,16 @@ packages:
- vite
dev: true
/nuxt3/3.0.0-27248503.1e69bc5:
resolution: {integrity: sha512-xuWSUeavBXKpWG+8VcA8m9lO5EFYhZkikZxGGQBZWQQVVgtIWmDFKw/B+3TtSg70GfnfniF+8Kb8Prxlzhg3EQ==}
/nuxt3/3.0.0-27249038.8f119ab:
resolution: {integrity: sha512-6yaDrGb80kfE0/LlvPWTvAcUfEOkn+jGQl9DWvqd62lKDOUJVPjrd+OzHeom3DnK9jDGe5cGFpk9N10M6p9G2A==}
engines: {node: ^14.16.0 || ^16.11.0}
hasBin: true
dependencies:
'@nuxt/design': 0.1.4
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27248503.1e69bc5
'@nuxt/nitro': /@nuxt/nitro-edge/3.0.0-27248503.1e69bc5_vue@3.2.20
'@nuxt/vite-builder': /@nuxt/vite-builder-edge/3.0.0-27248503.1e69bc5_vue@3.2.20
'@nuxt/webpack-builder': /@nuxt/webpack-builder-edge/3.0.0-27248503.1e69bc5_vue@3.2.20
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27249038.8f119ab
'@nuxt/nitro': /@nuxt/nitro-edge/3.0.0-27249038.8f119ab
'@nuxt/vite-builder': /@nuxt/vite-builder-edge/3.0.0-27249038.8f119ab_vue@3.2.20
'@nuxt/webpack-builder': /@nuxt/webpack-builder-edge/3.0.0-27249038.8f119ab_vue@3.2.20
'@vue/reactivity': 3.2.20
'@vue/shared': 3.2.20
'@vueuse/head': 0.6.0_vue@3.2.20
@@ -3824,8 +3865,8 @@ packages:
ignore: 5.1.8
mlly: 0.3.1
murmurhash-es: 0.1.1
nuxi: /nuxi-edge/3.0.0-27248503.1e69bc5
ohmyfetch: 0.3.2
nuxi: /nuxi-edge/3.0.0-27249038.8f119ab
ohmyfetch: 0.4.2
pathe: 0.2.0
scule: 0.2.1
ufo: 0.7.9
@@ -3876,11 +3917,11 @@ packages:
object-keys: 1.1.1
dev: true
/ohmyfetch/0.3.2:
resolution: {integrity: sha512-AG+brJ3aPsFGLZV8V4TDCqRQNjNPIHg3KJxem8tYp4w1+4PEvLpib5zNaRNGnB+8Dqc4ftPLCzQYEsz30haX2A==}
/ohmyfetch/0.4.2:
resolution: {integrity: sha512-wlZ12IB4L8qvr7KBnA4MdqqoUovgfOKUJXoZMSwrTp54jTs20LENDoFXmyW0Qwg9fydrB/sT2qD8a/0iFehQOw==}
dependencies:
destr: 1.1.0
node-fetch: 2.6.5
node-fetch: 3.0.0
ufo: 0.7.9
dev: true
@@ -4053,9 +4094,11 @@ packages:
/path-type/4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
dev: true
/pathe/0.2.0:
resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
dev: true
/picocolors/0.2.1:
resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==}
@@ -4068,6 +4111,7 @@ packages:
/picomatch/2.3.0:
resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==}
engines: {node: '>=8.6'}
dev: true
/pify/2.3.0:
resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=}
@@ -4079,22 +4123,6 @@ packages:
engines: {node: '>=10'}
dev: true
/pinia/2.0.0-rc.14:
resolution: {integrity: sha512-vM8vYMsFdFDK1ND6j4+f7TC4hKB8moAjyn9HcHKqdOf1bHN4fL5g9Mz/8t8U0pEqnUwR2AU8yxD0gr+uU18x3g==}
peerDependencies:
'@vue/composition-api': ^1.2.4
typescript: ^4.4.3
vue: ^2.6.14 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
typescript:
optional: true
dependencies:
'@vue/devtools-api': 6.0.0-beta.19
vue-demi: 0.11.4
dev: false
/pkg-dir/4.2.0:
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
engines: {node: '>=8'}
@@ -4106,6 +4134,7 @@ packages:
resolution: {integrity: sha512-RlrGelHSS2yPeLT9NMuMIfpKS7+gRAhuXi+PexBeToKjbRkmu+E+HdgDY2ZKU1RDirk5w9WuViEhOufELtAnug==}
dependencies:
jsonc-parser: 3.0.0
dev: true
/postcss-calc/8.0.0_postcss@8.3.11:
resolution: {integrity: sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==}
@@ -4579,6 +4608,7 @@ packages:
/queue-microtask/1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: true
/randombytes/2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
@@ -4607,6 +4637,7 @@ packages:
defu: 2.0.4
destr: 1.1.0
flat: 5.0.2
dev: true
/read-cache/1.0.0:
resolution: {integrity: sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=}
@@ -4706,6 +4737,7 @@ packages:
/reusify/1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: true
/rimraf/2.7.1:
resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
@@ -4778,6 +4810,7 @@ packages:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
queue-microtask: 1.2.3
dev: true
/safe-buffer/5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
@@ -4815,6 +4848,7 @@ packages:
/scule/0.2.1:
resolution: {integrity: sha512-M9gnWtn3J0W+UhJOHmBxBTwv8mZCan5i1Himp60t6vvZcor0wr+IM0URKmIglsWJ7bRujNAVVN77fp+uZaWoKg==}
dev: true
/selfsigned/1.10.11:
resolution: {integrity: sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==}
@@ -4838,6 +4872,7 @@ packages:
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
/send/0.17.1:
resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==}
@@ -4936,6 +4971,7 @@ packages:
/slash/3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
dev: true
/slice-ansi/4.0.0:
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
@@ -5007,6 +5043,7 @@ packages:
resolution: {integrity: sha512-eOsoKTWnr6C8aWrqJJ2KAReXoa7Vn5Ywyw6uCXgA/xDhxPoaIsBa5aNJmISY04dLwXPBnDHW4diGM7Sn5K4R/g==}
dependencies:
ci-info: 3.2.0
dev: true
/string-width/1.0.2:
resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=}
@@ -5284,6 +5321,7 @@ packages:
engines: {node: '>=8.0'}
dependencies:
is-number: 7.0.0
dev: true
/toidentifier/1.0.0:
resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==}
@@ -5320,6 +5358,7 @@ packages:
/ufo/0.7.9:
resolution: {integrity: sha512-6t9LrLk3FhqTS+GW3IqlITtfRB5JAVr5MMNjpBECfK827W+Vh5Ilw/LhTcHWrt6b3hkeBvcbjx4Ti7QVFzmcww==}
dev: true
/unbox-primitive/1.0.1:
resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==}
@@ -5332,16 +5371,17 @@ packages:
/unctx/1.0.2:
resolution: {integrity: sha512-qxRfnQZWJqkg180JeOCJEvtjj5/7wnWVqkNHln8muY5/z8kMWBFqikFBPwIPCQrZJ+jtaSWkVHJkuHUAXls6zw==}
dev: true
/unenv/0.3.10:
resolution: {integrity: sha512-IOIXMXBOZ2GCfo/rODEZt75aZ2QSmLfxURzufil3/K4G5+xWpxRLxYq9hxy5uo+Y/PLaMtPhnOtI/vAB7EbYlw==}
/unenv/0.4.0:
resolution: {integrity: sha512-/UwjnsUae/nW3x1zV9AKXHRWBsqPsrEcSz1eEroGkhOpnTGsZ1krOGn8lykmw1L9tAOdW4ENOVsR38cS6BW0LA==}
dependencies:
buffer: 6.0.3
defu: 5.0.0
events: 3.3.0
inherits: 2.0.4
mime: 2.5.2
node-fetch: 2.6.5
node-fetch: 3.0.0
process: 0.11.10
upath: 2.0.1
util: 0.12.4
@@ -5378,17 +5418,17 @@ packages:
webpack-virtual-modules: 0.4.3
dev: true
/unstorage/0.2.9:
resolution: {integrity: sha512-HU9e8o2qI/3iS0QS+Fkp7Uo24kbIv+mnG5/csw0DF7g+st9U4EhVGh3BjVdhuybvRWfySU77HLecRClaosMErw==}
/unstorage/0.3.0:
resolution: {integrity: sha512-pPO3Hm0SD6zvgpJZMGsmv7y/EV0djbGamDZBBM2tewxFTyn628QHThW4u8ay/O21QQBomCs7OWSQ92UMW0fyGQ==}
dependencies:
anymatch: 3.1.2
chokidar: 3.5.2
destr: 1.1.0
h3: 0.2.12
h3: 0.3.3
ioredis: 4.28.0
listhen: 0.2.5
mri: 1.2.0
ohmyfetch: 0.3.2
ohmyfetch: 0.4.2
ufo: 0.7.9
ws: 8.2.3
transitivePeerDependencies:
@@ -5399,6 +5439,7 @@ packages:
/untyped/0.2.9:
resolution: {integrity: sha512-8d8V+q/y5CGzV+IYnoOCMjrK+NSNp1HKO8iPQ+bV4rBP8knPIme3+j/bpej8IuMnEMxOJZNptXNOXCx7w+VJxQ==}
dev: true
/upath/2.0.1:
resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==}
@@ -5495,19 +5536,6 @@ packages:
bundle-runner: 0.0.1
dev: true
/vue-demi/0.11.4:
resolution: {integrity: sha512-/3xFwzSykLW2HiiLie43a+FFgNOcokbBJ+fzvFXd0r2T8MYohqvphUyDQ8lbAwzQ3Dlcrb1c9ykifGkhSIAk6A==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
dev: false
/vue-loader/16.8.1_webpack@5.59.1:
resolution: {integrity: sha512-V53TJbHmzjBhCG5OYI2JWy/aYDspz4oVHKxS43Iy212GjGIG1T3EsB3+GWXFm/1z5VwjdjLmdZUFYM70y77vtQ==}
peerDependencies:
@@ -5831,6 +5859,7 @@ packages:
/yallist/4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
/yaml/1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
+3
View File
@@ -1,3 +1,6 @@
{
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true
}
}
+2 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@braks/vue-flow",
"version": "0.1.2",
"version": "0.0.0",
"private": false,
"repository": {
"type": "git",
@@ -45,14 +45,11 @@
"devDependencies": {
"@antfu/eslint-config": "^0.9.0",
"@rollup/plugin-replace": "^2.4.2",
"@types/dagre": "^0.7.46",
"@vitejs/plugin-vue": "^1.9.3",
"autoprefixer": "^10.3.7",
"dagre": "^0.8.5",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.1",
"localforage": "^1.10.0",
"np": "^7.5.0",
"pnpm": "^6.18.0",
"postcss-nested": "^5.0.6",
@@ -73,7 +70,7 @@
},
"np": {
"branch": "master",
"yarn": true,
"yarn": false,
"message": "v%s"
}
}
-161
View File
@@ -3,8 +3,6 @@ lockfileVersion: 5.3
specifiers:
'@antfu/eslint-config': ^0.9.0
'@braks/revue-draggable': 0.2.5
'@rollup/plugin-commonjs': ^19.0.2
'@rollup/plugin-node-resolve': ^13.0.6
'@rollup/plugin-replace': ^2.4.2
'@types/d3': ^7.1.0
'@types/dagre': ^0.7.46
@@ -14,7 +12,6 @@ specifiers:
d3: ^7.1.1
d3-selection: ^3.0.0
d3-zoom: ^3.0.0
dagre: ^0.8.5
eslint: ^7.32.0
eslint-config-prettier: ^8.3.0
eslint-plugin-prettier: ^3.4.1
@@ -25,13 +22,11 @@ specifiers:
pnpm: ^6.18.0
postcss-nested: ^5.0.6
prettier: ^2.4.1
rollup-plugin-terser: ^7.0.2
typescript: ^4.4.4
unplugin-auto-import: ^0.4.12
vite: ^2.6.10
vite-svg-loader: ^2.2.0
vue: ^3.2.20
vue-dts-gen: ^0.3.0
vue-tsc: ^0.28.7
dependencies:
@@ -46,13 +41,10 @@ dependencies:
devDependencies:
'@antfu/eslint-config': 0.9.0_eslint@7.32.0+typescript@4.4.4
'@rollup/plugin-commonjs': 19.0.2
'@rollup/plugin-node-resolve': 13.0.6
'@rollup/plugin-replace': 2.4.2
'@types/dagre': 0.7.46
'@vitejs/plugin-vue': 1.9.3_vite@2.6.10
autoprefixer: 10.3.7
dagre: 0.8.5
eslint: 7.32.0
eslint-config-prettier: 8.3.0_eslint@7.32.0
eslint-plugin-prettier: 3.4.1_6e975bd57c7acf028c1a9ddbbf60c898
@@ -61,13 +53,11 @@ devDependencies:
pnpm: 6.18.0
postcss-nested: 5.0.6
prettier: 2.4.1
rollup-plugin-terser: 7.0.2
typescript: 4.4.4
unplugin-auto-import: 0.4.12_@vueuse+core@6.6.2+vite@2.6.10
vite: 2.6.10
vite-svg-loader: 2.2.0
vue: 3.2.20
vue-dts-gen: 0.3.0
vue-tsc: 0.28.7_typescript@4.4.4
packages:
@@ -483,35 +473,6 @@ packages:
fastq: 1.13.0
dev: true
/@rollup/plugin-commonjs/19.0.2:
resolution: {integrity: sha512-gBjarfqlC7qs0AutpRW/hrFNm+cd2/QKxhwyFa+srbg1oX7rDsEU3l+W7LAUhsAp9mPJMAkXDhLbQaVwEaE8bA==}
engines: {node: '>= 8.0.0'}
peerDependencies:
rollup: ^2.38.3
dependencies:
'@rollup/pluginutils': 3.1.0
commondir: 1.0.1
estree-walker: 2.0.2
glob: 7.2.0
is-reference: 1.2.1
magic-string: 0.25.7
resolve: 1.20.0
dev: true
/@rollup/plugin-node-resolve/13.0.6:
resolution: {integrity: sha512-sFsPDMPd4gMqnh2gS0uIxELnoRUp5kBl5knxD2EO0778G1oOJv4G1vyT2cpWz75OU2jDVcXhjVUuTAczGyFNKA==}
engines: {node: '>= 10.0.0'}
peerDependencies:
rollup: ^2.42.0
dependencies:
'@rollup/pluginutils': 3.1.0
'@types/resolve': 1.17.1
builtin-modules: 3.2.0
deepmerge: 4.2.2
is-module: 1.0.0
resolve: 1.20.0
dev: true
/@rollup/plugin-replace/2.4.2:
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
peerDependencies:
@@ -786,10 +747,6 @@ packages:
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
dev: true
/@types/estree/0.0.50:
resolution: {integrity: sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==}
dev: true
/@types/geojson/7946.0.8:
resolution: {integrity: sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==}
dev: false
@@ -828,12 +785,6 @@ packages:
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
dev: true
/@types/resolve/1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
dependencies:
'@types/node': 16.11.1
dev: true
/@types/responselike/1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
dependencies:
@@ -1399,10 +1350,6 @@ packages:
picocolors: 1.0.0
dev: true
/buffer-from/1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/builtin-modules/3.2.0:
resolution: {integrity: sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==}
engines: {node: '>=6'}
@@ -1418,11 +1365,6 @@ packages:
semver: 7.3.5
dev: true
/cac/6.7.11:
resolution: {integrity: sha512-m4xrA2MKfid6uDV2j2+0mXrtPGxlvAW0y+7Gnn2P8WVMSG+4e4tcoYX++94ZPblPfpBccJ5e7HvKdghlX5yiDA==}
engines: {node: '>=8'}
dev: true
/cacheable-lookup/2.0.1:
resolution: {integrity: sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==}
engines: {node: '>=10'}
@@ -1618,18 +1560,10 @@ packages:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: true
/commander/2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
dev: true
/commander/7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
/commondir/1.0.1:
resolution: {integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=}
dev: true
/concat-map/0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
dev: true
@@ -1972,13 +1906,6 @@ packages:
d3-zoom: 3.0.0
dev: false
/dagre/0.8.5:
resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==}
dependencies:
graphlib: 2.1.8
lodash: 4.17.21
dev: true
/date-fns/1.30.1:
resolution: {integrity: sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==}
dev: true
@@ -2043,11 +1970,6 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
/deepmerge/4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
dev: true
/defer-to-connect/1.1.3:
resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==}
dev: true
@@ -3092,12 +3014,6 @@ packages:
resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
dev: true
/graphlib/2.1.8:
resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==}
dependencies:
lodash: 4.17.21
dev: true
/hard-rejection/2.1.0:
resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
engines: {node: '>=6'}
@@ -3458,10 +3374,6 @@ packages:
engines: {node: '>=8'}
dev: true
/is-module/1.0.0:
resolution: {integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=}
dev: true
/is-negative-zero/2.0.1:
resolution: {integrity: sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==}
engines: {node: '>= 0.4'}
@@ -3515,12 +3427,6 @@ packages:
resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==}
dev: true
/is-reference/1.2.1:
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
dependencies:
'@types/estree': 0.0.50
dev: true
/is-regex/1.1.4:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
@@ -3604,15 +3510,6 @@ packages:
engines: {node: '>=10'}
dev: true
/jest-worker/26.6.2:
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/node': 16.11.1
merge-stream: 2.0.0
supports-color: 7.2.0
dev: true
/js-stringify/1.0.2:
resolution: {integrity: sha1-Fzb939lyTyijaCrcYjCufk6Weds=}
dev: true
@@ -4758,12 +4655,6 @@ packages:
engines: {node: '>=8'}
dev: true
/randombytes/2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
safe-buffer: 5.2.1
dev: true
/rc/1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
@@ -4921,17 +4812,6 @@ packages:
resolution: {integrity: sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==}
dev: false
/rollup-plugin-terser/7.0.2:
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
peerDependencies:
rollup: ^2.0.0
dependencies:
'@babel/code-frame': 7.15.8
jest-worker: 26.6.2
serialize-javascript: 4.0.0
terser: 5.9.0
dev: true
/rollup/2.58.0:
resolution: {integrity: sha512-NOXpusKnaRpbS7ZVSzcEXqxcLDOagN6iFS8p45RkoiMqPHDLwJm758UF05KlMoCRbLBTZsPOIa887gZJ1AiXvw==}
engines: {node: '>=10.0.0'}
@@ -4966,10 +4846,6 @@ packages:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: true
/safe-buffer/5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: true
/safe-regex/2.1.1:
resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==}
dependencies:
@@ -5009,12 +4885,6 @@ packages:
lru-cache: 6.0.0
dev: true
/serialize-javascript/4.0.0:
resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==}
dependencies:
randombytes: 2.1.0
dev: true
/shebang-command/2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -5063,13 +4933,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/source-map-support/0.5.20:
resolution: {integrity: sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==}
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
/source-map/0.5.7:
resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=}
engines: {node: '>=0.10.0'}
@@ -5080,11 +4943,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/source-map/0.7.3:
resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==}
engines: {node: '>= 8'}
dev: true
/sourcemap-codec/1.4.8:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
dev: true
@@ -5304,16 +5162,6 @@ packages:
supports-hyperlinks: 2.2.0
dev: true
/terser/5.9.0:
resolution: {integrity: sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==}
engines: {node: '>=10'}
hasBin: true
dependencies:
commander: 2.20.3
source-map: 0.7.3
source-map-support: 0.5.20
dev: true
/text-table/0.2.0:
resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=}
dev: true
@@ -5725,15 +5573,6 @@ packages:
vue: 3.2.20
dev: false
/vue-dts-gen/0.3.0:
resolution: {integrity: sha512-PXSqyEfFgcqjuioFYbLQtTHZ2+UCCY94uzo98/cQE6Vun/8sjD1Bo22R5E1xag2v2+0/eUl+SuDzldJR3U1AHQ==}
hasBin: true
dependencies:
cac: 6.7.11
fast-glob: 3.2.7
resolve-from: 5.0.0
dev: true
/vue-eslint-parser/7.11.0_eslint@7.32.0:
resolution: {integrity: sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==}
engines: {node: '>=8.10'}
+1
View File
@@ -128,6 +128,7 @@ const edgePos = computed(() =>
inactive: !store.elementsSelectable,
updating,
},
props.edge.class,
]"
@click="onEdgeClick"
@contextmenu="onEdgeContextMenu"
+1
View File
@@ -162,6 +162,7 @@ watch(
selected: props.selected,
selectable: selectable,
},
props.node.class,
]"
:style="{
zIndex: props.selected ? 10 : 3,
+1 -4
View File
@@ -128,10 +128,7 @@ const init = (opts: typeof props) => {
onBeforeUnmount(() => store?.$dispose())
watch(
() => props,
(val) => init(val),
)
watch(props, (val) => init(val))
init(props)
const nodeTypes = controlledComputed(