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 22:57:41 +01:00
committed by Braks
parent c72e75db38
commit c36cf59a80
7 changed files with 46 additions and 19 deletions
+1
View File
@@ -68,6 +68,7 @@ declare global {
const getBoundsofRects: typeof import('./utils/graph')['getBoundsofRects'] const getBoundsofRects: typeof import('./utils/graph')['getBoundsofRects']
const getClosestHandle: typeof import('./utils/handle')['getClosestHandle'] const getClosestHandle: typeof import('./utils/handle')['getClosestHandle']
const getConnectedEdges: typeof import('./utils/graph')['getConnectedEdges'] const getConnectedEdges: typeof import('./utils/graph')['getConnectedEdges']
const getConnectionStatus: typeof import('./utils/handle')['getConnectionStatus']
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope'] const getCurrentScope: typeof import('vue')['getCurrentScope']
const getDimensions: typeof import('./utils/graph')['getDimensions'] const getDimensions: typeof import('./utils/graph')['getDimensions']
@@ -1,7 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { GraphNode } from '../../types' import type { GraphNode } from '../../types'
import { ConnectionLineType, ConnectionMode, Position } from '../../types' import { ConnectionLineType, ConnectionMode, Position } from '../../types'
import { getMarkerId } from '../../utils/graph'
const { sourceNode } = defineProps<{ sourceNode: GraphNode }>() const { sourceNode } = defineProps<{ sourceNode: GraphNode }>()
@@ -12,6 +11,7 @@ const {
connectionLineType, connectionLineType,
connectionLineStyle, connectionLineStyle,
connectionLineOptions, connectionLineOptions,
connectionStatus,
viewport, viewport,
} = $(useVueFlow()) } = $(useVueFlow())
@@ -86,25 +86,24 @@ export default {
<component <component
:is="slots" :is="slots"
v-if="hasSlot" v-if="hasSlot"
v-bind="{ :source-x="sourceX"
sourceX, :source-y="sourceY"
sourceY, :source-position="sourceHandle?.position"
sourcePosition: sourceHandle?.position, :targetX="targetX"
targetX, :targetY="targetY"
targetY, :target-position="targetPosition"
targetPosition, :source-node="sourceNode"
sourceNode, :source-handle="sourceHandle"
sourceHandle, :marker-end="`url(#${getMarkerId(connectionLineOptions.markerEnd)})`"
markerEnd: `url(#${getMarkerId(connectionLineOptions.markerEnd)})`, :marker-start="`url(#${getMarkerId(connectionLineOptions.markerStart)})`"
markerStart: `url(#${getMarkerId(connectionLineOptions.markerStart)})`, :connection-status="connectionStatus"
}"
/> />
<path <path
v-else v-else
:d="dAttr" :d="dAttr"
class="vue-flow__connection-path" class="vue-flow__connection-path"
:class="connectionLineOptions.class" :class="[connectionLineOptions.class, connectionStatus]"
:style="connectionLineStyle || connectionLineOptions.style || {}" :style="connectionLineStyle || connectionLineOptions.style || {}"
:marker-end="`url(#${getMarkerId(connectionLineOptions.markerEnd)})`" :marker-end="`url(#${getMarkerId(connectionLineOptions.markerEnd)})`"
:marker-start="`url(#${getMarkerId(connectionLineOptions.markerStart)})`" :marker-start="`url(#${getMarkerId(connectionLineOptions.markerStart)})`"
@@ -33,6 +33,7 @@ export default function useHandle({
connectionRadius, connectionRadius,
connectOnClick, connectOnClick,
connectionClickStartHandle, connectionClickStartHandle,
connectionStatus,
nodesConnectable, nodesConnectable,
defaultEdgeOptions, defaultEdgeOptions,
autoPanOnConnect, autoPanOnConnect,
@@ -113,6 +114,8 @@ export default function useHandle({
event, event,
) )
connectionStatus.value = null
emits.connectStart({ event, nodeId, handleId, handleType }) emits.connectStart({ event, nodeId, handleId, handleType })
function onPointerMove(event: MouseEvent | TouchEvent) { function onPointerMove(event: MouseEvent | TouchEvent) {
@@ -154,6 +157,8 @@ export default function useHandle({
: connectionPosition, : connectionPosition,
) )
connectionStatus.value = getConnectionStatus(!!prevClosestHandle, isValid)
if (!prevClosestHandle) return resetRecentHandle(prevActiveHandle) if (!prevClosestHandle) return resetRecentHandle(prevActiveHandle)
connection = result.connection connection = result.connection
+1
View File
@@ -88,6 +88,7 @@ const defaultState = (): State => ({
connectionPosition: { x: NaN, y: NaN }, connectionPosition: { x: NaN, y: NaN },
connectionRadius: 20, connectionRadius: 20,
connectOnClick: true, connectOnClick: true,
connectionStatus: null,
snapGrid: [15, 15], snapGrid: [15, 15],
snapToGrid: false, snapToGrid: false,
+4 -4
View File
@@ -37,6 +37,8 @@ export type Connector = (
params: Connection, params: Connection,
) => Promise<(Connection & Partial<Edge>) | false> | ((Connection & Partial<Edge>) | false) ) => Promise<(Connection & Partial<Edge>) | false> | ((Connection & Partial<Edge>) | false)
export type ConnectionStatus = 'valid' | 'invalid'
/** The source nodes params when connection is initiated */ /** The source nodes params when connection is initiated */
export interface OnConnectStartParams { export interface OnConnectStartParams {
/** Source node id */ /** Source node id */
@@ -66,10 +68,6 @@ export interface ConnectionLineProps {
targetY: number targetY: number
/** Target position of the connection line */ /** Target position of the connection line */
targetPosition: Position targetPosition: Position
/** the shape of the connection line when active */
connectionLineType: ConnectionLineType
/** extra styles */
connectionLineStyle: CSSProperties
/** The source node of the connection line */ /** The source node of the connection line */
sourceNode: GraphNode sourceNode: GraphNode
/** The source handle element of the connection line */ /** The source handle element of the connection line */
@@ -78,4 +76,6 @@ export interface ConnectionLineProps {
markerStart: string markerStart: string
/** marker url */ /** marker url */
markerEnd: string markerEnd: string
/** status of the connection (valid, invalid) */
connectionStatus: ConnectionStatus
} }
+9 -1
View File
@@ -14,7 +14,14 @@ import type {
XYPosition, XYPosition,
} from './flow' } from './flow'
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components' 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 { DefaultEdgeOptions, Edge, EdgeUpdatable, GraphEdge } from './edge'
import type { CoordinateExtent, GraphNode, Node } from './node' import type { CoordinateExtent, GraphNode, Node } from './node'
import type { D3Selection, D3Zoom, D3ZoomHandler, PanOnScrollMode, ViewportFunctions, ViewportTransform } from './zoom' 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 connectionClickStartHandle: StartHandle | null
connectionPosition: XYPosition connectionPosition: XYPosition
connectionRadius: number connectionRadius: number
connectionStatus: ConnectionStatus | null
connectOnClick: boolean connectOnClick: boolean
edgeUpdaterRadius: number edgeUpdaterRadius: number
+13
View File
@@ -2,6 +2,7 @@ import { ConnectionMode } from '~/types'
import type { import type {
Actions, Actions,
Connection, Connection,
ConnectionStatus,
GraphEdge, GraphEdge,
GraphNode, GraphNode,
HandleType, HandleType,
@@ -160,3 +161,15 @@ export function getHandleType(edgeUpdaterType: HandleType | undefined, handleDom
return null 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
}