@@ -16,6 +16,7 @@ import {
1616 useRef ,
1717 useCallback ,
1818 useEffect ,
19+ useLayoutEffect ,
1920 startTransition ,
2021 Suspense ,
2122} from 'react' ;
@@ -117,7 +118,9 @@ function Link({
117118 href,
118119 children,
119120 ...props
120- } : React . AnchorHTMLAttributes < HTMLAnchorElement > ) {
121+ } : React . AnchorHTMLAttributes < HTMLAnchorElement > & {
122+ onNavigate ?: ( ) => void ;
123+ } ) {
121124 return (
122125 < NextLink
123126 href = { `${ href } ` }
@@ -128,11 +131,12 @@ function Link({
128131 ) ;
129132}
130133
131- function NavItem ( { url, isActive, children} : any ) {
134+ function NavItem ( { url, isActive, children, onNavigate } : any ) {
132135 return (
133136 < div className = "flex flex-auto sm:flex-1" >
134137 < Link
135138 href = { url }
139+ onNavigate = { onNavigate }
136140 className = { cn (
137141 'active:scale-95 transition-transform w-full text-center outline-link py-1.5 px-1.5 xs:px-3 sm:px-4 rounded-full capitalize whitespace-nowrap' ,
138142 ! isActive && 'hover:bg-primary/5 hover:dark:bg-primary-dark/5' ,
@@ -169,14 +173,21 @@ export default function TopNav({
169173 const [ showSearch , setShowSearch ] = useState ( false ) ;
170174 const [ isScrolled , setIsScrolled ] = useState ( false ) ;
171175 const scrollParentRef = useRef < HTMLDivElement > ( null ) ;
176+ const closeMenu = useCallback ( ( ) => setOpenMenuPath ( null ) , [ ] ) ;
172177 // Deriving from the path hides the menu as soon as a navigation commits.
173178 // Forget the path afterwards, so going Back doesn't reopen the menu.
174179 if ( openMenuPath !== null && openMenuPath !== asPath ) {
175- setOpenMenuPath ( null ) ;
180+ closeMenu ( ) ;
176181 }
177182 const isMenuOpen = openMenuPath === asPath ;
178183 const { breadcrumbs} = getRouteMeta ( asPath , routeTree ) ;
179184
185+ // The mobile menu is transient UI. Reset it when Activity hides this route
186+ // so going Back does not restore the menu in its open state.
187+ useLayoutEffect ( ( ) => {
188+ return ( ) => setOpenMenuPath ( null ) ;
189+ } , [ ] ) ;
190+
180191 // HACK. Fix up the data structures instead.
181192 if ( ( routeTree as any ) . routes . length === 1 ) {
182193 routeTree = ( routeTree as any ) . routes [ 0 ] ;
@@ -417,20 +428,28 @@ export default function TopNav({
417428 { /* No fallback UI so need to be careful not to suspend directly inside. */ }
418429 < Suspense fallback = { null } >
419430 < div className = "ps-3 xs:ps-5 xs:gap-0.5 xs:text-base overflow-x-auto flex flex-row lg:hidden text-base font-bold text-secondary dark:text-secondary-dark" >
420- < NavItem isActive = { section === 'learn' } url = "/learn" >
431+ < NavItem
432+ isActive = { section === 'learn' }
433+ url = "/learn"
434+ onNavigate = { closeMenu } >
421435 Learn
422436 </ NavItem >
423437 < NavItem
424438 isActive = { section === 'reference' }
425- url = "/reference/react" >
439+ url = "/reference/react"
440+ onNavigate = { closeMenu } >
426441 Reference
427442 </ NavItem >
428443 < NavItem
429444 isActive = { section === 'community' }
430- url = "/community" >
445+ url = "/community"
446+ onNavigate = { closeMenu } >
431447 Community
432448 </ NavItem >
433- < NavItem isActive = { section === 'blog' } url = "/blog" >
449+ < NavItem
450+ isActive = { section === 'blog' }
451+ url = "/blog"
452+ onNavigate = { closeMenu } >
434453 Blog
435454 </ NavItem >
436455 </ div >
@@ -445,6 +464,7 @@ export default function TopNav({
445464 routeTree = { routeTree }
446465 breadcrumbs = { breadcrumbs }
447466 isForceExpanded = { isMenuOpen }
467+ onNavigate = { closeMenu }
448468 />
449469 </ Suspense >
450470 < div className = "h-16" />
0 commit comments