next.js/test/e2e/app-dir/gesture-transitions/app/layout.tsx
layout.tsx71 lines2.1 KB
'use client'

import { ReactNode, startTransition } from 'react'
import { useRouter, usePathname } from 'next/navigation'
import Link from 'next/link'

const pendingResolvers = new Set<() => void>()

export default function Root({ children }: { children: ReactNode }) {
  const router = useRouter()
  const pathname = usePathname()
  const isOnHomePage = pathname === '/'

  const startGesture = (href: string) => {
    // NOTE: In a real scenario, this would be startGestureTransition,
    // not startTransition.
    startTransition(async () => {
      // Call gesture push to show prefetched content immediately
      ;(router as any).experimental_gesturePush(href)

      // Create a promise that won't resolve until the "end gesture" button
      // is clicked. This simulates a gesture that takes time to complete.
      await new Promise<void>((resolve) => {
        pendingResolvers.add(resolve)
      })

      // After the gesture ends, perform the canonical navigation
      router.push(href)
    })
  }

  const endGesture = () => {
    // Resolve all pending gestures
    for (const resolve of pendingResolvers) {
      resolve()
    }
    pendingResolvers.clear()
  }

  return (
    <html>
      <body>
        <header>
          <h1>Gesture Transitions Test</h1>
          <p>
            This test simulates a gesture transition using two buttons. "Start
            Gesture" calls <code>experimental_gesturePush</code> and begins an
            async transition that doesn't complete until "End Gesture" is
            clicked. This allows observing the intermediate gesture state before
            the canonical navigation completes.
          </p>
        </header>
        <nav>
          <Link href="/target-page">Link to target</Link>
          <button
            data-testid="start-gesture"
            onClick={() => startGesture('/target-page')}
            disabled={!isOnHomePage}
          >
            Start Gesture
          </button>
          <button data-testid="end-gesture" onClick={endGesture}>
            End Gesture
          </button>
        </nav>
        <main>{children}</main>
      </body>
    </html>
  )
}
Quest for Codev2.0.0
/
SIGN IN