diff --git a/packages/editor-ui/src/components/canvas/Canvas.vue b/packages/editor-ui/src/components/canvas/Canvas.vue
index b72c8065f4ab1..84997b70f62fa 100644
--- a/packages/editor-ui/src/components/canvas/Canvas.vue
+++ b/packages/editor-ui/src/components/canvas/Canvas.vue
@@ -1,13 +1,13 @@
@@ -82,6 +92,8 @@ function onKeyDown(e: KeyboardEvent) {
:max-zoom="2"
data-test-id="canvas"
@node-drag-stop="onNodeDragStop"
+ @edge-mouse-enter="onMouseEnterEdge"
+ @edge-mouse-leave="onMouseLeaveEdge"
@connect="onConnect"
>
@@ -89,7 +101,11 @@ function onKeyDown(e: KeyboardEvent) {
-
+
diff --git a/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.spec.ts b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.spec.ts
new file mode 100644
index 0000000000000..207efa6bab6c2
--- /dev/null
+++ b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.spec.ts
@@ -0,0 +1,42 @@
+import { fireEvent } from '@testing-library/vue';
+import CanvasEdge from './CanvasEdge.vue';
+import { createComponentRenderer } from '@/__tests__/render';
+
+const renderComponent = createComponentRenderer(CanvasEdge, {
+ props: {
+ sourceX: 0,
+ sourceY: 0,
+ sourcePosition: 'top',
+ targetX: 100,
+ targetY: 100,
+ targetPosition: 'bottom',
+ },
+});
+
+describe('CanvasEdge', () => {
+ it('should emit delete event when toolbar delete is clicked', async () => {
+ const { emitted, getByTestId } = renderComponent();
+ const deleteButton = getByTestId('delete-connection-button');
+
+ await fireEvent.click(deleteButton);
+
+ expect(emitted()).toHaveProperty('delete');
+ });
+
+ it('should compute edgeStyle correctly', () => {
+ const { container } = renderComponent({
+ props: {
+ style: {
+ stroke: 'red',
+ },
+ },
+ });
+
+ const edge = container.querySelector('.vue-flow__edge-path');
+
+ expect(edge).toHaveStyle({
+ stroke: 'red',
+ strokeWidth: 2,
+ });
+ });
+});
diff --git a/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.vue b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.vue
index 0d9d4617899df..fec9d28ef21b9 100644
--- a/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.vue
+++ b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdge.vue
@@ -2,16 +2,19 @@
/* eslint-disable vue/no-multiple-template-root */
import type { Connection, EdgeProps } from '@vue-flow/core';
import { BaseEdge, EdgeLabelRenderer, getBezierPath } from '@vue-flow/core';
+import CanvasEdgeToolbar from './CanvasEdgeToolbar.vue';
import { computed, useCssModule } from 'vue';
-import { useI18n } from '@/composables/useI18n';
const emit = defineEmits<{
delete: [connection: Connection];
}>();
-const props = defineProps();
+const props = defineProps<
+ EdgeProps & {
+ hovered?: boolean;
+ }
+>();
-const i18n = useI18n();
const $style = useCssModule();
const edgeStyle = computed(() => ({
@@ -19,8 +22,19 @@ const edgeStyle = computed(() => ({
...props.style,
}));
-const edgeLabelStyle = computed(() => ({
- transform: `translate(-50%, -50%) translate(${path.value[1]}px,${path.value[2]}px)`,
+const isEdgeToolbarVisible = computed(() => props.selected || props.hovered);
+
+const edgeToolbarStyle = computed(() => {
+ return {
+ transform: `translate(-50%, -50%) translate(${path.value[1]}px,${path.value[2]}px)`,
+ };
+});
+
+const edgeToolbarClasses = computed(() => ({
+ [$style.edgeToolbar]: true,
+ [$style.edgeToolbarVisible]: isEdgeToolbarVisible.value,
+ nodrag: true,
+ nopan: true,
}));
const path = computed(() =>
@@ -60,24 +74,24 @@ function onDelete() {
:label-bg-style="{ fill: 'red' }"
:label-bg-padding="[2, 4]"
:label-bg-border-radius="2"
+ :class="$style.edge"
/>
-
-
-
+
diff --git a/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdgeToolbar.spec.ts b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdgeToolbar.spec.ts
new file mode 100644
index 0000000000000..6968ac58a4a47
--- /dev/null
+++ b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdgeToolbar.spec.ts
@@ -0,0 +1,16 @@
+import { fireEvent } from '@testing-library/vue';
+import CanvasEdgeToolbar from './CanvasEdgeToolbar.vue';
+import { createComponentRenderer } from '@/__tests__/render';
+
+const renderComponent = createComponentRenderer(CanvasEdgeToolbar);
+
+describe('CanvasEdgeToolbar', () => {
+ it('should emit delete event when delete button is clicked', async () => {
+ const { getByTestId, emitted } = renderComponent();
+ const deleteButton = getByTestId('delete-connection-button');
+
+ await fireEvent.click(deleteButton);
+
+ expect(emitted()).toHaveProperty('delete');
+ });
+});
diff --git a/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdgeToolbar.vue b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdgeToolbar.vue
new file mode 100644
index 0000000000000..c7d287aa4b86d
--- /dev/null
+++ b/packages/editor-ui/src/components/canvas/elements/edges/CanvasEdgeToolbar.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+