Reading Progress
A pinned bar that tracks how far through the page, or a chosen element, the reader is.
The bar is live at the very top of this page. Scroll and it fills.
Installation
npx shadcn@latest add @loomui/reading-progressNo keyframes to add. The bar is driven by a passive scroll listener.
Usage
import { ReadingProgress } from "@/components/ui/reading-progress"<ReadingProgress />Measure one article rather than the whole document by passing a ref:
const article = React.useRef<HTMLElement>(null)
return (
<>
<ReadingProgress target={article} />
<article ref={article}>{/* ... */}</article>
</>
)The bar scales on the x axis from its left edge, so nothing about it touches
layout. There is no transition on it at all. Scrolling is the highest-frequency input a
page has, and a bar that eases toward the scroll position just reads as lag.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
position | "top" | "bottom" | "top" | Which edge the bar pins to. |
thickness | number | 2 | Bar thickness in pixels. |
target | RefObject<HTMLElement | null> | none | Measure this element, not the document. |
disabled | boolean | false | Render nothing. |
className | string | none | Merged onto the track. Colour goes here. |
Any other <div> prop is forwarded.
Accessibility
The bar is aria-hidden and pointer-events-none. It duplicates what the
scrollbar already conveys, and a progressbar role whose aria-valuenow
cannot update on every frame announces worse than nothing. There is also
nothing to disable for reduced motion, because nothing is animated: the bar
follows the scroll position exactly.