ProgressRing
React progress ring chart — progress from a fixed 12-o'clock start — never a needle gauge. Tiny accessible SVG microchart; RSC-safe static or /interactive.
- encodes
- arc sweep (fixed 12-o'clock start)
- precision
- medium — Progress when the % must read precisely
- nodes
- ≤ 3
ProgressRing answers "how complete is this?" at icon size, where a linear bar doesn't fit. The start angle is fixed at 12 o'clock and the caps are butt-cut — the two quiet ways rings inflate progress, both removed. It is never a gauge: no needle, no red zone.
Install
import { ProgressRing } from "@microcharts/react/progress-ring";<ProgressRing value={0.68} title="Backup" />Try it
When to use it
- Good for — tab headers, KPI card corners, cooldowns and retry timers (
sweep). - Avoid for — precise reads (Progress — the % label is the datum there).
Sizing
Variants
Edge cases
Four homes
Why this default
Butt caps and a fixed start: rounded caps overstate small fractions, and variable start angles make identical fractions look different. Past 100% the ring clamps while the center label carries the true percent — same contract as Progress. A full circle is drawn as two half-arcs (SVG cannot draw a single 360° arc).
Accessibility
The accessible name reuses the progress wording — "68% complete.", or "32% remaining." in sweep mode. The interactive entry announces only at 25/50/75/100% threshold crossings — a streaming value never spams the screen reader.
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
| Prop | Type | Notes |
|---|---|---|
| value* | number | The progressed amount. |
| max | number | Denominator (default 1). |
| sweep | boolean | Countdown: the REMAINING wedge shrinks. |
| weight | number | Ring thickness (viewBox units). |
| label | "none" | "percent" | Centered figure (≥ 20 px rendered). |
| size | number | Ring box edge in viewBox units (default 24). |
| animate | boolean | interactiveOpt-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.