feat(core): add connection status to connection lines

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
braks
2023-02-05 21:59:04 +01:00
committed by Braks
parent c72e75db38
commit c36cf59a80
7 changed files with 46 additions and 19 deletions

View File

@@ -68,6 +68,7 @@ declare global {
const getBoundsofRects: typeof import('./utils/graph')['getBoundsofRects']
const getClosestHandle: typeof import('./utils/handle')['getClosestHandle']
const getConnectedEdges: typeof import('./utils/graph')['getConnectedEdges']
const getConnectionStatus: typeof import('./utils/handle')['getConnectionStatus']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const getDimensions: typeof import('./utils/graph')['getDimensions']

View File

@@ -1,7 +1,6 @@
<script lang="ts" setup>
import type { GraphNode } from '../../types'
import { ConnectionLineType, ConnectionMode, Position } from '../../types'
import { getMarkerId } from '../../utils/graph'
const { sourceNode } = defineProps<{ sourceNode: GraphNode }>()
@@ -12,6 +11,7 @@ const {
connectionLineType,
connectionLineStyle,
connectionLineOptions,
connectionStatus,
viewport,
} = $(useVueFlow())
@@ -86,25 +86,24 @@ export default {
<component
:is="slots"
v-if="hasSlot"
v-bind="{
sourceX,
sourceY,
sourcePosition: sourceHandle?.position,
targetX,
targetY,
targetPosition,
sourceNode,
sourceHandle,
markerEnd: `url(#${getMarkerId(connectionLineOptions.markerEnd)})`,
markerStart: `url(#${getMarkerId(connectionLineOptions.markerStart)})`,
}"
:source-x="sourceX"
:source-y="sourceY"
:source-position="sourceHandle?.position"
:targetX="targetX"
:targetY="targetY"
:target-position="targetPosition"
:source-node="sourceNode"
:source-handle="sourceHandle"
:marker-end="`url(#${getMarkerId(connectionLineOptions.markerEnd)})`"
:marker-start="`url(#${getMarkerId(connectionLineOptions.markerStart)})`"
:connection-status="connectionStatus"
/>
<path
v-else
:d="dAttr"
class="vue-flow__connection-path"
:class="connectionLineOptions.class"
:class="[connectionLineOptions.class, connectionStatus]"
:style="connectionLineStyle || connectionLineOptions.style || {}"
:marker-end="`url(#${getMarkerId(connectionLineOptions.markerEnd)})`"
:marker-start="`url(#${getMarkerId(connectionLineOptions.markerStart)})`"

View File

@@ -33,6 +33,7 @@ export default function useHandle({
connectionRadius,
connectOnClick,
connectionClickStartHandle,
connectionStatus,
nodesConnectable,
defaultEdgeOptions,
autoPanOnConnect,
@@ -113,6 +114,8 @@ export default function useHandle({
event,
)
connectionStatus.value = null
emits.connectStart({ event, nodeId, handleId, handleType })
function onPointerMove(event: MouseEvent | TouchEvent) {
@@ -154,6 +157,8 @@ export default function useHandle({
: connectionPosition,
)
connectionStatus.value = getConnectionStatus(!!prevClosestHandle, isValid)
if (!prevClosestHandle) return resetRecentHandle(prevActiveHandle)
connection = result.connection

View File

@@ -88,6 +88,7 @@ const defaultState = (): State => ({
connectionPosition: { x: NaN, y: NaN },
connectionRadius: 20,
connectOnClick: true,
connectionStatus: null,
snapGrid: [15, 15],
snapToGrid: false,

View File

@@ -37,6 +37,8 @@ export type Connector = (
params: Connection,
) => Promise<(Connection & Partial<Edge>) | false> | ((Connection & Partial<Edge>) | false)
export type ConnectionStatus = 'valid' | 'invalid'
/** The source nodes params when connection is initiated */
export interface OnConnectStartParams {
/** Source node id */
@@ -66,10 +68,6 @@ export interface ConnectionLineProps {
targetY: number
/** Target position of the connection line */
targetPosition: Position
/** the shape of the connection line when active */
connectionLineType: ConnectionLineType
/** extra styles */
connectionLineStyle: CSSProperties
/** The source node of the connection line */
sourceNode: GraphNode
/** The source handle element of the connection line */
@@ -78,4 +76,6 @@ export interface ConnectionLineProps {
markerStart: string
/** marker url */
markerEnd: string
/** status of the connection (valid, invalid) */
connectionStatus: ConnectionStatus
}

View File

@@ -14,7 +14,14 @@ import type {
XYPosition,
} from './flow'
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
import type { Connection, ConnectionLineOptions, ConnectionLineType, ConnectionMode, Connector } from './connection'
import type {
Connection,
ConnectionLineOptions,
ConnectionLineType,
ConnectionMode,
ConnectionStatus,
Connector,
} from './connection'
import type { DefaultEdgeOptions, Edge, EdgeUpdatable, GraphEdge } from './edge'
import type { CoordinateExtent, GraphNode, Node } from './node'
import type { D3Selection, D3Zoom, D3ZoomHandler, PanOnScrollMode, ViewportFunctions, ViewportTransform } from './zoom'
@@ -81,6 +88,7 @@ export interface State extends Omit<FlowOptions, 'id' | 'modelValue'> {
connectionClickStartHandle: StartHandle | null
connectionPosition: XYPosition
connectionRadius: number
connectionStatus: ConnectionStatus | null
connectOnClick: boolean
edgeUpdaterRadius: number

View File

@@ -2,6 +2,7 @@ import { ConnectionMode } from '~/types'
import type {
Actions,
Connection,
ConnectionStatus,
GraphEdge,
GraphNode,
HandleType,
@@ -160,3 +161,15 @@ export function getHandleType(edgeUpdaterType: HandleType | undefined, handleDom
return null
}
export function getConnectionStatus(isInsideConnectionRadius: boolean, isHandleValid: boolean) {
let connectionStatus: ConnectionStatus | null = null
if (isHandleValid) {
connectionStatus = 'valid'
} else if (isInsideConnectionRadius && !isHandleValid) {
connectionStatus = 'invalid'
}
return connectionStatus
}