feat: Enable passing components as node/edge-types
* Instead of using slots (re)-enable passing components for node/edge-types
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import ColorSelectorNode from './ColorSelectorNode.vue'
|
import ColorSelectorNode from './ColorSelectorNode.vue'
|
||||||
import { ConnectionMode, Elements, isEdge, Node, Position, SnapGrid, useVueFlow, VueFlow, Controls, MiniMap } from '~/index'
|
import { ConnectionMode, Controls, Elements, isEdge, MiniMap, Node, Position, SnapGrid, useVueFlow, VueFlow } from '~/index'
|
||||||
|
|
||||||
const elements = ref<Elements>([])
|
const elements = ref<Elements>([])
|
||||||
const bgColor = ref('#1A192B')
|
const bgColor = ref('#1A192B')
|
||||||
@@ -62,25 +62,23 @@ onMounted(() => {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const { onPaneReady } = useVueFlow()
|
const { onPaneReady } = useVueFlow({
|
||||||
onPaneReady((flowInstance) => {
|
connectionMode: ConnectionMode.Loose,
|
||||||
flowInstance.fitView()
|
connectionLineStyle,
|
||||||
console.log('flow loaded:', flowInstance)
|
snapToGrid: true,
|
||||||
|
snapGrid,
|
||||||
|
defaultZoom: 1.5,
|
||||||
|
nodeTypes: {
|
||||||
|
selectorNode: markRaw(ColorSelectorNode),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
onPaneReady((i) => {
|
||||||
|
i.fitView()
|
||||||
|
console.log('flow loaded:', i)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VueFlow
|
<VueFlow v-model="elements" :style="{ backgroundColor: bgColor }">
|
||||||
v-model="elements"
|
|
||||||
:style="{ backgroundColor: bgColor }"
|
|
||||||
:connection-mode="ConnectionMode.Loose"
|
|
||||||
:connection-line-style="connectionLineStyle"
|
|
||||||
:snap-to-grid="true"
|
|
||||||
:snap-grid="snapGrid"
|
|
||||||
:default-zoom="1.5"
|
|
||||||
>
|
|
||||||
<template #node-selectorNode="props">
|
|
||||||
<ColorSelectorNode v-bind="props" />
|
|
||||||
</template>
|
|
||||||
<MiniMap :node-stroke-color="nodeStroke" :node-color="nodeColor" />
|
<MiniMap :node-stroke-color="nodeStroke" :node-color="nodeColor" />
|
||||||
<Controls />
|
<Controls />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export default (
|
|||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
() => props.paneMovable,
|
() => props.paneMovable,
|
||||||
(v) => isDef(v) && (store.paneMoveable = v),
|
(v) => isDef(v) && (store.paneMovable = v),
|
||||||
{ immediate: isDef(props.paneMovable) },
|
{ immediate: isDef(props.paneMovable) },
|
||||||
)
|
)
|
||||||
watch(
|
watch(
|
||||||
@@ -206,5 +206,15 @@ export default (
|
|||||||
(v) => isDef(v) && (store.applyDefault = v),
|
(v) => isDef(v) && (store.applyDefault = v),
|
||||||
{ immediate: isDef(props.applyDefault) },
|
{ immediate: isDef(props.applyDefault) },
|
||||||
)
|
)
|
||||||
|
watch(
|
||||||
|
() => props.nodeTypes,
|
||||||
|
(v) => isDef(v) && (store.nodeTypes = v),
|
||||||
|
{ immediate: isDef(props.nodeTypes) },
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => props.edgeTypes,
|
||||||
|
(v) => isDef(v) && (store.edgeTypes = v),
|
||||||
|
{ immediate: isDef(props.edgeTypes) },
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ onMounted(async () => {
|
|||||||
const pinchZoom = store.zoomOnPinch && event.ctrlKey
|
const pinchZoom = store.zoomOnPinch && event.ctrlKey
|
||||||
|
|
||||||
// if all interactions are disabled, we prevent all zoom events
|
// if all interactions are disabled, we prevent all zoom events
|
||||||
if (!store.paneMoveable && !store.zoomOnScroll && !store.panOnScroll && !store.zoomOnDoubleClick && !store.zoomOnPinch)
|
if (!store.paneMovable && !store.zoomOnScroll && !store.panOnScroll && !store.zoomOnDoubleClick && !store.zoomOnPinch)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
// during a selection we prevent all other interactions
|
// during a selection we prevent all other interactions
|
||||||
@@ -148,7 +148,7 @@ onMounted(async () => {
|
|||||||
if (!store.zoomOnScroll && !store.panOnScroll && !pinchZoom && event.type === 'wheel') return false
|
if (!store.zoomOnScroll && !store.panOnScroll && !pinchZoom && event.type === 'wheel') return false
|
||||||
|
|
||||||
// if the pane is not movable, we prevent dragging it with mousestart or touchstart
|
// if the pane is not movable, we prevent dragging it with mousestart or touchstart
|
||||||
if (!store.paneMoveable && (event.type === 'mousedown' || event.type === 'touchstart')) return false
|
if (!store.paneMovable && (event.type === 'mousedown' || event.type === 'touchstart')) return false
|
||||||
|
|
||||||
// default filter for d3-zoom
|
// default filter for d3-zoom
|
||||||
return (!event.ctrlKey || event.type === 'wheel') && !event.button
|
return (!event.ctrlKey || event.type === 'wheel') && !event.button
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const setElements: Actions['setElements'] = (elements, extent) => {
|
const setElements: Actions['setElements'] = (elements, extent) => {
|
||||||
if (!state.initialized && !elements.length) return
|
if ((!state.initialized && !elements.length) || !elements) return
|
||||||
setNodes(elements.filter(isNode), extent)
|
setNodes(elements.filter(isNode), extent)
|
||||||
setEdges(elements.filter(isEdge))
|
setEdges(elements.filter(isEdge))
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
if (typeof opts.panOnScroll !== 'undefined') state.panOnScroll = opts.panOnScroll
|
if (typeof opts.panOnScroll !== 'undefined') state.panOnScroll = opts.panOnScroll
|
||||||
if (typeof opts.panOnScrollMode !== 'undefined') state.panOnScrollMode = opts.panOnScrollMode
|
if (typeof opts.panOnScrollMode !== 'undefined') state.panOnScrollMode = opts.panOnScrollMode
|
||||||
if (typeof opts.panOnScrollSpeed !== 'undefined') state.panOnScrollSpeed = opts.panOnScrollSpeed
|
if (typeof opts.panOnScrollSpeed !== 'undefined') state.panOnScrollSpeed = opts.panOnScrollSpeed
|
||||||
if (typeof opts.paneMovable !== 'undefined') state.paneMoveable = opts.paneMovable
|
if (typeof opts.paneMovable !== 'undefined') state.paneMovable = opts.paneMovable
|
||||||
if (typeof opts.zoomOnScroll !== 'undefined') state.zoomOnScroll = opts.zoomOnScroll
|
if (typeof opts.zoomOnScroll !== 'undefined') state.zoomOnScroll = opts.zoomOnScroll
|
||||||
if (typeof opts.preventScrolling !== 'undefined') state.preventScrolling = opts.preventScrolling
|
if (typeof opts.preventScrolling !== 'undefined') state.preventScrolling = opts.preventScrolling
|
||||||
if (typeof opts.zoomOnDoubleClick !== 'undefined') state.zoomOnDoubleClick = opts.zoomOnDoubleClick
|
if (typeof opts.zoomOnDoubleClick !== 'undefined') state.zoomOnDoubleClick = opts.zoomOnDoubleClick
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default (state: State): ComputedGetters => {
|
|||||||
const getEdgeTypes = computed(() => {
|
const getEdgeTypes = computed(() => {
|
||||||
const edgeTypes: Record<string, any> = {
|
const edgeTypes: Record<string, any> = {
|
||||||
...defaultEdgeTypes,
|
...defaultEdgeTypes,
|
||||||
|
...state.edgeTypes,
|
||||||
}
|
}
|
||||||
const keys = Object.keys(edgeTypes)
|
const keys = Object.keys(edgeTypes)
|
||||||
state.edges?.forEach((e) => e.type && !keys.includes(e.type) && (edgeTypes[e.type] = e.type))
|
state.edges?.forEach((e) => e.type && !keys.includes(e.type) && (edgeTypes[e.type] = e.type))
|
||||||
@@ -15,6 +16,7 @@ export default (state: State): ComputedGetters => {
|
|||||||
const getNodeTypes = computed(() => {
|
const getNodeTypes = computed(() => {
|
||||||
const nodeTypes: Record<string, any> = {
|
const nodeTypes: Record<string, any> = {
|
||||||
...defaultNodeTypes,
|
...defaultNodeTypes,
|
||||||
|
...state.nodeTypes,
|
||||||
}
|
}
|
||||||
const keys = Object.keys(nodeTypes)
|
const keys = Object.keys(nodeTypes)
|
||||||
state.nodes?.forEach((n) => n.type && !keys.includes(n.type) && (nodeTypes[n.type] = n.type))
|
state.nodes?.forEach((n) => n.type && !keys.includes(n.type) && (nodeTypes[n.type] = n.type))
|
||||||
|
|||||||
+4
-2
@@ -59,7 +59,7 @@ export default (opts?: FlowOptions): State => {
|
|||||||
panOnScroll: false,
|
panOnScroll: false,
|
||||||
panOnScrollSpeed: 0.5,
|
panOnScrollSpeed: 0.5,
|
||||||
panOnScrollMode: PanOnScrollMode.Free,
|
panOnScrollMode: PanOnScrollMode.Free,
|
||||||
paneMoveable: true,
|
paneMovable: true,
|
||||||
edgeUpdaterRadius: 10,
|
edgeUpdaterRadius: 10,
|
||||||
onlyRenderVisibleElements: false,
|
onlyRenderVisibleElements: false,
|
||||||
defaultZoom: 1,
|
defaultZoom: 1,
|
||||||
@@ -100,10 +100,12 @@ export default (opts?: FlowOptions): State => {
|
|||||||
} as State
|
} as State
|
||||||
|
|
||||||
if (opts) {
|
if (opts) {
|
||||||
|
if (typeof opts.nodeTypes !== 'undefined') state.nodeTypes = opts.nodeTypes
|
||||||
|
if (typeof opts.edgeTypes !== 'undefined') state.edgeTypes = opts.edgeTypes
|
||||||
if (typeof opts.panOnScroll !== 'undefined') state.panOnScroll = opts.panOnScroll
|
if (typeof opts.panOnScroll !== 'undefined') state.panOnScroll = opts.panOnScroll
|
||||||
if (typeof opts.panOnScrollMode !== 'undefined') state.panOnScrollMode = opts.panOnScrollMode
|
if (typeof opts.panOnScrollMode !== 'undefined') state.panOnScrollMode = opts.panOnScrollMode
|
||||||
if (typeof opts.panOnScrollSpeed !== 'undefined') state.panOnScrollSpeed = opts.panOnScrollSpeed
|
if (typeof opts.panOnScrollSpeed !== 'undefined') state.panOnScrollSpeed = opts.panOnScrollSpeed
|
||||||
if (typeof opts.paneMovable !== 'undefined') state.paneMoveable = opts.paneMovable
|
if (typeof opts.paneMovable !== 'undefined') state.paneMovable = opts.paneMovable
|
||||||
if (typeof opts.zoomOnScroll !== 'undefined') state.zoomOnScroll = opts.zoomOnScroll
|
if (typeof opts.zoomOnScroll !== 'undefined') state.zoomOnScroll = opts.zoomOnScroll
|
||||||
if (typeof opts.preventScrolling !== 'undefined') state.preventScrolling = opts.preventScrolling
|
if (typeof opts.preventScrolling !== 'undefined') state.preventScrolling = opts.preventScrolling
|
||||||
if (typeof opts.zoomOnDoubleClick !== 'undefined') state.zoomOnDoubleClick = opts.zoomOnDoubleClick
|
if (typeof opts.zoomOnDoubleClick !== 'undefined') state.zoomOnDoubleClick = opts.zoomOnDoubleClick
|
||||||
|
|||||||
+4
-1
@@ -5,6 +5,7 @@ import { ConnectionLineType, ConnectionMode } from './connection'
|
|||||||
import { KeyCode, PanOnScrollMode, UseZoomPanHelper } from './zoom'
|
import { KeyCode, PanOnScrollMode, UseZoomPanHelper } from './zoom'
|
||||||
import { Actions, ComputedGetters, State, FlowStore } from './store'
|
import { Actions, ComputedGetters, State, FlowStore } from './store'
|
||||||
import { FlowHooksOn } from './hooks'
|
import { FlowHooksOn } from './hooks'
|
||||||
|
import { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from "~/types/components";
|
||||||
|
|
||||||
export type FlowElement<N = any, E = any> = GraphNode<N> | GraphEdge<E>
|
export type FlowElement<N = any, E = any> = GraphNode<N> | GraphEdge<E>
|
||||||
export type FlowElements<N = any, E = any> = FlowElement<N, E>[]
|
export type FlowElements<N = any, E = any> = FlowElement<N, E>[]
|
||||||
@@ -83,11 +84,13 @@ export type FlowInstance<N = any, E = N> = {
|
|||||||
} & UseZoomPanHelper
|
} & UseZoomPanHelper
|
||||||
|
|
||||||
export interface FlowProps<N = any, E = N> {
|
export interface FlowProps<N = any, E = N> {
|
||||||
|
id?: string
|
||||||
/** @deprecated use nodes / edges instead */
|
/** @deprecated use nodes / edges instead */
|
||||||
modelValue?: Elements<N, E>
|
modelValue?: Elements<N, E>
|
||||||
nodes?: Node<N>[]
|
nodes?: Node<N>[]
|
||||||
edges?: Edge<E>[]
|
edges?: Edge<E>[]
|
||||||
id?: string
|
edgeTypes?: { [key in keyof DefaultEdgeTypes]?: EdgeComponent } & { [key: string]: EdgeComponent }
|
||||||
|
nodeTypes?: { [key in keyof DefaultNodeTypes]?: NodeComponent } & { [key: string]: NodeComponent }
|
||||||
connectionMode?: ConnectionMode
|
connectionMode?: ConnectionMode
|
||||||
connectionLineType?: ConnectionLineType
|
connectionLineType?: ConnectionLineType
|
||||||
connectionLineStyle?: CSSProperties
|
connectionLineStyle?: CSSProperties
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
import { ComputedRef, CSSProperties, ToRefs } from 'vue'
|
import { ComputedRef, CSSProperties, ToRefs } from 'vue'
|
||||||
import { Dimensions, Elements, FlowElements, FlowInstance, FlowOptions, Rect, SnapGrid, Transform, XYPosition } from './flow'
|
import { Dimensions, Elements, FlowElements, FlowInstance, FlowOptions, Rect, SnapGrid, Transform, XYPosition } from './flow'
|
||||||
import { HandleType, EdgeComponent, NodeComponent } from './components'
|
import { HandleType, EdgeComponent, NodeComponent, DefaultNodeTypes, DefaultEdgeTypes } from './components'
|
||||||
import { Connection, ConnectionLineType, ConnectionMode, SetConnectionId } from './connection'
|
import { Connection, ConnectionLineType, ConnectionMode, SetConnectionId } from './connection'
|
||||||
import { Edge, GraphEdge } from './edge'
|
import { Edge, GraphEdge } from './edge'
|
||||||
import { GraphNode, CoordinateExtent, Node } from './node'
|
import { GraphNode, CoordinateExtent, Node } from './node'
|
||||||
@@ -54,7 +54,7 @@ export interface State<N = any, E = N> extends Omit<FlowOptions<N, E>, 'id' | 'm
|
|||||||
nodesConnectable: boolean
|
nodesConnectable: boolean
|
||||||
elementsSelectable: boolean
|
elementsSelectable: boolean
|
||||||
selectNodesOnDrag: boolean
|
selectNodesOnDrag: boolean
|
||||||
paneMoveable: boolean
|
paneMovable: boolean
|
||||||
zoomOnScroll: boolean
|
zoomOnScroll: boolean
|
||||||
zoomOnPinch: boolean
|
zoomOnPinch: boolean
|
||||||
panOnScroll: boolean
|
panOnScroll: boolean
|
||||||
@@ -95,8 +95,8 @@ export interface Actions<N = any, E = N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Getters<N = any, E = N> {
|
export interface Getters<N = any, E = N> {
|
||||||
getEdgeTypes: Record<string, EdgeComponent>
|
getEdgeTypes: Record<keyof DefaultEdgeTypes | string, EdgeComponent>
|
||||||
getNodeTypes: Record<string, NodeComponent>
|
getNodeTypes: Record<keyof DefaultNodeTypes | string, NodeComponent>
|
||||||
getNodes: GraphNode<N>[]
|
getNodes: GraphNode<N>[]
|
||||||
getEdges: GraphEdge<E>[]
|
getEdges: GraphEdge<E>[]
|
||||||
getNode: (id: string) => GraphNode<N> | undefined
|
getNode: (id: string) => GraphNode<N> | undefined
|
||||||
|
|||||||
Reference in New Issue
Block a user