Gauge
A ring. It exists because a rating out of five and a completion out of one hundred are different quantities that people read the same way — as “how full is it” — and a ring answers that faster than a number alone. It is never used without the number in the centre.
Rating gauge
The colour comes from the tier the value falls in, exactly as ScoreBar derives it. It is never passed in as a prop, so a 2.1 cannot be rendered green by a caller who wanted a nicer-looking page.
An unrated event shows the track and a dash. It does not show a zero-length arc — an empty ring reads as a rating of nought, and nought is a score nobody gave. Same rule as the ScoreBar neutral.
Live
Progress gauge
The same geometry showing completion rather than quality. It is --color-primary at every value: a half-finished profile is not a bad profile, and colouring it amber would say it was.
Specification
| Property | Value | Why |
|---|---|---|
| Sizes | sm 40 · md 64 · lg 96 | Below 40 the centred figure stops being legible |
| Stroke | 4 · 6 · 8, by size | Constant ratio, so the ring reads the same at every size |
| Start | 12 o'clock, clockwise | The only starting point people predict |
| Cap | round | A square cap at a low value looks like a rendering error |
| Track | --color-border, full circle | The remainder must be visible or there is no scale |
| Rating colour | Derived from the value's tier | Never a prop — the same rule as ScoreBar |
| Progress colour | --color-primary at all values | Incomplete is not bad |
| Rating role | role="img" + aria-label | It is a picture of one figure, read once |
| Progress role | role="progressbar" + aria-valuenow/min/max | It changes, and the change is the point |
role="meter" would be the literal match for a rating, and we do not use it: support across screen readers is inconsistent enough that the announcement is unreliable. role="img" with a written label says exactly what we mean — “Rating 4.7 out of 5 — excellent” — in every reader.
Rules
- Never a ring alone. The number lives in the centre. An arc without a figure is a decoration that people misread by half a point in either direction.
- Never a partial scale. The ring always represents the full range. Drawing 3.2–5.0 as a full circle is the radial version of a truncated y-axis — see Data visualisation.
- Do not animate on load beyond
--duration-base, and not at all underprefers-reduced-motion. A ring that winds up on every page load is decoration. - Never spin it. A rotating ring is a spinner, and a spinner means “waiting”. If you are waiting, use the skeleton.
- One per view. A grid of rings is a chart, and a radar or bar chart will read better.
- Use ScoreBar for comparison. Rings are hard to compare against each other; bars share a baseline. A ring is for a single headline figure.
React
From @sportingscouter/ui-react. The component adds no visual values of its own — every class comes from the same tv() recipe the design system defines, so the two cannot drift.
import { Gauge } from '@sportingscouter/ui-react';
<Gauge value={62} label="Profile completeness" />
<Gauge value={100} label="Categories rated" tone="success" size="lg" />
<Gauge value={12} label="Reviews needed" tone="warning" size="sm" />
{/* A Gauge measures COMPLETION, which has no quality — so
it never takes a rating hue. A 40%-complete profile in
rating-fair orange reads as a bad review. That is why
this is not a ScoreBar. */}
{/* role="progressbar" with aria-valuenow, not role="img":
the value should be pollable. Below 20px the figure is
dropped rather than truncated. */}
<Gauge value={62} label="Profile completeness" size="xs" />theme.css.