'use client';
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
import React, { startTransition, useCallback, useEffect, useOptimistic, useRef } from 'react';
/**
 * Route transitions are useful in showing immediate visual feedback to the user when navigating between pages. This is especially useful on slow networks when navigating to data heavy or process intensive pages.
 * To use route transitions, place the `RouteTransitionProvider` at the root of your application, outside of the `ProgressBar` component.
 * To trigger a route transition, use the `Link` component from `@payloadcms/ui`,
 * or wrap a callback function with the `startRouteTransition` method.
 * To gain access to the `RouteTransitionContext`, call the `useRouteTransition` hook in your component.
 * @returns A context provider with methods and state for transitioning between routes, including `isTransitioning`, `startRouteTransition`, and `transitionProgress`.
 * @example
 * import { RouteTransitionProvider, ProgressBar, Link } from '@payloadcms/ui'
 * const App = () => (
 *  <RouteTransitionProvider>
 *   <ProgressBar />
 *   <Link href="/somewhere">Go Somewhere</Link>
 *  </RouteTransitionProvider>
 * )
 */ export const RouteTransitionProvider = ({ children })=>{
    const [isTransitioning, setIsTransitioning] = useOptimistic(false);
    const [transitionProgress, setTransitionProgress] = React.useState(0);
    const transitionProgressRef = useRef(transitionProgress);
    const timerID = useRef(null);
    const initiateProgress = useCallback(()=>{
        timerID.current = setInterval(()=>{
            // randomly update progress using an exponential curve
            // cap the progress to ensure it never fully reaches completion
            // accelerate quickly then decelerate slowly
            const maxProgress = 0.93;
            const jumpFactor = 0.2;
            // lower to reduce jumps in progress
            const growthFactor = 0.75;
            // adjust to control acceleration
            const slowdownFactor = 0.75;
            // adjust to control deceleration
            const newProgress = transitionProgressRef.current + (maxProgress - transitionProgressRef.current) * Math.random() * jumpFactor * Math.pow(Math.log(1 + (1 - transitionProgressRef.current) * growthFactor), slowdownFactor);
            setTransitionProgress(newProgress);
            transitionProgressRef.current = newProgress;
        }, 250);
    }, // every n ms, update progress
    []);
    useEffect(()=>{
        setTransitionProgress(0);
        transitionProgressRef.current = 0;
        if (isTransitioning) {
            initiateProgress();
        } else {
            if (timerID.current) {
                clearInterval(timerID.current);
            }
        }
    }, [
        isTransitioning,
        initiateProgress
    ]);
    const startRouteTransition = useCallback((callback)=>{
        startTransition(()=>{
            setIsTransitioning(true);
            if (typeof callback === 'function') {
                callback();
            }
        });
    }, [
        setIsTransitioning
    ]);
    return /*#__PURE__*/ _jsxDEV(RouteTransitionContext, {
        value: {
            isTransitioning,
            startRouteTransition,
            transitionProgress
        },
        children: children
    }, void 0, false, {
        fileName: "src/providers/RouteTransition/index.tsx",
        lineNumber: 77,
        columnNumber: 5
    }, this);
};
const RouteTransitionContext = /*#__PURE__*/ React.createContext({
    isTransitioning: false,
    // Default implementation: just call the callback directly (no transition animation)
    startRouteTransition: (callback)=>{
        if (typeof callback === 'function') {
            callback();
        }
    },
    transitionProgress: 0
});
/**
 * Use this hook to access the `RouteTransitionContext` provided by the `RouteTransitionProvider`.
 * To start a transition, fire the `startRouteTransition` method with a provided callback to run while the transition takes place.
 * @returns The `RouteTransitionContext` needed for transitioning between routes, including `isTransitioning`, `startRouteTransition`, and `transitionProgress`.
 * @example
 * 'use client'
 * import React, { useCallback } from 'react'
 * import { useTransition } from '@payloadcms/ui'
 * import { useRouter } from 'next/navigation'
 *
 * const MyComponent: React.FC = () => {
 *   const router = useRouter()
 *   const { startRouteTransition } = useRouteTransition()
 *
 *   const redirectSomewhere = useCallback(() => {
 *     startRouteTransition(() => router.push('/somewhere'))
 *   }, [startRouteTransition, router])
 *
 *   // ...
 * }
 */ export const useRouteTransition = ()=>React.use(RouteTransitionContext);

//# sourceMappingURL=index.js.map