Skip to content

Commit 030cf1c

Browse files
Copilotalexr00
andcommitted
Replace IntersectionObserver with scroll-based position detection
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent 863c9f4 commit 030cf1c

File tree

1 file changed

+18
-25
lines changed

1 file changed

+18
-25
lines changed

webviews/editorWebview/overview.tsx

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,49 +32,42 @@ const useMediaQuery = (query: string) => {
3232
export const Overview = (pr: PullRequest) => {
3333
const isSingleColumnLayout = useMediaQuery('(max-width: 768px)');
3434
const titleRef = React.useRef<HTMLDivElement>(null);
35-
const sentinelRef = React.useRef<HTMLDivElement>(null);
3635

3736
React.useEffect(() => {
38-
const sentinel = sentinelRef.current;
3937
const title = titleRef.current;
4038

41-
if (!sentinel || !title) {
39+
if (!title) {
4240
return;
4341
}
4442

4543
// Initially ensure title is not stuck
4644
title.classList.remove('stuck');
4745

48-
// Use IntersectionObserver to detect when the title becomes sticky
49-
// The sentinel is positioned right before the title
50-
// When sentinel scrolls out of view (past the top), title becomes stuck
51-
const observer = new IntersectionObserver(
52-
([entry]) => {
53-
// When sentinel is intersecting (visible), title is NOT stuck
54-
// When sentinel is not intersecting (scrolled past top), title IS stuck
55-
if (entry.isIntersecting) {
56-
title.classList.remove('stuck');
57-
} else {
58-
title.classList.add('stuck');
59-
}
60-
},
61-
{
62-
// Use threshold 1 to only trigger when sentinel is fully visible/invisible
63-
// This prevents false positives when sentinel is partially visible
64-
threshold: [1]
46+
// Use scroll event to detect when title actually becomes sticky
47+
// Check if the title's top position is at the viewport top (sticky position)
48+
const handleScroll = () => {
49+
const rect = title.getBoundingClientRect();
50+
// Title is stuck when its top is at position 0 (sticky top: 0)
51+
// Add small threshold to account for sub-pixel rendering
52+
if (rect.top <= 1) {
53+
title.classList.add('stuck');
54+
} else {
55+
title.classList.remove('stuck');
6556
}
66-
);
57+
};
58+
59+
// Check initial state after a brief delay to ensure layout is settled
60+
const timeoutId = setTimeout(handleScroll, 100);
6761

68-
observer.observe(sentinel);
62+
window.addEventListener('scroll', handleScroll, { passive: true });
6963

7064
return () => {
71-
observer.disconnect();
65+
clearTimeout(timeoutId);
66+
window.removeEventListener('scroll', handleScroll);
7267
};
7368
}, []);
7469

7570
return <>
76-
{/* Sentinel element positioned just before the sticky title */}
77-
<div ref={sentinelRef} style={{ height: '1px' }} />
7871
<div id="title" className="title" ref={titleRef}>
7972
<div className="details">
8073
<Header {...pr} />

0 commit comments

Comments
 (0)