Skip to content

Commit 62b058d

Browse files
docs(layout): fix sidebar bounce on short pages by stabilizing scroll/fixed logic
Stabilizes the docs sidebar behavior on pages shorter than the sidebar by making the fixed state update idempotent, simplifying fade logic, and ensuring proper initial state handling. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
1 parent df2eda0 commit 62b058d

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

web/src/app/docs/layout.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ export default function DocsLayout({
2626
// The header with logo is approximately 72px tall (p-4 = 16px top/bottom + content height)
2727
// Fix the sidebar when the user scrolls past the header
2828
const shouldBeFixed = window.scrollY > 72
29-
setIsFixed((prev) => (prev !== shouldBeFixed ? shouldBeFixed : prev))
29+
if (shouldBeFixed !== isFixed) {
30+
setIsFixed(shouldBeFixed)
31+
}
3032
}
3133

3234
window.addEventListener('scroll', handleScroll, { passive: true })
3335
return () => window.removeEventListener('scroll', handleScroll)
34-
}, [])
36+
}, [isFixed])
3537

3638
// Handle sidebar scroll for dynamic fade effects
3739
useEffect(() => {
@@ -43,16 +45,14 @@ export default function DocsLayout({
4345
const isAtTop = scrollTop === 0
4446
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1
4547

46-
setShowTopFade((prev) => (prev !== !isAtTop ? !isAtTop : prev))
47-
setShowBottomFade((prev) => (prev !== !isAtBottom ? !isAtBottom : prev))
48+
setShowTopFade(!isAtTop)
49+
setShowBottomFade(!isAtBottom)
4850
}
4951

50-
// Use requestAnimationFrame to check initial state after layout
51-
requestAnimationFrame(() => {
52-
handleScroll()
53-
})
52+
// Check initial state
53+
handleScroll()
5454

55-
sidebarElement.addEventListener('scroll', handleScroll, { passive: true })
55+
sidebarElement.addEventListener('scroll', handleScroll)
5656
return () => sidebarElement.removeEventListener('scroll', handleScroll)
5757
}, [])
5858

@@ -62,8 +62,8 @@ export default function DocsLayout({
6262
<div className="hidden lg:block w-64 shrink-0">
6363
<div
6464
className={`w-64 z-40 transition-all duration-200 ease-in-out ${
65-
isFixed ? 'fixed top-4 h-[calc(100vh-2rem)]' : 'relative'
66-
}`}
65+
isFixed ? 'fixed top-4' : 'sticky top-4'
66+
} h-[calc(100vh-2rem)]`}
6767
>
6868
{/* Dynamic gradient fade indicators */}
6969
{showTopFade && (

0 commit comments

Comments
 (0)