From 96913d2738b0a3908e96a699c59ad6a03eb15565 Mon Sep 17 00:00:00 2001 From: milanofthe Date: Sun, 13 Sep 2026 17:55:15 +0200 Subject: [PATCH] Add labels to connections with inline editing --- docs/pvm-spec.md | 1 + src/lib/components/canvas/flowConverters.ts | 2 +- src/lib/components/contextMenuBuilders.ts | 6 + .../components/edges/OrthogonalEdge.svelte | 146 +++++++++++++++++- src/lib/constants/dimensions.ts | 10 ++ src/lib/stores/clipboard.ts | 3 +- src/lib/stores/edgeLabelEdit.svelte.ts | 10 ++ src/lib/stores/graph/connections.ts | 16 ++ src/lib/stores/graph/index.ts | 1 + src/lib/stores/graph/nodes.ts | 3 +- src/lib/types/nodes.ts | 1 + 11 files changed, 195 insertions(+), 4 deletions(-) create mode 100644 src/lib/stores/edgeLabelEdit.svelte.ts diff --git a/docs/pvm-spec.md b/docs/pvm-spec.md index e74711e1..db717de4 100644 --- a/docs/pvm-spec.md +++ b/docs/pvm-spec.md @@ -192,6 +192,7 @@ A connection is a directed wire from a source output port to a target input port | `targetNodeId` | string | yes | ID of the target node. | | `targetPortIndex` | number | yes | Index into the target node's `inputs` array. | | `waypoints` | array | no | Route control points. UI-only, no simulation semantics. | +| `label` | string | no | Text shown on the wire, e.g. a signal name. UI-only, no simulation semantics. | **Fan-out:** A single output port can connect to multiple input ports (multiple connections share the same `sourceNodeId`/`sourcePortIndex`). diff --git a/src/lib/components/canvas/flowConverters.ts b/src/lib/components/canvas/flowConverters.ts index 6407b209..712ebc09 100644 --- a/src/lib/components/canvas/flowConverters.ts +++ b/src/lib/components/canvas/flowConverters.ts @@ -56,7 +56,7 @@ export function toFlowEdge(conn: Connection): Edge { target: conn.targetNodeId, targetHandle: HANDLE_ID.input(conn.targetNodeId, conn.targetPortIndex), type: 'orthogonal', - data: { waypoints: conn.waypoints }, + data: { waypoints: conn.waypoints, label: conn.label }, selectable: true, deletable: true, animated: false diff --git a/src/lib/components/contextMenuBuilders.ts b/src/lib/components/contextMenuBuilders.ts index 645194be..e1be1ef6 100644 --- a/src/lib/components/contextMenuBuilders.ts +++ b/src/lib/components/contextMenuBuilders.ts @@ -9,6 +9,7 @@ import type { ContextMenuTarget } from '$lib/stores/contextMenu'; import { graphStore, ANNOTATION_FONT_SIZE } from '$lib/stores/graph'; import { historyStore } from '$lib/stores/history'; import { routingStore } from '$lib/stores/routing'; +import { editEdgeLabel } from '$lib/stores/edgeLabelEdit.svelte'; import { eventStore } from '$lib/stores/events'; import { clipboardStore } from '$lib/stores/clipboard'; import { codePreviewStore } from '$lib/stores/codePreview'; @@ -400,6 +401,11 @@ function buildEventMenu(eventId: string): MenuItemType[] { */ function buildEdgeMenu(edgeId: string): MenuItemType[] { return [ + { + label: 'Edit Label', + icon: 'tag', + action: () => editEdgeLabel(edgeId) + }, { label: 'Reset Route', icon: 'rotate', diff --git a/src/lib/components/edges/OrthogonalEdge.svelte b/src/lib/components/edges/OrthogonalEdge.svelte index 5aba0f89..c5c5c485 100644 --- a/src/lib/components/edges/OrthogonalEdge.svelte +++ b/src/lib/components/edges/OrthogonalEdge.svelte @@ -26,12 +26,15 @@ + @@ -386,8 +463,30 @@ class:highlighted={highlightColor !== undefined} /> + + {#if label && !isEditingLabel && labelAnchor} + {label} + {/if} +{#if isEditingLabel && labelAnchor} + + + +{/if} +