From a3dafa971ae8346b1b836ce5cbb51589bfdc2321 Mon Sep 17 00:00:00 2001 From: headpatsyou Date: Wed, 7 Jan 2026 09:07:48 +0000 Subject: [PATCH] fix: ToC highlights only topmost visible heading --- src/components/markdown/TableOfContents.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/components/markdown/TableOfContents.tsx b/src/components/markdown/TableOfContents.tsx index 0527de9..d123be8 100644 --- a/src/components/markdown/TableOfContents.tsx +++ b/src/components/markdown/TableOfContents.tsx @@ -8,13 +8,27 @@ export function TableOfContents({ headings }: { headings: Heading[] }) { const observerRef = useRef(null); useEffect(() => { + const visibleHeadings = new Map(); + const callback: IntersectionObserverCallback = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { - setActiveId(entry.target.id); + visibleHeadings.set(entry.target.id, entry.boundingClientRect.top); + } else { + visibleHeadings.delete(entry.target.id); } }); + + // Find the topmost visible heading + if (visibleHeadings.size > 0) { + const sortedHeadings = Array.from(visibleHeadings.entries()) + .sort((a, b) => a[1] - b[1]); + setActiveId(sortedHeadings[0][0]); + } else { + setActiveId(null); + } }; + const observer = new IntersectionObserver(callback, { rootMargin: "-40% 0px -55% 0px", threshold: 0.1,