Skip to content

Commit 35ac1d3

Browse files
fix: backdrop stays visible when opening sidebar via hamburger button
1 parent 5c4f528 commit 35ac1d3

1 file changed

Lines changed: 19 additions & 5 deletions

File tree

client/src/components/Layout/Layout.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export default function Layout({ children }: LayoutProps) {
2727
const backdropRef = useRef<HTMLDivElement>(null);
2828
const wasOpen = useRef(false);
2929
const isHorizontalSwipe = useRef<boolean | null>(null);
30+
const backdropHideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
3031

3132
// Close mobile menu on route change
3233
useEffect(() => {
@@ -73,11 +74,19 @@ export default function Layout({ children }: LayoutProps) {
7374
sidebar.style.transform = open ? 'translateX(0)' : `translateX(-${SIDEBAR_WIDTH}px)`;
7475
}
7576
if (backdrop) {
77+
// Clear any pending hide timer
78+
if (backdropHideTimer.current) {
79+
clearTimeout(backdropHideTimer.current);
80+
backdropHideTimer.current = null;
81+
}
7682
backdrop.style.transition = 'opacity 300ms cubic-bezier(0.4, 0, 0.2, 1)';
7783
backdrop.style.opacity = open ? '0.6' : '0';
78-
if (!open) {
79-
setTimeout(() => {
80-
if (backdrop) backdrop.style.display = 'none';
84+
if (open) {
85+
backdrop.style.display = 'block';
86+
} else {
87+
backdropHideTimer.current = setTimeout(() => {
88+
if (backdropRef.current) backdropRef.current.style.display = 'none';
89+
backdropHideTimer.current = null;
8190
}, 300);
8291
}
8392
}
@@ -189,14 +198,19 @@ export default function Layout({ children }: LayoutProps) {
189198
sidebar.style.transform = mobileMenuOpen ? 'translateX(0)' : `translateX(-${SIDEBAR_WIDTH}px)`;
190199

191200
if (backdrop) {
201+
// Clear any pending hide timer
202+
if (backdropHideTimer.current) {
203+
clearTimeout(backdropHideTimer.current);
204+
backdropHideTimer.current = null;
205+
}
192206
backdrop.style.transition = 'opacity 300ms cubic-bezier(0.4, 0, 0.2, 1)';
193207
backdrop.style.opacity = mobileMenuOpen ? '0.6' : '0';
194208
if (mobileMenuOpen) {
195209
backdrop.style.display = 'block';
196210
} else {
197-
// Defer display:none so the fade animation can play
198-
setTimeout(() => {
211+
backdropHideTimer.current = setTimeout(() => {
199212
if (backdropRef.current) backdropRef.current.style.display = 'none';
213+
backdropHideTimer.current = null;
200214
}, 300);
201215
}
202216
}

0 commit comments

Comments
 (0)