Progress
Shows how close something is to done, like 3 of 5 steps.
Examples
Vacation fund$640 of $1,000
64%
Shape
- Vacation fund$640 of $1,000
bardefault
- 64%
ring
Sizes
sm
- 64%
mddefault
- 64%
lg
States
- $0 of $1,000
empty
- $640 of $1,000
part
- $1,000 of $1,000
full
Usage
When to use it
Rules
7 rules
- Must
- Pass label naming what is measured, such as "Saved toward Vacation fund". Because a meter with no name is read as a bare number with nothing to say what it measures.
- Must
- Pass valueText for money, such as "$640 of $1,000". Because without it a screen reader hears "64%" and never the amount.
- Must
- Show the figure as text beside a bar or inside a ring. Because the bar renders no text, so a sighted person guesses the amount from the fill length.
- Should
- Pass the real max and value, such as 640 of 1000, not a percentage you worked out.
- Should
- Leave the sm ring empty; 40px has no room for a figure, so put it beside.
- Never
- Use it for a task that is running; it has no indeterminate state. Because it is role meter, so a reader hears a fixed amount while nothing tells them work is moving.
- Never
- Recolor the fill per goal or turn it red past a limit; say over budget in words. Because the fill clamps at max, so a red bar cannot show how far over and fails color-blind readers.
Accessibility
4 checks
- The root is role meter with aria-valuenow, aria-valuemin, aria-valuemax and the label as its name.
- valueText becomes aria-valuetext, so money is read as money.
- The lime fill has an olive edge, 3.95:1 on the page, so the filled part reads on grey.
- The ring and the bar are hidden from assistive tech; the figure inside a ring is read as text too.
Edge cases
6 edge cases
- Over the goal
- The fill stops at full; say how much over in the text.
- Nothing saved
- Only the grey track shows.
- Right to left
- The bar fills from the right; the ring runs the other way.
- Narrow container
- The bar takes the width; the ring keeps its size.
- Value changes
- The fill moves over 200ms, at once under reduced motion.
- max of 0
- It draws empty instead of dividing by zero.
API
6 props
value, maxnumberdefault0, 100labelstringvalueTextstringshape'bar' | 'ring'default'bar'size'sm' | 'md' | 'lg'default'md'childrenReactNode
Tokens
9 tokens
--surface-3- #e6e4df
--accent- #e4f222
--accent-line- #7c8700
--fg- #0f0f0d
--text-sm- 14px
--text-lg- 18px
--text-xs- 12px
--dur-base- 200ms
--ease-out- cubic-bezier(0.16, 1, 0.3, 1)