@@ -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