Circular progress
A determinate ring or half ring drawn as an SVG stroke, with the value in the middle.
Last updated
62%
Show codeHide code
<CircularProgress value={62} label="Upload">62%</CircularProgress>Add
npx @ava-ui/apogee add circular-progress
No Apogee dependencies. Zero JS.
Usage
---
import CircularProgress from '@/components/apogee/CircularProgress/CircularProgress.astro'
---
<CircularProgress value={62} label="Upload progress">62%</CircularProgress>
API
@composable — exposed to Content Editors in AVA. Any other native <div>
attribute passes through. The default slot sits in the centre (at the bottom
edge for shape="half").
| Prop | Type | Default | Description |
|---|---|---|---|
value |
number |
0 |
Current value. |
min |
number |
0 |
Lower bound. |
max |
number |
100 |
Upper bound. |
label |
string |
— | Accessible name (aria-label); say what is progressing. |
size |
'small' | 'medium' | 'large' | 'xlarge' |
'medium' |
Ring 32 / 48 / 64 / 96px wide. |
thickness |
'thin' | 'regular' | 'thick' |
'regular' |
Stroke width, relative to the ring. |
color |
'primary' | 'neutral' | 'critical' | 'positive' | 'warning' |
'primary' |
Ring hue. |
shape |
'circle' | 'half' |
'circle' |
A full ring or the top half (a gauge). |
class |
string |
— | Extra classes, appended last. |
Variants
Every shape:
25%
100%
Show codeHide code
<CircularProgress value={25} label="Quarter">25%</CircularProgress>
<CircularProgress value={100} shape="half" label="Complete">100%</CircularProgress>Every size:
40%
40%
40%
Show codeHide code
<CircularProgress value={40} size="small" />
<CircularProgress value={40} size="medium">40%</CircularProgress>
<CircularProgress value={40} size="large">40%</CircularProgress>
<CircularProgress value={40} size="xlarge">40%</CircularProgress>Every thickness and every color:
Show codeHide code
<CircularProgress value={70} thickness="thin" />
<CircularProgress value={70} thickness="regular" />
<CircularProgress value={70} thickness="thick" />
<CircularProgress value={70} color="neutral" /> … critical, positive, warningStates
- Determinate only — the value is always known; for an unknown wait use Spinner.
- Animated — the arc tweens when
valuechanges (--duration-slow), still underprefers-reduced-motiononly through your own override; the stroke is a transition, not a loop.
Examples
A storage gauge:
8.2 / 10 GB
Show codeHide code
<CircularProgress value={8.2} max={10} shape="half" size="xlarge" color="warning" label="Storage used">
8.2 <small>/ 10 GB</small>
</CircularProgress>The text inside is sized to the ring: it never grows past the inner edge and
wraps when it must. Put a unit or a secondary part in <small>; any other
size classes inside are overridden.
Accessibility
role="progressbar"witharia-valuemin,aria-valuemaxandaria-valuenow; give it alabel.- The slot text is visible to everyone; keep it the same number the attributes carry.
- Native semantics, no extra ARIA needed.
Tokens
| Token | Used for |
|---|---|
--background-neutral-faded |
Track |
--background-{hue} |
Fill (through the stroke-{hue} utility) |
--foreground-neutral |
Slot text |
--duration-slow |
Arc transition |
Do / Don’t
- Do show the number in the slot; a ring alone is hard to read past “about half”.
- Do use
halffor a gauge (a quota, a score),circlefor progress. - Don’t use it for a step count; that is Steps or ProgressIndicator.
- Don’t animate from 0 on every render; set the real value server-side.
Content
labelnames the thing measured (“Upload progress”, “Storage used”).- The slot shows the value in the user’s unit (percent, GB, points), short.