From 468d21b83985dadde34d21481c845f25fe6a31bf Mon Sep 17 00:00:00 2001 From: Artem Kyrychenko Date: Tue, 20 Oct 2026 16:47:14 +0300 Subject: [PATCH 1/3] fix(ui): nodes connections drift from arrow center based on connection length --- src/dev-toolbar/reactivity/index.tsx | 8 +++++--- src/dev-toolbar/reactivity/layout.test.ts | 8 +++++--- src/dev-toolbar/reactivity/layout.ts | 3 ++- src/dev-toolbar/reactivity/styles.css | 1 + 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/dev-toolbar/reactivity/index.tsx b/src/dev-toolbar/reactivity/index.tsx index 73f6494..10c87e3 100644 --- a/src/dev-toolbar/reactivity/index.tsx +++ b/src/dev-toolbar/reactivity/index.tsx @@ -7,6 +7,7 @@ import { Text } from '../../ui/Text.js'; import { FitIcon, GraphIcon, PauseIcon, PlayIcon } from '../icons.js'; import { formatValue, typeName } from './format.js'; import { + ARROW_SIZE, edgePath, layoutGraph, NODE_HEIGHT, @@ -526,10 +527,11 @@ export default function ReactivityViewer(props: ReactivityViewerProps): JSX.Elem diff --git a/src/dev-toolbar/reactivity/layout.test.ts b/src/dev-toolbar/reactivity/layout.test.ts index cc3ebe8..ecefd36 100644 --- a/src/dev-toolbar/reactivity/layout.test.ts +++ b/src/dev-toolbar/reactivity/layout.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from 'vitest'; import { + ARROW_SIZE, edgePath, layoutGraph, LAYER_GAP, @@ -125,14 +126,15 @@ describe('layoutGraph', () => { }); describe('edgePath', () => { - it('starts at the right edge of the source and ends at the left edge of the target', () => { + it('starts at the right edge of the source and ends arrow-size before the left edge of the target', () => { const from = { id: 'a', layer: 0, index: 0, x: 0, y: 0 }; const to = { id: 'b', layer: 1, index: 0, x: 280, y: 0 }; const middle = NODE_HEIGHT / 2; - const curve = Math.max((to.x - NODE_WIDTH) * 0.5, 40); + const endX = to.x - ARROW_SIZE; + const curve = Math.max((endX - NODE_WIDTH) * 0.5, 40); expect(edgePath(from, to)).toBe( - `M ${NODE_WIDTH} ${middle} C ${NODE_WIDTH + curve} ${middle}, ${to.x - curve} ${middle}, ${to.x} ${middle}`, + `M ${NODE_WIDTH} ${middle} C ${NODE_WIDTH + curve} ${middle}, ${endX - curve} ${middle}, ${endX} ${middle}`, ); }); diff --git a/src/dev-toolbar/reactivity/layout.ts b/src/dev-toolbar/reactivity/layout.ts index a2d176b..ff5d78c 100644 --- a/src/dev-toolbar/reactivity/layout.ts +++ b/src/dev-toolbar/reactivity/layout.ts @@ -5,6 +5,7 @@ export const NODE_HEIGHT = 44; export const LAYER_GAP = 76; export const ROW_GAP = 14; export const PADDING = 24; +export const ARROW_SIZE = 8; export interface LayoutInput { id: string; @@ -270,7 +271,7 @@ export function placeHoverCard(input: HoverCardInput): HoverCardPlacement { export function edgePath(from: LayoutNode, to: LayoutNode): string { const startX = from.x + NODE_WIDTH; const startY = from.y + NODE_HEIGHT / 2; - const endX = to.x; + const endX = to.x - ARROW_SIZE; const endY = to.y + NODE_HEIGHT / 2; const distance = Math.max(Math.abs(endX - startX) * 0.5, 40); return `M ${startX} ${startY} C ${startX + distance} ${startY}, ${endX - distance} ${endY}, ${endX} ${endY}`; diff --git a/src/dev-toolbar/reactivity/styles.css b/src/dev-toolbar/reactivity/styles.css index 3e00873..a02a2ee 100644 --- a/src/dev-toolbar/reactivity/styles.css +++ b/src/dev-toolbar/reactivity/styles.css @@ -183,6 +183,7 @@ fill: none; stroke: var(--start-dt-border); stroke-width: 1.5; + stroke-linecap: round; } [data-solid-reactivity-edge='muted'] { From 67fbd6dd55e5523a8913884e1d82b286a261e5db Mon Sep 17 00:00:00 2001 From: Artem Kyrychenko Date: Tue, 20 Oct 2026 16:59:30 +0300 Subject: [PATCH 2/3] fix(ui): update `` path and allow arrows to be colored when node is selected --- src/dev-toolbar/reactivity/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dev-toolbar/reactivity/index.tsx b/src/dev-toolbar/reactivity/index.tsx index 10c87e3..dfc20f5 100644 --- a/src/dev-toolbar/reactivity/index.tsx +++ b/src/dev-toolbar/reactivity/index.tsx @@ -534,7 +534,7 @@ export default function ReactivityViewer(props: ReactivityViewerProps): JSX.Elem markerHeight={ARROW_SIZE} orient="auto-start-reverse" > - + From 2350f36f28a37f7946624b0093d17f9b203fa2b6 Mon Sep 17 00:00:00 2001 From: Artem Kyrychenko Date: Tue, 20 Oct 2026 17:30:08 +0300 Subject: [PATCH 3/3] feat(ui): add `solid-reactivity-arrow-active` to preserve "scale on active" behaviour with `markerUnits="userSpaceOnUse"` attribute --- src/dev-toolbar/reactivity/index.tsx | 49 +++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/dev-toolbar/reactivity/index.tsx b/src/dev-toolbar/reactivity/index.tsx index dfc20f5..8da9d74 100644 --- a/src/dev-toolbar/reactivity/index.tsx +++ b/src/dev-toolbar/reactivity/index.tsx @@ -536,23 +536,42 @@ export default function ReactivityViewer(props: ReactivityViewerProps): JSX.Elem > + + + - {(edge) => ( - - {(from) => ( - - {(to) => ( - - )} - - )} - - )} + {(edge) => { + const role = () => edgeRoleOf(edge); + return ( + + {(from) => ( + + {(to) => ( + + )} + + )} + + ); + }}