← All @molecule/* packages · App templates
@molecule/app-reading-progress-bar-reactFeature · reading-progress-bar · App (browser) · v1.0.1 · Apache-2.0
Top-of-page scroll progress bar for article pages
npm install @molecule/app-reading-progress-bar-react@molecule/app-reading-progress-bar-react is a ready-made reading-progress-bar feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.
import { useRef } from 'react'
import { ReadingProgressBar } from '@molecule/app-reading-progress-bar-react'
const articleRef = useRef<HTMLElement>(null)
// Pin to top, track a specific article element
<ReadingProgressBar containerRef={articleRef} color="var(--brand)" thickness={4} />
// Simpler: track whole-page scroll
<ReadingProgressBar position="top" />Works with: @molecule/app-react, @molecule/app-ui
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
React reading progress bar.
Exports <ReadingProgressBar> — a thin top-of-page bar that fills as the
user scrolls through an article. Used by blog and news-aggregator
article pages.
import { useRef } from 'react'
import { ReadingProgressBar } from '@molecule/app-reading-progress-bar-react'
const articleRef = useRef<HTMLElement>(null)
// Pin to top, track a specific article element
<ReadingProgressBar containerRef={articleRef} color="var(--brand)" thickness={4} />
// Simpler: track whole-page scroll
<ReadingProgressBar position="top" />
feature
npm install @molecule/app-reading-progress-bar-react @molecule/app-react @molecule/app-ui react
npm install -D @types/react
ReadingProgressBarPropsProps for the {@link ReadingProgressBar} component.
interface ReadingProgressBarProps {
/**
* Optional ref to the article element. When provided, progress is
* measured against that element's bounding rect (so the bar fills as the
* user scrolls through the article body, not the whole page). When
* omitted, progress falls back to `window` scroll position.
*/
containerRef?: RefObject<Element | null>
/** Bar thickness in pixels. Defaults to `3`. */
thickness?: number
/**
* Where the bar pins. Defaults to `'top'`. Both variants render fixed
* across the full viewport width with a high z-index.
*/
position?: 'top' | 'bottom'
/**
* CSS color for the filled portion of the bar. Defaults to
* `'currentColor'` so the bar inherits whatever text color is in scope —
* letting the surrounding theme drive it. Pass an explicit color
* (`'#3b82f6'`, `'var(--brand)'`, etc.) to override.
*/
color?: string
/** Extra classes on the outer wrapper. */
className?: string
/** `data-mol-id` for AI-agent / E2E selectors. */
dataMolId?: string
}
computeArticleProgress(el, viewportHeight)Computes the scroll progress (0..1) of an element, measured by how much of the element has scrolled past the top of the viewport.
Specifically:
0 when the element's top is at or below the viewport top.1 when the element's bottom is at or above the viewport top
plus the viewport height (i.e. the element has been fully read).The same formula works whether the user reads inside window (no
containerRef) or scrolls a fixed element — the bounding rect already
accounts for the layout.
function computeArticleProgress(el: Element, viewportHeight: number): number
el — The article element whose read-through progress we want.viewportHeight — The viewport height to use as the denominator.Returns: A number in [0, 1].
computeWindowProgress()Computes window scroll progress (0..1) using scrollY and the document's
total scrollable height.
function computeWindowProgress(): number
Returns: A number in [0, 1]. Falls back to 0 when there is nothing to scroll (page shorter than the viewport).
ReadingProgressBar(props)Top-of-page reading progress bar.
Tracks how far the user has scrolled through an article and renders a thin horizontal bar pinned to the top (or bottom) of the viewport, filling left-to-right from 0% to 100% as they read.
Throttles scroll updates with requestAnimationFrame so the work runs
at most once per frame — handler attaches in passive mode.
Listens to both scroll and resize because progress changes when the
viewport height changes (e.g. mobile toolbar collapse).
No containerRef → measures window. With containerRef → measures
the element so the bar reflects progress through that specific article
even when the page has additional scrollable content above/below.
function ReadingProgressBar({
containerRef,
thickness = 3,
position = 'top',
color,
className,
dataMolId,
}: ReadingProgressBarProps): ReactElement<unknown, string | JSXElementConstructor<any>>
props — Component props (see {@link ReadingProgressBarProps}).Peer dependencies:
@molecule/app-react ^1.0.1@molecule/app-ui ^1.0.1react ^18.0.0 || ^19.0.0@molecule/app-react@molecule/app-uireactCompanion locale bond: @molecule/app-locales-reading-progress-bar (the
progressbar aria-label). The fill defaults to currentColor — it inherits
the surrounding text color, so pass color (e.g. var(--color-primary))
when the ambient text color is low-contrast against the page edge. The bar
renders position: fixed at z-index: 1000 spanning the viewport width;
it only listens to window scroll — containerRef changes what is
measured, not which scroller is observed (inner scroll containers won't
drive it). Requires the app-react i18n provider and a wired ClassMap bond.
Translation strings are provided by @molecule/app-locales-reading-progress-bar.