Custom Edge Types
yh-flow supports registering and using custom edge types. Through a simple registration mechanism, you can configure unique appearances and interaction logics for specific types of edges without repeating code in every canvas.
Core Concepts
When using custom components, it is recommended to inject them via the yh-flow Props. This aligns with low coupling and high cohesion functional programming principles, and is fully compatible with SSR environments like Nuxt.
1. Component Prop Injection (Recommended)
Inject component types via the edge-types property. This approach has a clear scope and does not pollute the global state, making it ideal for large-scale applications.
<script setup lang="ts">
import { ref, defineComponent, h } from 'vue'
import { Flow } from '@yh-ui/flow'
// 1. Define or import your custom edge component
const MyCustomEdge = defineComponent({
props: ['path', 'stroke'],
setup(props) {
return () => h('path', { d: props.path, stroke: 'orange', strokeWidth: 3, fill: 'none' })
}
})
// 2. Map component to a specific type key
const edgeTypes = {
'custom-orange': MyCustomEdge
}
const edges = ref([{ id: 'e1', source: 'a', target: 'b', type: 'custom-orange' }])
</script>
<template>
<yh-flow :edges="edges" :edge-types="edgeTypes" />
</template>2. Global Registration (Multi-Instance Sharing)
Use registerCustomEdge if you need to share the same custom styles across multiple independent flow instances. This adds the component to the internal global registry.
CAUTION
In SSR (Nuxt 3) environments, please register only in client-side plugins or prioritize Prop injection to prevent state leaks between requests.
import { registerCustomEdge } from '@yh-ui/flow'
// Import your component from a separate file
import MyEdgeComponent from './MyEdge.vue'
registerCustomEdge({
type: 'my-custom-edge',
component: MyEdgeComponent,
label: 'Corporate Review Edge'
})3. Slot Mode (Manual)
If you only want to change edge styles temporarily in a specific canvas or need access to complex parent context, use the #edge slot:
<yh-flow :nodes="nodes" :edges="edges">
<template #edge="edgeProps">
<!-- Manual control over rendering -->
<MySpecialEdge v-bind="edgeProps" />
</template>
</yh-flow>Complete Example
Developing a Custom Edge Component
Custom components receive a complete Prop object including coordinates, paths, center points, and original data.
<!-- CustomEdgeComponent.vue -->
<template>
<g class="custom-edge" :class="{ 'is-selected': edge.selected }">
<!-- Main path -->
<path
:d="path"
:stroke="stroke"
:stroke-width="strokeWidth"
fill="none"
:stroke-dasharray="edge.animated ? '5,5' : 'none'"
/>
<!-- Marker at the center -->
<circle :cx="labelX" :cy="labelY" r="5" fill="#10b981" />
<!-- Label -->
<text v-if="edge.label" :x="labelX" :y="labelY - 10" text-anchor="middle" class="edge-label">
{{ edge.label }}
</text>
</g>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { Edge } from '@yh-ui/flow'
interface Props {
edge: Edge
path: string
sourceX: number
sourceY: number
targetX: number
targetY: number
labelX: number
labelY: number
stroke: string
strokeWidth: number
}
const props = defineProps<Props>()
</script>
<style scoped>
.custom-edge path {
transition: all 0.3s;
}
.custom-edge.is-selected path {
stroke-width: 5;
filter: drop-shadow(0 0 4px rgba(16, 185, 129, 0.5));
}
.edge-label {
font-size: 12px;
fill: #64748b;
font-weight: bold;
}
</style>Automatic Rendering Demo
The example below shows how the EdgeRenderer takes over rendering once a type is registered.
API Reference
Registration Functions
| Function | Description |
|---|---|
registerCustomEdge(edge: CustomEdge) | Register global custom edge component |
getCustomEdge(type: string) | Get registered component information |
registerEdgeTemplate(template: EdgeTemplate) | Register edge template with defaults |
Type Definitions
// Custom Edge Configuration
interface CustomEdge {
type: string // Unique identifier for Edge.type
component: Component // Vue component
label?: string // Alias or description
}
// Props passed to custom components
interface EdgeProps {
edge: Edge // Raw edge data
path: string // Pre-calculated SVG path string
sourceX: number // Source X
sourceY: number // Source Y
targetX: number // Target X
targetY: number // Target Y
labelX: number // Center point X
labelY: number // Center point Y
labelWidth: number // Pre-calculated label width (px)
stroke: string // Pre-calculated stroke color
strokeWidth: number // Calculated stroke width
}Custom edge components must return valid SVG elements (typically wrapped in a
<g>tag), otherwise rendering may break when layered.