refactor(nodes): use HandleConnectable type for nodes connectable prop

This commit is contained in:
braks
2022-10-10 21:33:44 +02:00
committed by Braks
parent 0215d49ad3
commit 283846c196
5 changed files with 36 additions and 34 deletions
+19 -22
View File
@@ -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 })
}
}
+2 -2
View File
@@ -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)),
}
}
+4 -1
View File
@@ -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
}
+4 -4
View File
@@ -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) */