From 09624e9cb7a3f4490be6f47f2e81634a9696d128 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Fri, 6 Mar 2026 11:15:02 +0100 Subject: [PATCH] fix: Sidebar accounts for sticky header height via ResizeObserver Measures the review header dynamically and offsets the sidebar's sticky top and max-height accordingly, eliminating the gap when scrolled. --- apps/web/src/components/review/ReviewTab.tsx | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/web/src/components/review/ReviewTab.tsx b/apps/web/src/components/review/ReviewTab.tsx index ec78480..91c7c4e 100644 --- a/apps/web/src/components/review/ReviewTab.tsx +++ b/apps/web/src/components/review/ReviewTab.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { toast } from "sonner"; import { Loader2 } from "lucide-react"; import { trpc } from "@/lib/trpc"; @@ -18,6 +18,18 @@ export function ReviewTab({ initiativeId }: ReviewTabProps) { const [selectedCommit, setSelectedCommit] = useState(null); const [viewedFiles, setViewedFiles] = useState>(new Set()); const fileRefs = useRef>(new Map()); + const headerRef = useRef(null); + const [headerHeight, setHeaderHeight] = useState(0); + + useEffect(() => { + const el = headerRef.current; + if (!el) return; + const ro = new ResizeObserver(([entry]) => { + setHeaderHeight(entry.contentRect.height); + }); + ro.observe(el); + return () => ro.disconnect(); + }, []); const toggleViewed = useCallback((filePath: string) => { setViewedFiles(prev => { @@ -313,6 +325,7 @@ export function ReviewTab({ initiativeId }: ReviewTabProps) { return (
{/* Header: phase selector + toolbar */} +
({ id: p.id, name: p.name, status: p.status }))} activePhaseId={activePhaseId} @@ -331,12 +344,19 @@ export function ReviewTab({ initiativeId }: ReviewTabProps) { viewedCount={viewedFiles.size} totalCount={allFiles.length} /> +
{/* Main content area — sidebar always rendered to preserve state */}
{/* Left: Sidebar — sticky to viewport, scrolls independently */}
-
+