Skip to content
microcharts
ReferenceCoreProgress

Progress

React progress chart — elapsed fraction with a percent label, step segments, and honest >100% handling. Tiny accessible SVG microchart; RSC-safe static or /interactive.

encodes
zero-anchored bar length + direct % label
precision
high
nodes
≤ 4 continuous · ≤ 3 + segments

Progress answers "how far along is this, exactly?". The bar gives the instant read; the percent label is the datum — a bare bar is decoration. The track never shrinks for the label (the viewBox widens instead), so fractions stay comparable down a table column.

Progress
interactive · 3.49 kB · static · 2.11 kB

Install

Import & usereact/progress
import { Progress } from "@microcharts/react/progress";<Progress value={0.68} title="Onboarding" />
Needs package + stylesheetSet up with AI

Try it

When to use it

  • Good for — KPI cards, table completion columns, step counts (segments).
  • Avoid for — icon-size slots (ProgressRing) or composition (SegmentedBar).

Sizing

Variants

segments
label modes
burn-down
locale

With label="percent" (the default) the accessible name follows format/locale too — "68 %" under de-DE rather than the English "68%".

Edge cases

over 100%
zero
no denominator (max = 0)

max <= 0 (or a non-finite value/max) renders an empty track with no fill, and the label becomes an em dash ("—") rather than a fabricated number — the accessible name says "No data." instead of computing a meaningless ratio. A value of 0 renders a real, empty-but-present bar (not the no-data state), so "not started" and "unmeasurable" stay visually distinct.

Four homes

Why this default

The percent label is on by default because it is the datum — the bar alone can't say "68%". Past 100% the bar clamps at full but the label carries the true figure ("112%"): the number and the bar only ever disagree in that one documented case, and the number wins. max <= 0 renders an empty track and says "No data." rather than inventing a fraction.

max — not total — is the deliberate exception across the library: every other denominator prop names a discrete count (total on IconArray, TallyMarks, Honeycomb…), but Progress tracks a continuous goal that can be overshot, so it keeps the word that says "ceiling," not "count."

Accessibility

The accessible name is the completion — "68% complete.", or "3 of 5 steps." when segmented, or "32% remaining." with positive="down". The interactive entry re-announces through a polite live region, throttled to whole-percent changes so a streaming value doesn't spam screen readers, and the fill-width transition is gated on reduced motion.

This chart is a single unit, so there is nothing to rove between: a click, tap, Enter or Space selects it and fires onSelect, and no selection stays pinned. That is the scalar half of the shared interaction contract. Hover or focus also reveals the reading itself in a floating chip, for the sizes and label modes where the mark does not print it; readout={false} drops the chip and keeps everything else.

Props

PropTypeNotes
value*numberThe progressed amount.
maxnumberDenominator (default 1).
segmentsnumberDiscrete-chunk track — the chart says step count, not ratio.
label"percent" | "value" | "fraction" | "none"The direct label; percent is the default datum.
positive"up" | "down"down = burn-down wording (summary only; the bar stays factual).
animatebooleaninteractiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion.

Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.

Related charts