Orbit spinner
StableA satellite with a fading tail, circling a faint orbit: Orbit's sign that something is working. It lives inside the thing that is busy, a button or a row, and takes that thing's colour.
Sizes
size is the diameter in pixels, 16 by default. The orbit's stroke grows with it (about a ninth of the size, never thinner than 1.5px), so it reads at every size.
| Size | Where it is used |
|---|---|
| 12 | Extra small buttons. |
| 14 | The command palette, beside "Searching". |
| 15 | Small and medium buttons. |
| 16 | The default: beside a line of text. |
| 18 | Large buttons. |
| 24 to 48 | A panel waiting on something with no known shape. If the shape is known, use a Skeleton. |
Colour
The spinner has no colour of its own: it takes the text colour around it. The satellite and its tail are the full colour, and the orbit is the same colour at 20%. Set color on a parent to change it.
In buttons
A button's loading swaps its leading icon for a spinner in the label's colour, and keeps the comet in orbit around the pill. You do not place the spinner yourself. Press a button to run it.
See Button for how a loading button keeps focus and ignores repeat presses. The command palette shows the same spinner, 14px and teal, beside "Searching" while results load: see Command palette.
Beside text
Sized to the words it sits with, and in their colour, for a status that is running somewhere on the page.
Reduced motion
One lap takes 0.95s, easing a little in and out, and it loops for as long as the wait lasts. When the system asks for reduced motion the satellite stops travelling: it holds at the top of its orbit, and it and its tail breathe, fading gently in and out, so it still says "working" without movement.
In both themes
Sizes, colours and loading buttons, light and dark side by side.
Guidelines
- Use it for actions and short waits. For content with a known shape (a list, a card, a figure), use a Skeleton.
- One spinner per wait. Never a spinner inside a region that is already showing skeletons.
- Say what is happening in the words beside it, in the present tense: "Saving", "Syncing catalogue".
Accessibility
- Without a label the spinner is hidden from assistive tech. That is right inside a button: the button itself is marked busy.
- With
labelit becomes a status (role="status") holding the label as visually hidden text, so screen readers announce it when it appears. Use it for a spinner that stands alone. - Under reduced motion it stops travelling and breathes in place.
Props
These three only: set colour and spacing on a wrapper.
| Prop | Type | Default | Description |
|---|---|---|---|
size | number | 16 | Diameter in pixels. |
label | string | None | Makes the spinner a status that announces this text. Without it, the spinner is hidden from assistive tech. |
className | string | None | Extra class on the outer element. |