From a8b3269b1eb4fdf2ac68f80e6479e6c9843fc780 Mon Sep 17 00:00:00 2001 From: rouggy Date: Sun, 5 Jul 2026 14:40:20 +0200 Subject: [PATCH] fix: Bandmap scroll bar to top --- frontend/src/components/BandMap.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/BandMap.tsx b/frontend/src/components/BandMap.tsx index 9dc5488..0531065 100644 --- a/frontend/src/components/BandMap.tsx +++ b/frontend/src/components/BandMap.tsx @@ -284,6 +284,10 @@ export function BandMap({ band, spots, spotStatus, currentFreqHz, onSpotClick, o out.push({ spot: filtered[i], freqY: desired[i], labelY: centers[i] + shift - PILL_H / 2 }); } const lastLabelBottom = out.length ? out[out.length - 1].labelY + PILL_H : 0; + // In fit mode the band scale exactly fills the viewport (innerH = containerH + // − pads); when crowded sub-bands stack labels past the bottom the content + // grows and a scroll bar appears — the map defaults to the top so the whole + // band is visible, and you scroll down to reach the stacked spots. return { placed: out, totalH: Math.max(innerH + TOP_PAD + BOT_PAD, lastLabelBottom + BOT_PAD), @@ -300,15 +304,19 @@ export function BandMap({ band, spots, spotStatus, currentFreqHz, onSpotClick, o // frequency actually changes (or band/zoom/size), so tuning follows the rig // while a stable frequency leaves your manual scroll alone. useEffect(() => { - if (!range || containerH <= 0 || currentFreqHz <= 0) return; - const kHz = currentFreqHz / 1000; - if (kHz < lo || kHz > hi) return; + if (!range || containerH <= 0) return; const el = scrollerRef.current; if (!el) return; + // Fit-to-band: keep the view at the top so the full band is always in frame; + // any overflow spots are reached by scrolling down (don't follow the rig). + if (fitToBand) { el.scrollTop = 0; return; } + if (currentFreqHz <= 0) return; + const kHz = currentFreqHz / 1000; + if (kHz < lo || kHz > hi) return; el.scrollTop = Math.max(0, freqToY(kHz) - containerH / 2); // freqToY is recomputed each render; intentionally excluded from deps. // eslint-disable-next-line react-hooks/exhaustive-deps - }, [band, containerH, currentFreqHz, range, lo, hi, pxPerKHz]); + }, [band, containerH, currentFreqHz, range, lo, hi, pxPerKHz, fitToBand]); useEffect(() => { const el = scrollerRef.current;