From 81ede3137765c3040bfb0bdf2d6a11f133cd44e5 Mon Sep 17 00:00:00 2001 From: Pierre Chalamet Date: Fri, 16 Jan 2026 11:04:13 +0100 Subject: [PATCH] highlight edges on drag --- src/Terrabuild.UI/src/App.tsx | 31 +++++++++++++++++++ .../src/components/GraphPanel.tsx | 12 +++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Terrabuild.UI/src/App.tsx b/src/Terrabuild.UI/src/App.tsx index c9e2e8f0..a214cc81 100644 --- a/src/Terrabuild.UI/src/App.tsx +++ b/src/Terrabuild.UI/src/App.tsx @@ -102,6 +102,7 @@ const App = () => { const [manualPositions, setManualPositions] = useState< Record >({}); + const [draggedNodeId, setDraggedNodeId] = useState(null); const [nodes, setNodes] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const flowInstance = useRef(null); @@ -427,6 +428,34 @@ const App = () => { return layoutGraph(flowNodes, flowEdges); }, [graph, selectedNodeId, layoutVersion, effectiveColorScheme, theme]); + useEffect(() => { + const isDark = effectiveColorScheme === "dark"; + const defaultStroke = isDark ? theme.colors.dark[3] : theme.colors.gray[5]; + const highlightStroke = theme.colors.blue[6]; + setEdges((current) => + current.map((edge) => { + const isConnected = + draggedNodeId !== null && + (edge.source === draggedNodeId || edge.target === draggedNodeId); + const stroke = isConnected ? highlightStroke : defaultStroke; + return { + ...edge, + style: { + ...edge.style, + stroke, + strokeWidth: isConnected ? 2 : 1, + }, + markerStart: edge.markerStart + ? { + ...edge.markerStart, + color: stroke, + } + : edge.markerStart, + }; + }) + ); + }, [draggedNodeId, effectiveColorScheme, theme, setEdges]); + const nodeCount = graph ? Object.keys(graph.nodes).length : 0; const rootNodeCount = graph?.rootNodes?.length ?? 0; const formatLabel = (value: string) => @@ -876,6 +905,8 @@ const App = () => { onNodeClick={(_, node) => loadProjectResults(node.data.meta as ProjectNode) } + onNodeDragStart={(_, node) => setDraggedNodeId(node.id)} + onNodeDragStop={() => setDraggedNodeId(null)} onReflow={() => { setManualPositions({}); setLayoutVersion((value) => value + 1); diff --git a/src/Terrabuild.UI/src/components/GraphPanel.tsx b/src/Terrabuild.UI/src/components/GraphPanel.tsx index 19a28fa9..c0c3c71f 100644 --- a/src/Terrabuild.UI/src/components/GraphPanel.tsx +++ b/src/Terrabuild.UI/src/components/GraphPanel.tsx @@ -21,6 +21,8 @@ type GraphPanelProps = { onNodesChange: OnNodesChange; onEdgesChange: OnEdgesChange; onNodeClick: NodeMouseHandler; + onNodeDragStart: NodeMouseHandler; + onNodeDragStop: NodeMouseHandler; onReflow: () => void; }; @@ -33,6 +35,8 @@ const GraphPanel = ({ onNodesChange, onEdgesChange, onNodeClick, + onNodeDragStart, + onNodeDragStop, onReflow, }: GraphPanelProps) => { return ( @@ -87,9 +91,11 @@ const GraphPanel = ({ elementsSelectable panOnDrag onNodesChange={onNodesChange} - onEdgesChange={onEdgesChange} - onNodeClick={onNodeClick} - > + onEdgesChange={onEdgesChange} + onNodeClick={onNodeClick} + onNodeDragStart={onNodeDragStart} + onNodeDragStop={onNodeDragStop} + >