fix: diagram zoom not working on initial render
The wheel event listener was attached in a useEffect with empty deps, but the SVG element doesn't exist during the loading state. Switch svgRef from a plain ref to a callback ref that triggers re-attachment when the SVG element becomes available after data loads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState, type RefCallback } from 'react';
|
||||
|
||||
interface ZoomPanState {
|
||||
scale: number;
|
||||
@@ -23,7 +23,13 @@ export function useZoomPan() {
|
||||
const didPan = useRef(false);
|
||||
const panStart = useRef({ x: 0, y: 0 });
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const svgRef = useRef<SVGSVGElement>(null);
|
||||
const svgElRef = useRef<SVGSVGElement | null>(null);
|
||||
const [svgReady, setSvgReady] = useState(false);
|
||||
|
||||
const svgRef: RefCallback<SVGSVGElement> = useCallback((el: SVGSVGElement | null) => {
|
||||
svgElRef.current = el;
|
||||
setSvgReady(!!el);
|
||||
}, []);
|
||||
|
||||
const clampScale = (s: number) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s));
|
||||
|
||||
@@ -32,8 +38,9 @@ export function useZoomPan() {
|
||||
|
||||
// Attach wheel listener with { passive: false } so preventDefault() stops page scroll.
|
||||
// React's onWheel is passive by default and cannot prevent scrolling.
|
||||
// Re-runs when the SVG element becomes available (e.g. after loading state clears).
|
||||
useEffect(() => {
|
||||
const svg = svgRef.current;
|
||||
const svg = svgElRef.current;
|
||||
if (!svg) return;
|
||||
const handler = (e: WheelEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -56,7 +63,7 @@ export function useZoomPan() {
|
||||
};
|
||||
svg.addEventListener('wheel', handler, { passive: false });
|
||||
return () => svg.removeEventListener('wheel', handler);
|
||||
}, []);
|
||||
}, [svgReady]);
|
||||
|
||||
const onPointerDown = useCallback(
|
||||
(e: React.PointerEvent<SVGSVGElement>) => {
|
||||
|
||||
Reference in New Issue
Block a user