+
+ );
+}
diff --git a/packages/react/src/additional-components/EdgeToolbar/index.tsx b/packages/react/src/additional-components/EdgeToolbar/index.tsx
new file mode 100644
index 00000000..5e1bc931
--- /dev/null
+++ b/packages/react/src/additional-components/EdgeToolbar/index.tsx
@@ -0,0 +1,2 @@
+export { EdgeToolbar } from './EdgeToolbar';
+export type { EdgeToolbarProps } from './types';
diff --git a/packages/react/src/additional-components/EdgeToolbar/types.ts b/packages/react/src/additional-components/EdgeToolbar/types.ts
new file mode 100644
index 00000000..96261694
--- /dev/null
+++ b/packages/react/src/additional-components/EdgeToolbar/types.ts
@@ -0,0 +1,41 @@
+import type { HTMLAttributes } from 'react';
+import type { Position, Align } from '@xyflow/system';
+
+/**
+ * @expand
+ */
+export type EdgeToolbarProps = HTMLAttributes & {
+ /**
+ * By passing in an array of edge id's you can render a single tooltip for a group or collection
+ * of edges.
+ */
+ edgeId?: string;
+ /** If `true`, edge toolbar is visible even if edge is not selected. */
+ isVisible?: boolean;
+ /**
+ * TODO: What and how?? Needed?
+ * Position of the toolbar relative to the edge.
+ * @default Position.Top
+ * @example Position.TopLeft, Position.TopRight, Position.BottomLeft, Position.BottomRight
+ */
+ position?: Position;
+ /**
+ * The space between the edge and the toolbar, measured in pixels.
+ * @default 10
+ */
+ offset?: number;
+ /**
+ * Align the toolbar relative to the edge.
+ * @default "center"
+ * @example Align.Start, Align.Center, Align.End
+ */
+ align?: Align;
+ /**
+ * The `x` position of the edge label.
+ */
+ labelX: number;
+ /**
+ * The `y` position of the edge label.
+ */
+ labelY: number;
+};
diff --git a/packages/react/src/additional-components/index.ts b/packages/react/src/additional-components/index.ts
index 94a1595e..787303a5 100644
--- a/packages/react/src/additional-components/index.ts
+++ b/packages/react/src/additional-components/index.ts
@@ -3,3 +3,4 @@ export * from './Controls';
export * from './MiniMap';
export * from './NodeResizer';
export * from './NodeToolbar';
+export * from './EdgeToolbar';
diff --git a/packages/system/src/utils/edge-toolbar.ts b/packages/system/src/utils/edge-toolbar.ts
new file mode 100644
index 00000000..3fe2c5c2
--- /dev/null
+++ b/packages/system/src/utils/edge-toolbar.ts
@@ -0,0 +1,6 @@
+import { Position, type Viewport, type Align } from '..';
+
+export function getEdgeToolbarTransform(labelX: number, labelY: number, viewport: Viewport): string {
+ // Position the toolbar at the edge label center (scaling is handled by EdgeLabelRenderer)
+ return `translate(${labelX}px, ${labelY}px)`;
+}
diff --git a/packages/system/src/utils/index.ts b/packages/system/src/utils/index.ts
index 2640195d..caf8b026 100644
--- a/packages/system/src/utils/index.ts
+++ b/packages/system/src/utils/index.ts
@@ -5,6 +5,7 @@ export * from './graph';
export * from './general';
export * from './marker';
export * from './node-toolbar';
+export * from './edge-toolbar';
export * from './store';
export * from './types';
export * from './shallow-node-data';