feat(vue-flow): add autoConnect option
# What's changed? * auto-connect allows to easily enable the default add edge change handler (shown in the examples) * allow auto-connect to be a function that returns false when connection is cancelled or partial edge when it should be created
This commit is contained in:
@@ -36,6 +36,7 @@ const props = withDefaults(defineProps<FlowProps>(), {
|
||||
fitViewOnInit: undefined,
|
||||
connectOnClick: undefined,
|
||||
connectionLineStyle: undefined,
|
||||
autoConnect: undefined,
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Ref, ToRefs } from 'vue'
|
||||
import type { WatchPausableReturn } from '@vueuse/core'
|
||||
import type { FlowProps, GraphEdge, GraphNode, VueFlowStore } from '~/types'
|
||||
import { isFunction } from '@vueuse/core'
|
||||
import type { Connection, FlowProps, GraphEdge, GraphNode, VueFlowStore } from '~/types'
|
||||
|
||||
const isDef = <T>(val: T): val is NonNullable<T> => typeof val !== 'undefined'
|
||||
export default (models: ToRefs<Pick<FlowProps, 'nodes' | 'edges' | 'modelValue'>>, props: FlowProps, store: VueFlowStore) => {
|
||||
@@ -171,8 +172,45 @@ export default (models: ToRefs<Pick<FlowProps, 'nodes' | 'edges' | 'modelValue'>
|
||||
})
|
||||
}
|
||||
|
||||
const watchAutoConnect = () => {
|
||||
scope.run(() => {
|
||||
watch(
|
||||
() => props.autoConnect,
|
||||
() => {
|
||||
if (isDef(props.autoConnect)) {
|
||||
store.autoConnect.value = props.autoConnect
|
||||
}
|
||||
},
|
||||
{ immediate: isDef(props.autoConnect) },
|
||||
)
|
||||
|
||||
watch(
|
||||
store.autoConnect,
|
||||
() => {
|
||||
const autoConnector = async (params: Connection) => {
|
||||
let connect: boolean | Connection = true
|
||||
if (isFunction(props.autoConnect)) {
|
||||
connect = await props.autoConnect(params)
|
||||
}
|
||||
|
||||
if (connect) {
|
||||
store.addEdges([params])
|
||||
}
|
||||
}
|
||||
|
||||
if (store.autoConnect) {
|
||||
store.onConnect(autoConnector)
|
||||
} else {
|
||||
store.hooks.value.connect.off(autoConnector)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const watchRest = () => {
|
||||
const skip = ['id', 'modelValue', 'edges', 'nodes', 'maxZoom', 'minZoom', 'applyDefault']
|
||||
const skip = ['id', 'modelValue', 'edges', 'nodes', 'maxZoom', 'minZoom', 'applyDefault', 'autoConnect']
|
||||
Object.keys(props).forEach((prop) => {
|
||||
if (!skip.includes(prop)) {
|
||||
const model = props[prop as keyof typeof props]
|
||||
@@ -193,9 +231,16 @@ export default (models: ToRefs<Pick<FlowProps, 'nodes' | 'edges' | 'modelValue'>
|
||||
})
|
||||
}
|
||||
|
||||
;[watchModelValue, watchNodesValue, watchEdgesValue, watchMinZoom, watchMaxZoom, watchApplyDefault, watchRest].forEach(
|
||||
(watch) => watch(),
|
||||
)
|
||||
;[
|
||||
watchModelValue,
|
||||
watchNodesValue,
|
||||
watchEdgesValue,
|
||||
watchMinZoom,
|
||||
watchMaxZoom,
|
||||
watchApplyDefault,
|
||||
watchAutoConnect,
|
||||
watchRest,
|
||||
].forEach((watch) => watch())
|
||||
})
|
||||
|
||||
return () => scope.stop()
|
||||
|
||||
@@ -101,6 +101,7 @@ const defaultState = (): State => ({
|
||||
hooks: createHooks(),
|
||||
|
||||
applyDefault: true,
|
||||
autoConnect: false,
|
||||
|
||||
fitViewOnInit: false,
|
||||
noDragClassName: 'nodrag',
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { CSSProperties } from 'vue'
|
||||
import type { Position } from './flow'
|
||||
import type { GraphNode } from './node'
|
||||
import type { HandleElement, HandleType } from './handle'
|
||||
import type { Edge } from './edge'
|
||||
|
||||
/** Connection line types (same as default edge types */
|
||||
export enum ConnectionLineType {
|
||||
@@ -23,6 +24,10 @@ export interface Connection {
|
||||
targetHandle: string | null
|
||||
}
|
||||
|
||||
export type Connector = (
|
||||
params: Connection,
|
||||
) => Promise<(Connection & Partial<Edge>) | false> | ((Connection & Partial<Edge>) | false)
|
||||
|
||||
/** The source nodes params when connection is initiated */
|
||||
export interface OnConnectStartParams {
|
||||
/** Source node id */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { CSSProperties } from 'vue'
|
||||
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
|
||||
import type { CoordinateExtent, GraphNode, Node } from './node'
|
||||
import type { ConnectionLineType, ConnectionMode } from './connection'
|
||||
import type { ConnectionLineType, ConnectionMode, Connector } from './connection'
|
||||
import type { KeyCode, PanOnScrollMode } from './zoom'
|
||||
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
|
||||
|
||||
@@ -122,6 +122,8 @@ export interface FlowProps {
|
||||
connectOnClick?: boolean
|
||||
/** apply default change handlers for position, dimensions, adding/removing nodes. set this to false if you want to apply the changes manually */
|
||||
applyDefault?: boolean
|
||||
/** automatically create an edge when connection is triggered */
|
||||
autoConnect?: boolean | Connector
|
||||
noDragClassName?: string
|
||||
noWheelClassName?: string
|
||||
noPanClassName?: string
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { CSSProperties, ComputedRef, ToRefs } from 'vue'
|
||||
import type { Dimensions, ElementData, Elements, FlowElements, FlowExportObject, FlowOptions, SnapGrid, XYPosition } from './flow'
|
||||
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
|
||||
import type { Connection, ConnectionLineType, ConnectionMode } from './connection'
|
||||
import type { Connection, ConnectionLineType, ConnectionMode, Connector } from './connection'
|
||||
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
|
||||
import type { CoordinateExtent, GraphNode, Node } from './node'
|
||||
import type { D3Selection, D3Zoom, D3ZoomHandler, KeyCode, PanOnScrollMode, Viewport, ViewportFunctions } from './zoom'
|
||||
@@ -88,6 +88,7 @@ export interface State extends Omit<FlowOptions, 'id' | 'modelValue'> {
|
||||
|
||||
initialized: boolean
|
||||
applyDefault: boolean
|
||||
autoConnect: boolean | Connector
|
||||
|
||||
fitViewOnInit?: boolean
|
||||
|
||||
|
||||
Reference in New Issue
Block a user