diff --git a/ui/src/components/ProcessDiagram/useZoomPan.ts b/ui/src/components/ProcessDiagram/useZoomPan.ts index 555e0436..22c5fef8 100644 --- a/ui/src/components/ProcessDiagram/useZoomPan.ts +++ b/ui/src/components/ProcessDiagram/useZoomPan.ts @@ -64,7 +64,11 @@ export function useZoomPan() { isPanning.current = true; didPan.current = false; panStart.current = { x: e.clientX - state.translateX, y: e.clientY - state.translateY }; - (e.currentTarget as SVGSVGElement).setPointerCapture(e.pointerId); + // Only capture pointer on empty space — capturing on nodes would + // redirect click/dblclick to the SVG, breaking node interactions + if (!(e.target as Element).closest('[data-node-id]')) { + (e.currentTarget as SVGSVGElement).setPointerCapture(e.pointerId); + } }, [state.translateX, state.translateY], ); @@ -85,7 +89,10 @@ export function useZoomPan() { const onPointerUp = useCallback( (e: React.PointerEvent) => { isPanning.current = false; - (e.currentTarget as SVGSVGElement).releasePointerCapture(e.pointerId); + const svg = e.currentTarget as SVGSVGElement; + if (svg.hasPointerCapture(e.pointerId)) { + svg.releasePointerCapture(e.pointerId); + } }, [], );