'use client' import { useEffect, useState } from 'react' /** * Thin reading progress bar. Tracks the nearest scrollable ancestor * (public layout uses a fixed-height overflow container, not window). */ export function ReadingProgress({ accent = '#A47148' }: { accent?: string }) { const [progress, setProgress] = useState(0) useEffect(() => { const findScrollRoot = (): HTMLElement | Window => { let el: HTMLElement | null = document.querySelector('[data-pub-root]') as HTMLElement | null while (el) { const { overflowY } = getComputedStyle(el) if (overflowY === 'auto' || overflowY === 'scroll') return el el = el.parentElement } return window } const root = findScrollRoot() const update = () => { let scrollTop: number let scrollHeight: number let clientHeight: number if (root === window) { scrollTop = window.scrollY scrollHeight = document.documentElement.scrollHeight clientHeight = window.innerHeight } else { const node = root as HTMLElement scrollTop = node.scrollTop scrollHeight = node.scrollHeight clientHeight = node.clientHeight } const max = Math.max(1, scrollHeight - clientHeight) setProgress(Math.min(100, Math.max(0, (scrollTop / max) * 100))) } update() root.addEventListener('scroll', update, { passive: true }) window.addEventListener('resize', update, { passive: true }) return () => { root.removeEventListener('scroll', update) window.removeEventListener('resize', update) } }, []) return (
) }