refactor(core,edges): add div based edge label renderer

This commit is contained in:
braks
2022-11-04 22:10:40 +01:00
committed by Braks
parent 0f2bc10fd2
commit 43ff2a42e6
10 changed files with 168 additions and 107 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@vue-flow/core': patch
---
Teleport edge labels into separate svg container (fixes edges overlapping edge labels)
@@ -0,0 +1,23 @@
<script lang="ts" setup>
import { useVueFlow } from '../../composables'
const { viewportRef } = useVueFlow()
const teleportTarget = $computed(() => viewportRef.value?.getElementsByClassName('vue-flow__edge-labels')[0])
</script>
<script lang="ts">
export default {
name: 'EdgeLabelRenderer',
}
</script>
<template>
<svg>
<foreignObject height="0" width="0">
<Teleport :to="teleportTarget" :disabled="!teleportTarget">
<slot />
</Teleport>
</foreignObject>
</svg>
</template>
@@ -1,4 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { isString } from '@vueuse/core'
import type { EdgeTextProps } from '../../types/components' import type { EdgeTextProps } from '../../types/components'
import type { Rect as RectType } from '../../types' import type { Rect as RectType } from '../../types'
@@ -55,10 +56,8 @@ export default {
/> />
<text v-bind="$attrs" ref="el" class="vue-flow__edge-text" :y="box.height / 2" dy="0.3em" :style="labelStyle"> <text v-bind="$attrs" ref="el" class="vue-flow__edge-text" :y="box.height / 2" dy="0.3em" :style="labelStyle">
<slot> <slot>
<component :is="label" v-if="typeof label !== 'string' && typeof label" /> <component :is="label" v-if="!isString(label)" />
<template v-else> <template v-else> {{ label }} </template>
{{ label }}
</template>
</slot> </slot>
</text> </text>
</g> </g>
@@ -7,3 +7,4 @@ export { default as StraightEdge } from './StraightEdge'
export { default as EdgeAnchor } from './EdgeAnchor' export { default as EdgeAnchor } from './EdgeAnchor'
export { default as EdgeText } from './EdgeText.vue' export { default as EdgeText } from './EdgeText.vue'
export { default as EdgeWrapper } from './Wrapper' export { default as EdgeWrapper } from './Wrapper'
export { default as EdgeLabelRenderer } from './EdgeLabelRenderer.vue'
@@ -127,7 +127,8 @@ export default {
</script> </script>
<template> <template>
<svg v-for="group of groups" :key="group.level" class="vue-flow__edges vue-flow__container" :style="`z-index: ${group.level}`"> <template v-for="group of groups" :key="group.level">
<svg class="vue-flow__edges vue-flow__container" :style="`z-index: ${group.level}`">
<MarkerDefinitions v-if="group.isMaxLevel" /> <MarkerDefinitions v-if="group.isMaxLevel" />
<g> <g>
<EdgeWrapper <EdgeWrapper
@@ -145,6 +146,8 @@ export default {
/> />
</g> </g>
</svg> </svg>
</template>
<svg v-if="connectionLineVisible && !!sourceNode" class="vue-flow__edges vue-flow__connectionline vue-flow__container"> <svg v-if="connectionLineVisible && !!sourceNode" class="vue-flow__edges vue-flow__connectionline vue-flow__container">
<ConnectionLine :source-node="sourceNode" /> <ConnectionLine :source-node="sourceNode" />
</svg> </svg>
@@ -53,6 +53,9 @@ export default {
:style="{ transform: `translate(${viewport.x}px,${viewport.y}px) scale(${viewport.zoom})`, opacity: ready ? undefined : 0 }" :style="{ transform: `translate(${viewport.x}px,${viewport.y}px) scale(${viewport.zoom})`, opacity: ready ? undefined : 0 }"
> >
<EdgeRenderer /> <EdgeRenderer />
<div class="vue-flow__edge-labels" />
<NodeRenderer /> <NodeRenderer />
<slot /> <slot />
</div> </div>
+10 -1
View File
@@ -7,7 +7,16 @@ export { default as VueFlow } from './container/VueFlow/VueFlow.vue'
export { default as Handle } from './components/Handle/Handle.vue' export { default as Handle } from './components/Handle/Handle.vue'
export { StraightEdge, StepEdge, BezierEdge, SimpleBezierEdge, SmoothStepEdge, BaseEdge, EdgeText } from './components/Edges' export {
StraightEdge,
StepEdge,
BezierEdge,
SimpleBezierEdge,
SmoothStepEdge,
BaseEdge,
EdgeText,
EdgeLabelRenderer,
} from './components/Edges'
export { getBezierPath, getSimpleBezierPath, getSmoothStepPath, getStraightPath } from './components/Edges/utils' export { getBezierPath, getSimpleBezierPath, getSmoothStepPath, getStraightPath } from './components/Edges/utils'
+7
View File
@@ -39,6 +39,13 @@
z-index: 5; z-index: 5;
} }
.vue-flow__edge-labels {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
}
.vue-flow__nodesselection-rect:focus, .vue-flow__nodesselection-rect:focus,
.vue-flow__nodesselection-rect:focus-visible { .vue-flow__nodesselection-rect:focus-visible {
outline: none; outline: none;
+1 -1
View File
@@ -106,7 +106,7 @@ export const parseEdge = (edge: Edge, defaults?: Partial<GraphEdge>): GraphEdge
selectable: edge.selectable, selectable: edge.selectable,
data: shallowReactive(edge.data || {}), data: shallowReactive(edge.data || {}),
events: shallowReactive(edge.events || {}), events: shallowReactive(edge.events || {}),
label: edge.label && !isString(edge.label) ? markRaw(edge.label) : undefined, label: edge.label && !isString(edge.label) ? markRaw(edge.label) : edge.label,
...defaults, ...defaults,
} as GraphEdge) } as GraphEdge)
: defaults : defaults
+12 -1
View File
@@ -36,6 +36,13 @@
z-index: 5; z-index: 5;
} }
.vue-flow__edge-labels {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
}
.vue-flow__nodesselection-rect:focus, .vue-flow__nodesselection-rect:focus,
.vue-flow__nodesselection-rect:focus-visible { .vue-flow__nodesselection-rect:focus-visible {
outline: none; outline: none;
@@ -86,7 +93,7 @@
fill: white; fill: white;
} }
.vue-flow__edge-text { &-text {
pointer-events: none; pointer-events: none;
user-select: none; user-select: none;
} }
@@ -132,6 +139,10 @@
position: absolute; position: absolute;
pointer-events: all; pointer-events: all;
cursor: grab; cursor: grab;
&.dragging {
cursor: grabbing;
}
} }
} }