Skip to content
Components
/
Progress
Dark

Progress

Progress shows that work is happening: a spinner when the wait has no end in sight, a bar when it does.

Preview

Two ways to say the app is busy. Spinner when you cannot tell how long, bar when you can. On iOS both are ProgressView, on Android CircularProgressIndicator and LinearProgressIndicator.

Spinner base 24, Progress Bar at 50
both on brand/base over bg/soft-100

The file says 8 steps at 80ms, so a full turn takes 640ms. Here that is one arc on a steps(8) animation, not eight frames swapped by hand. Reduced motion stops it.

Spinner

Four sizes crossed with eight frames, 32 variants. The arc is identical in all of them, only the box changes.

sm 16, md 20, base 24, lg 32
ring is 28 percent of the radius: 2.24, 2.8, 3.36, 4.48
Frame 1 to 8, held still
45 degrees apart, eight of them close the circle

Every frame is two ellipses at the full box, a track and a 270 degree indicator, both at an inner radius of 0.72. The ring scales with the box. The frames exist so the animation can live in Figma. In code you rotate one arc.

Progress Bar

320 by 8, clipping, with an indicator inside it. Five variants set the width, nothing else changes.

Value 0, 25, 50, 75, 100
indicator widths 0.01, 80, 160, 240, 320

Value 0 is not an empty track. The indicator is a real node 0.01 wide, so it rounds to nothing but is still there. Value is a five step axis, not a number, so real progress means overriding the width on the instance rather than picking a variant.

Properties

Two separate sets, three axes between them. No text, no icons, no slots.

Property
Type
Default
Size
sm | md | base | lg, on Spinner
sm
Frame
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8, on Spinner
1
Value
0 | 25 | 50 | 75 | 100, on Progress Bar
0
Set
Variants
Size
Spinner
32, Size crossed with Frame
16, 20, 24, 32 square
Progress Bar
5, on Value
320 x 8

Frame is a timeline, not a state. It exists so the spin can be assembled in Figma. Never expose it: pick a Size, rotate one arc for 640ms, loop. Five stops of Value are enough to design against, never enough to ship. Neither set carries a label, a buffer track or an indeterminate bar.

Tokens

Two colours across both sets. That is the entire palette.

Token
Light
Dark
Applied to
bg/soft-100
#E9E9EA
#48484A
Spinner track ring, bar track
brand/base
#155DFC
#2B7FFF
Spinner arc, bar indicator

In light the track resolves to colors/gray/100, in dark to colors/gray/700, so it lifts off the background in both modes. The brand goes one step lighter in dark. There is no success, warning or error progress here.

Guidelines

Do

Let the spinner promise nothing but that something is happening. Sign in, a network call, a sync with no total: that is exactly the wait it was drawn for.

Don't
68%

Never put a percentage next to the spinner. If you can count it, the bar shows it properly. If you cannot, the number is a guess and people will hold you to it.

One question: do you know the total. Uploads, downloads and multi step forms do, so they get the bar bound to the real number. Everything else gets the spinner. Use the smallest size the surface allows, one on screen at a time. Past a few seconds, say what is taking so long.