35 lines
1019 B
TypeScript
35 lines
1019 B
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
import { motion, useSpring } from 'motion/react'
|
|
|
|
export default function ProgressBar() {
|
|
const [progress, setProgress] = useState(0)
|
|
|
|
useEffect(() => {
|
|
const update = () => {
|
|
const { scrollTop, scrollHeight, clientHeight } = document.documentElement
|
|
const max = scrollHeight - clientHeight
|
|
const p = max > 0 ? scrollTop / max : 0
|
|
setProgress(Math.min(1, Math.max(0, p)))
|
|
}
|
|
update()
|
|
window.addEventListener('scroll', update, { passive: true })
|
|
window.addEventListener('resize', update)
|
|
return () => {
|
|
window.removeEventListener('scroll', update)
|
|
window.removeEventListener('resize', update)
|
|
}
|
|
}, [])
|
|
|
|
const smooth = useSpring(progress, { stiffness: 140, damping: 24, mass: 0.2 })
|
|
|
|
return (
|
|
<motion.div
|
|
className="fixed left-0 top-0 z-40 h-0.5 origin-left bg-neutral-900 dark:bg-neutral-100"
|
|
style={{ scaleX: smooth, width: '100%' }}
|
|
aria-hidden="true"
|
|
/>
|
|
)
|
|
}
|