Skip to content

Feedback

Spinner

The one “working” indicator — a ring, never a shimmer.

When to reach for it

A wait short enough that the shape of what is coming does not matter. Longer than that, use a Skeleton.

Examples

sizes

Loading, smallLoading, mediumLoading, large

on a filled ground

Indexing 1,204 frames

Notes

The system's one "working" indicator.

A ring, not a blurred glow and not a shimmer: the White Reset has no light source, so depth and softness are not available to it. The leading quarter is the only thing that distinguishes the ring from a plain circle, which is why the track stays a hairline — a spinner is a hint that time is passing, not a feature of the page.

It spins under motion-safe only. A reader who has asked for less motion gets a static ring, which still reads as "not finished" because the leading quarter is darker than the track.

For a wait long enough that the reader would otherwise wonder whether the page is broken, prefer Skeleton — a shape that describes what is coming beats a dot that describes nothing.

Props

Spinner props
PropTypeDefaultDescription
labelstring | null'Loading'Announced to assistive tech. Pass the specific thing being waited on ("Loading projects"), not the generic word — a screen reader user hearing "Loading" three times cannot tell which three things. Pass `null` for a spinner that sits inside a control which already names the operation (a button whose own label changes to "Saving…"), so the two are not read out twice.
size'sm' | 'md' | 'lg''md'14px / 18px / 26px. Match the size of the type it sits beside.
tone'default' | 'current''default'`default` draws the ring against the page — a hairline track in the rule colour with the leading quarter in ink. `current` draws it in the inherited text colour, which is what a spinner inside a filled button needs: on an ink ground an ink ring is invisible.

Also accepts everything in HTMLAttributes<HTMLSpanElement>. Those are forwarded to the underlying element and are not listed row by row.

Accessibility

  • label names the specific thing being waited on; three spinners all saying “Loading” tell a screen reader nothing.
  • label={null} silences it for use inside a control that already announces the operation.
  • Spins under motion-safe only; the static ring still reads as unfinished because the leading quarter is darker.