refactor(nodes): use HandleConnectable type for nodes connectable prop
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { isString } from '@vueuse/core'
|
||||
import { isFunction, isString } from '@vueuse/core'
|
||||
import { useHandle, useNode, useVueFlow } from '../../composables'
|
||||
import type { Position } from '../../types'
|
||||
import { ConnectionMode } from '../../types'
|
||||
@@ -8,7 +8,7 @@ import { getDimensions } from '../../utils'
|
||||
|
||||
const { type = 'source', position = 'top' as Position, connectable = true, id, isValidConnection } = defineProps<HandleProps>()
|
||||
|
||||
const { connectionStartHandle, connectionMode, vueFlowRef } = $(useVueFlow())
|
||||
const { connectionStartHandle, connectionMode, vueFlowRef, nodesConnectable } = $(useVueFlow())
|
||||
|
||||
const { id: nodeId, node, nodeEl, connectedEdges } = useNode()
|
||||
|
||||
@@ -19,6 +19,8 @@ const handleId = $computed(() => id ?? (connectionMode === ConnectionMode.Strict
|
||||
const isConnectable = computed(() => {
|
||||
if (isString(connectable) && connectable === 'single') {
|
||||
return !connectedEdges.value.some((edge) => edge[type] === nodeId && edge[`${type}Handle`] === handleId)
|
||||
} else if (isFunction(connectable)) {
|
||||
return connectable(node, connectedEdges.value)
|
||||
}
|
||||
|
||||
return connectable
|
||||
@@ -34,25 +36,6 @@ const onClickHandler = (event: MouseEvent) => {
|
||||
onClick(event, handleId ?? null, nodeId, type, isValidConnection)
|
||||
}
|
||||
|
||||
const getClasses = computed(() => {
|
||||
return [
|
||||
'vue-flow__handle',
|
||||
`vue-flow__handle-${position}`,
|
||||
`vue-flow__handle-${handleId}`,
|
||||
'nodrag',
|
||||
{
|
||||
source: type !== 'target',
|
||||
target: type === 'target',
|
||||
connectable: isConnectable,
|
||||
connecting:
|
||||
connectionStartHandle &&
|
||||
connectionStartHandle.nodeId === nodeId &&
|
||||
connectionStartHandle.handleId === handleId &&
|
||||
connectionStartHandle.type === type,
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const existingBounds = node.handleBounds[type]?.find((b) => b.id === handleId)
|
||||
if (!vueFlowRef || existingBounds) return
|
||||
@@ -92,7 +75,21 @@ export default {
|
||||
:data-handleid="handleId"
|
||||
:data-nodeid="nodeId"
|
||||
:data-handlepos="position"
|
||||
:class="getClasses"
|
||||
class="vue-flow__handle nodrag"
|
||||
:class="[
|
||||
`vue-flow__handle-${position}`,
|
||||
`vue-flow__handle-${handleId}`,
|
||||
{
|
||||
source: type !== 'target',
|
||||
target: type === 'target',
|
||||
connectable: isConnectable,
|
||||
connecting:
|
||||
connectionStartHandle &&
|
||||
connectionStartHandle.nodeId === nodeId &&
|
||||
connectionStartHandle.handleId === handleId &&
|
||||
connectionStartHandle.type === type,
|
||||
},
|
||||
]"
|
||||
@mousedown="onMouseDownHandler"
|
||||
@click="onClickHandler"
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import { useDrag, useNodeHooks, useVueFlow } from '../../composables'
|
||||
import type { GraphNode, NodeComponent, SnapGrid, XYZPosition } from '../../types'
|
||||
import type { GraphNode, HandleConnectable, NodeComponent, SnapGrid, XYZPosition } from '../../types'
|
||||
import { NodeId, NodeRef } from '../../context'
|
||||
import { getConnectedEdges, getXYZPos, handleNodeClick } from '../../utils'
|
||||
|
||||
@@ -9,7 +9,7 @@ const { id, type, name, draggable, selectable, connectable, snapGrid, ...props }
|
||||
id: string
|
||||
draggable: boolean
|
||||
selectable: boolean
|
||||
connectable: boolean
|
||||
connectable: HandleConnectable
|
||||
snapGrid?: SnapGrid
|
||||
type: NodeComponent | Function | Object | false
|
||||
name: string
|
||||
@@ -39,6 +39,8 @@ const node = $(useVModel(props, 'node'))
|
||||
|
||||
const parentNode = $computed(() => (node.parentNode ? getNode(node.parentNode) : undefined))
|
||||
|
||||
const connectedEdges = $computed(() => getConnectedEdges([node], edges))
|
||||
|
||||
const nodeElement = ref()
|
||||
|
||||
provide(NodeRef, nodeElement)
|
||||
@@ -137,19 +139,19 @@ onBeforeUnmount(() => {
|
||||
|
||||
const onMouseEnter = (event: MouseEvent) => {
|
||||
if (!dragging?.value) {
|
||||
emit.mouseEnter({ event, node, connectedEdges: getConnectedEdges([node], edges) })
|
||||
emit.mouseEnter({ event, node, connectedEdges })
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseMove = (event: MouseEvent) => {
|
||||
if (!dragging?.value) {
|
||||
emit.mouseMove({ event, node, connectedEdges: getConnectedEdges([node], edges) })
|
||||
emit.mouseMove({ event, node, connectedEdges })
|
||||
}
|
||||
}
|
||||
|
||||
const onMouseLeave = (event: MouseEvent) => {
|
||||
if (!dragging?.value) {
|
||||
emit.mouseLeave({ event, node, connectedEdges: getConnectedEdges([node], edges) })
|
||||
emit.mouseLeave({ event, node, connectedEdges })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ export default function useNode<Data = ElementData, CustomEvents extends Record<
|
||||
|
||||
return {
|
||||
id: nodeId,
|
||||
node,
|
||||
nodeEl,
|
||||
parentNode: node.parentNode ? findNode(node.parentNode) : undefined,
|
||||
node,
|
||||
parentNode: computed(() => (node.parentNode ? findNode(node.parentNode) : undefined)),
|
||||
connectedEdges: computed(() => getConnectedEdges([node], getEdges.value)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ export type ValidConnectionFunc = (
|
||||
elements: { edges: GraphEdge[]; sourceNode: GraphNode; targetNode: GraphNode },
|
||||
) => boolean
|
||||
|
||||
/** set to true to allow unlimited connections, single for only one connection or use a cb function to determine connect-ability */
|
||||
export type HandleConnectable = boolean | 'single' | ((node: GraphNode, connectedEdges: GraphEdge[]) => boolean)
|
||||
|
||||
export interface HandleProps {
|
||||
/** Unique id of handle element */
|
||||
id?: string
|
||||
@@ -32,5 +35,5 @@ export interface HandleProps {
|
||||
/** A valid connection func {@link ValidConnectionFunc} */
|
||||
isValidConnection?: ValidConnectionFunc
|
||||
/** Enable/disable connecting to handle */
|
||||
connectable?: boolean | 'single'
|
||||
connectable?: HandleConnectable
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Component, VNode } from 'vue'
|
||||
import type { ClassFunc, Dimensions, ElementData, Position, SnapGrid, StyleFunc, Styles, XYPosition, XYZPosition } from './flow'
|
||||
import type { DefaultNodeTypes, NodeComponent } from './components'
|
||||
import type { HandleElement, ValidConnectionFunc } from './handle'
|
||||
import type { HandleConnectable, HandleElement, ValidConnectionFunc } from './handle'
|
||||
import type { CustomEvent, NodeEventsHandler, NodeEventsOn } from './hooks'
|
||||
|
||||
/** Defined as [[x-from, y-from], [x-to, y-to]] **/
|
||||
@@ -31,7 +31,7 @@ export interface Node<Data = ElementData, CustomEvents extends Record<string, Cu
|
||||
sourcePosition?: Position
|
||||
draggable?: boolean
|
||||
selectable?: boolean
|
||||
connectable?: boolean
|
||||
connectable?: HandleConnectable
|
||||
dragHandle?: string
|
||||
/** move on grid */
|
||||
snapGrid?: SnapGrid
|
||||
@@ -93,8 +93,8 @@ export interface NodeProps<Data = ElementData, CustomEvents = {}> {
|
||||
type: keyof DefaultNodeTypes | string
|
||||
/** is node selected */
|
||||
selected: boolean
|
||||
/** can node be connected */
|
||||
connectable: boolean
|
||||
/** can node handles be connected */
|
||||
connectable: HandleConnectable
|
||||
/** node x, y (relative) position on graph */
|
||||
position: XYPosition
|
||||
/** dom element dimensions (width, height) */
|
||||
|
||||
Reference in New Issue
Block a user