feat(edges): hide edge while updating

This commit is contained in:
braks
2022-08-30 22:16:10 +02:00
committed by Braks
parent 058fb5ae10
commit bd4eb7cc54
2 changed files with 172 additions and 174 deletions
+156 -171
View File
@@ -1,6 +1,6 @@
import type { CSSProperties, Component, FunctionalComponent, VNode } from 'vue' import type { CSSProperties, Component, VNode } from 'vue'
import EdgeAnchor from './EdgeAnchor' import EdgeAnchor from './EdgeAnchor'
import type { EdgeComponent, EdgeEventsOn, EdgeMarkerType, EdgeTextProps, GraphNode, EdgeUpdatable } from '~/types' import type { EdgeComponent, EdgeEventsOn, EdgeMarkerType, EdgeTextProps, EdgeUpdatable, GraphNode } from '~/types'
import { ConnectionMode, Position } from '~/types' import { ConnectionMode, Position } from '~/types'
import { getEdgePositions, getHandle, getMarkerId } from '~/utils' import { getEdgePositions, getHandle, getMarkerId } from '~/utils'
@@ -31,193 +31,178 @@ interface Props {
markerStart?: EdgeMarkerType markerStart?: EdgeMarkerType
connectionMode: ConnectionMode connectionMode: ConnectionMode
edgeUpdaterRadius: number edgeUpdaterRadius: number
updating?: boolean
} }
const Wrapper: FunctionalComponent<Props> = function ( const Wrapper = defineComponent({
{ props: [
name, 'name',
type, 'type',
id, 'id',
data, 'data',
events, 'events',
labelBgBorderRadius, 'labelBgBorderRadius',
labelBgPadding, 'labelBgPadding',
labelBgStyle, 'labelBgStyle',
labelStyle, 'labelStyle',
labelShowBg, 'labelShowBg',
style, 'style',
animated, 'animated',
label, 'label',
updatable, 'updatable',
selectable, 'selectable',
target, 'target',
source, 'source',
sourceNode, 'sourceNode',
targetNode, 'targetNode',
sourceHandleId, 'sourceHandleId',
targetHandleId, 'targetHandleId',
selected, 'selected',
markerEnd, 'markerEnd',
markerStart, 'markerStart',
connectionMode, 'connectionMode',
edgeUpdaterRadius, 'edgeUpdaterRadius',
}, 'updating',
{ emit }, ],
) { emits: ['source-mousedown', 'target-mousedown'],
if (!sourceNode || !targetNode) return null setup(props: Props, { emit }) {
let updating = $ref(false)
let updating = $ref(false) const onEdgeUpdaterMouseEnter = () => (updating = true)
const onEdgeUpdaterMouseEnter = () => (updating = true) const onEdgeUpdaterMouseOut = () => (updating = false)
const onEdgeUpdaterMouseOut = () => (updating = false) const onEdgeUpdaterSourceMouseDown = (e: MouseEvent) => {
emit('source-mousedown', e)
}
const onEdgeUpdaterSourceMouseDown = (e: MouseEvent) => { const onEdgeUpdaterTargetMouseDown = (e: MouseEvent) => {
emit('source-mousedown', e) emit('target-mousedown', e)
} }
const onEdgeUpdaterTargetMouseDown = (e: MouseEvent) => { return () => {
emit('target-mousedown', e) if (!props.sourceNode || !props.targetNode) return null
}
let sourceNodeHandles let sourceNodeHandles
if (connectionMode === ConnectionMode.Strict) { if (props.connectionMode === ConnectionMode.Strict) {
sourceNodeHandles = sourceNode.handleBounds.source sourceNodeHandles = props.sourceNode.handleBounds.source
} else { } else {
sourceNodeHandles = sourceNode.handleBounds.source ?? sourceNode.handleBounds.target sourceNodeHandles = props.sourceNode.handleBounds.source ?? props.sourceNode.handleBounds.target
} }
const sourceHandle = getHandle(sourceNodeHandles, sourceHandleId) const sourceHandle = getHandle(sourceNodeHandles, props.sourceHandleId)
let targetNodeHandles let targetNodeHandles
if (connectionMode === ConnectionMode.Strict) { if (props.connectionMode === ConnectionMode.Strict) {
targetNodeHandles = targetNode.handleBounds.target targetNodeHandles = props.targetNode.handleBounds.target
} else { } else {
targetNodeHandles = targetNode.handleBounds.target ?? targetNode.handleBounds.source targetNodeHandles = props.targetNode.handleBounds.target ?? props.targetNode.handleBounds.source
} }
const targetHandle = getHandle(targetNodeHandles, targetHandleId) const targetHandle = getHandle(targetNodeHandles, props.targetHandleId)
const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom
const targetPosition = targetHandle ? targetHandle.position : Position.Top const targetPosition = targetHandle ? targetHandle.position : Position.Top
const { sourceX, sourceY, targetY, targetX } = getEdgePositions( const { sourceX, sourceY, targetY, targetX } = getEdgePositions(
sourceNode, props.sourceNode,
sourceHandle, sourceHandle,
sourcePosition,
targetNode,
targetHandle,
targetPosition,
)
return h(
'g',
{
class: [
'vue-flow__edge',
`vue-flow__edge-${name}`,
{
updating,
selected,
animated,
inactive: !selectable,
},
],
},
[
h(type as any, {
id,
sourceNode,
targetNode,
source,
target,
updatable,
selected,
animated,
label,
labelStyle,
labelShowBg,
labelBgStyle,
labelBgPadding,
labelBgBorderRadius,
data,
events,
style,
markerStart: `url(#${getMarkerId(markerStart)})`,
markerEnd: `url(#${getMarkerId(markerEnd)})`,
sourcePosition, sourcePosition,
props.targetNode,
targetHandle,
targetPosition, targetPosition,
sourceX, )
sourceY,
targetX, return h(
targetY, 'g',
sourceHandleId, {
targetHandleId, class: [
}), 'vue-flow__edge',
[ `vue-flow__edge-${props.name}`,
updatable === 'source' || updatable === true ? [ h(
'g',
{ {
onMousedown: onEdgeUpdaterSourceMouseDown, updating,
onMouseenter: onEdgeUpdaterMouseEnter, selected: props.selected,
onMouseout: onEdgeUpdaterMouseOut, animated: props.animated,
inactive: !props.selectable,
}, },
h(EdgeAnchor, { ],
position: sourcePosition, },
centerX: sourceX, [
centerY: sourceY, props.updating
radius: edgeUpdaterRadius, ? null
}), : h(props.type as any, {
)] : null, id: props.id,
updatable === 'target' || updatable === true ? [ h( sourceNode: props.sourceNode,
'g', targetNode: props.targetNode,
{ source: props.source,
onMousedown: onEdgeUpdaterTargetMouseDown, target: props.target,
onMouseenter: onEdgeUpdaterMouseEnter, updatable: props.updatable,
onMouseout: onEdgeUpdaterMouseOut, selected: props.selected,
}, animated: props.animated,
h(EdgeAnchor, { label: props.label,
position: targetPosition, labelStyle: props.labelStyle,
centerX: targetX, labelShowBg: props.labelShowBg,
centerY: targetY, labelBgStyle: props.labelBgStyle,
radius: edgeUpdaterRadius, labelBgPadding: props.labelBgPadding,
}), labelBgBorderRadius: props.labelBgBorderRadius,
)] : null, data: props.data,
events: props.events,
style: props.style,
markerStart: `url(#${getMarkerId(props.markerStart)})`,
markerEnd: `url(#${getMarkerId(props.markerEnd)})`,
sourcePosition,
targetPosition,
sourceX,
sourceY,
targetX,
targetY,
sourceHandleId: props.sourceHandleId,
targetHandleId: props.targetHandleId,
}),
[
props.updatable === 'source' || props.updatable === true
? [
h(
'g',
{
onMousedown: onEdgeUpdaterSourceMouseDown,
onMouseenter: onEdgeUpdaterMouseEnter,
onMouseout: onEdgeUpdaterMouseOut,
},
h(EdgeAnchor, {
position: sourcePosition,
centerX: sourceX,
centerY: sourceY,
radius: props.edgeUpdaterRadius,
}),
),
]
: null,
props.updatable === 'target' || props.updatable === true
? [
h(
'g',
{
onMousedown: onEdgeUpdaterTargetMouseDown,
onMouseenter: onEdgeUpdaterMouseEnter,
onMouseout: onEdgeUpdaterMouseOut,
},
h(EdgeAnchor, {
position: targetPosition,
centerX: targetX,
centerY: targetY,
radius: props.edgeUpdaterRadius,
}),
),
]
: null,
],
], ],
], )
) }
} },
})
Wrapper.props = [
'name',
'type',
'id',
'data',
'events',
'labelBgBorderRadius',
'labelBgPadding',
'labelBgStyle',
'labelStyle',
'labelShowBg',
'style',
'animated',
'label',
'updatable',
'selectable',
'target',
'source',
'sourceNode',
'targetNode',
'sourceHandleId',
'targetHandleId',
'selected',
'markerEnd',
'markerStart',
'connectionMode',
'edgeUpdaterRadius',
]
Wrapper.emits = ['source-mousedown', 'target-mousedown']
export default Wrapper export default Wrapper
@@ -32,8 +32,11 @@ const {
} = $(useVueFlow()) } = $(useVueFlow())
const selectable = (s?: boolean) => (typeof s === 'undefined' ? elementsSelectable : s) const selectable = (s?: boolean) => (typeof s === 'undefined' ? elementsSelectable : s)
const updatable = (u?: EdgeUpdatable) => (typeof u === 'undefined' ? edgesUpdatable : u) const updatable = (u?: EdgeUpdatable) => (typeof u === 'undefined' ? edgesUpdatable : u)
const updating = ref<string>()
const sourceNode = $( const sourceNode = $(
controlledComputed($$(connectionNodeId), () => { controlledComputed($$(connectionNodeId), () => {
if (connectionNodeId) return getNode(connectionNodeId) if (connectionNodeId) return getNode(connectionNodeId)
@@ -142,9 +145,15 @@ const onEdgeMouseMove = (event: MouseEvent, edge: GraphEdge) => hooks[edge.id].e
const onEdgeMouseLeave = (event: MouseEvent, edge: GraphEdge) => hooks[edge.id].emit.mouseLeave({ event, edge }) const onEdgeMouseLeave = (event: MouseEvent, edge: GraphEdge) => hooks[edge.id].emit.mouseLeave({ event, edge })
const onEdgeUpdaterSourceMouseDown = (event: MouseEvent, edge: GraphEdge) => handleEdgeUpdater(event, edge, true) const onEdgeUpdaterSourceMouseDown = (event: MouseEvent, edge: GraphEdge) => {
updating.value = edge.id
handleEdgeUpdater(event, edge, true)
}
const onEdgeUpdaterTargetMouseDown = (event: MouseEvent, edge: GraphEdge) => handleEdgeUpdater(event, edge, false) const onEdgeUpdaterTargetMouseDown = (event: MouseEvent, edge: GraphEdge) => {
updating.value = edge.id
handleEdgeUpdater(event, edge, false)
}
const { onMouseDown } = useHandle() const { onMouseDown } = useHandle()
@@ -164,7 +173,10 @@ const handleEdgeUpdater = (event: MouseEvent, edge: GraphEdge, isSourceHandle: b
(connection) => { (connection) => {
if (!connectionExists(connection, getEdges)) hooks[edge.id].emit.update({ edge, connection }) if (!connectionExists(connection, getEdges)) hooks[edge.id].emit.update({ edge, connection })
}, },
() => hooks[edge.id].emit.updateEnd({ event, edge }), () => {
hooks[edge.id].emit.updateEnd({ event, edge })
updating.value = ''
},
) )
} }
@@ -205,6 +217,7 @@ export default {
:selectable="selectable(edge.selectable)" :selectable="selectable(edge.selectable)"
:selected="edge.selected" :selected="edge.selected"
:updatable="updatable(edge.updatable)" :updatable="updatable(edge.updatable)"
:updating="edge.id === updating"
:label-style="edge.labelStyle" :label-style="edge.labelStyle"
:label-show-bg="edge.labelShowBg" :label-show-bg="edge.labelShowBg"
:label-bg-style="edge.labelBgStyle" :label-bg-style="edge.labelBgStyle"