{"version":3,"file":"index.mjs","sources":["../src/index.tsx"],"sourcesContent":["import { useRouter } from 'next/navigation';\nimport Link from 'next/link';\nimport {\n  createContext,\n  memo,\n  startTransition,\n  useContext,\n  useEffect,\n  useOptimistic,\n  useState,\n} from 'react';\n\nfunction easeOutQuad(t: number) {\n  return t * (2 - t);\n}\n\nfunction generateEaseOutArray(length: number) {\n  const result = [];\n  for (let i = 1; i <= length; i++) {\n    const easedValue = Math.round(easeOutQuad(i / (length - 1)) * 100);\n    result.push(easedValue);\n  }\n  return result;\n}\n\nconst Context = createContext<{\n  progress: number;\n  startNewProgress: () => void;\n  optimisticObj: { loading: boolean };\n  stateObj: { showing: boolean };\n}>({\n  progress: 0,\n  startNewProgress: () => {},\n  optimisticObj: { loading: false },\n  stateObj: { showing: false },\n});\n\n/**\n * Internal hook for managing progress state\n * @internal\n */\nexport const useProgress = () => {\n  const [optimisticObj, setOptimisticObj] = useOptimistic({\n    loading: false,\n  });\n  const [stateObj, setStateObj] = useState({\n    showing: false,\n  }); // to show latest status, use obj instead of just boolean\n  const [progress, setProgress] = useState(5);\n\n  useEffect(() => {\n    if (!optimisticObj.loading) {\n      return;\n    }\n\n    setStateObj(() => {\n      return {\n        showing: true,\n      };\n    });\n    setProgress(0);\n  }, [optimisticObj]);\n\n  useEffect(() => {\n    if (optimisticObj.loading || !stateObj.showing) {\n      return;\n    }\n\n    const timeout = setTimeout(() => {\n      setProgress(0);\n      setStateObj((obj) => {\n        return {\n          ...obj,\n          showing: false,\n        };\n      });\n    }, 300);\n\n    return () => {\n      clearTimeout(timeout);\n    };\n  }, [optimisticObj.loading, stateObj.showing]);\n\n  useEffect(() => {\n    if (!stateObj.showing) {\n      return;\n    }\n\n    let index = 0;\n    const arr = generateEaseOutArray(100).map((val) => val * (90 / 100));\n\n    const updateProgress = () => {\n      setProgress((prev) => {\n        if (!optimisticObj.loading) {\n          return 100;\n        }\n\n        const val = arr[index];\n        index++;\n\n        if (!val) {\n          return prev;\n        }\n\n        return val;\n      });\n    };\n\n    const interval = setInterval(updateProgress, 100);\n    updateProgress();\n\n    return () => {\n      clearInterval(interval);\n    };\n  }, [stateObj, optimisticObj.loading]);\n\n  const startNewProgress = () => {\n    setOptimisticObj({\n      loading: true,\n    });\n  };\n\n  return {\n    startNewProgress,\n    progress,\n    optimisticObj,\n    stateObj,\n  };\n};\n\n/**\n * Provider component that manages navigation progress state\n * Wrap your application with this provider to enable navigation progress functionality\n * \n * @example\n * ```tsx\n * <NextNavigationProgressProvider>\n *   <NextNavigationProgressBar />\n *   {children}\n * </NextNavigationProgressProvider>\n * ```\n */\nexport const NextNavigationProgressProvider = ({\n  children,\n}: {\n  children: React.ReactNode;\n}) => {\n  const { progress, startNewProgress, optimisticObj, stateObj } = useProgress();\n\n  return (\n    <Context.Provider\n      value={{ progress, startNewProgress, optimisticObj, stateObj }}\n    >\n      {children}\n    </Context.Provider>\n  );\n};\n\n/**\n * Progress bar component that displays navigation progress\n * Must be used inside NextNavigationProgressProvider\n * \n * @example\n * ```tsx\n * <NextNavigationProgressProvider>\n *   <NextNavigationProgressBar />\n *   {children}\n * </NextNavigationProgressProvider>\n * ```\n */\nexport const NextNavigationProgressBar = () => {\n  const { progress, stateObj } = useContext(Context);\n\n  return (\n    <div\n      style={{\n        display: stateObj.showing ? 'block' : 'none',\n      }}\n    >\n      <div\n        style={{\n          width: stateObj.showing ? `${progress}%` : 0,\n          height: '3px',\n          backgroundColor: '#228be6',\n          transition: stateObj.showing ? 'width 0.3s' : 'none',\n          opacity: stateObj.showing ? 1 : 0,\n        }}\n      ></div>\n    </div>\n  );\n};\n\n/**\n * Hook to access navigation progress state and controls\n * Must be used inside NextNavigationProgressProvider\n * \n * @returns {Object} Progress state and control functions\n * @returns {number} progress - Current progress value (0-100)\n * @returns {Function} startNewProgress - Function to start a new progress animation\n * @returns {Object} optimisticObj - Object containing loading state\n * @returns {Object} stateObj - Object containing visibility state\n * \n * @example\n * ```tsx\n * const { progress, startNewProgress, optimisticObj, stateObj } = useNavigationProgress();\n * ```\n */\nexport const useNavigationProgress = () => {\n  return useContext(Context);\n};\n\n/**\n * Pre-configured Link component that automatically triggers navigation progress\n * Wraps Next.js Link component with progress bar integration\n * \n * @param {React.ReactNode} children - Link content\n * @param {string} className - CSS class name\n * @param {string} href - Destination URL\n * @param {string} [target] - Link target attribute\n * @param {Function} [onClick] - Custom click handler\n * @param {boolean} [prefetch] - Next.js prefetch behavior\n * @param {React.CSSProperties} [style] - Inline styles\n * \n * @example\n * ```tsx\n * <NavigationLink href=\"/about\" className=\"nav-link\">\n *   About Page\n * </NavigationLink>\n * ```\n */\nexport const NavigationLink = memo(function NavigationLink({\n  children,\n  className,\n  href,\n  target,\n  onClick,\n  prefetch,\n  style,\n}: {\n  children: React.ReactNode;\n  className?: string;\n  href: string;\n  onClick?: React.MouseEventHandler<HTMLAnchorElement>;\n  target?: string;\n  prefetch?: boolean;\n  style?: React.CSSProperties;\n}) {\n  const router = useRouter();\n  const { startNewProgress } = useNavigationProgress();\n\n  return (\n    <Link\n      prefetch={prefetch}\n      className={className}\n      href={href}\n      onClick={(e) => {\n        if (onClick) {\n          onClick(e);\n          return;\n        }\n\n        startTransition(async () => {\n          startNewProgress();\n          router.push(href);\n        });\n      }}\n      target={target}\n      style={style}\n    >\n      {children}\n    </Link>\n  );\n});\n"],"names":["_jsx"],"mappings":"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"}