refactor(core,edges): add div based edge label renderer
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user