Spinner

Animated loading spinner in three sizes.
iOS
Android
Web
tsx
<Spinner />

Props

Prop
Description
children
ReactNode
Optional label rendered beside (or below) the indicator in the spinner's canonical muted small type. Supplying it turns the bare indicator into a component-owned loading pairing, so the caller never hand-composes a Row/Column + Typography beside a <Spinner />. A bare <Spinner /> (no children) is unchanged.
description
ReactNode
Optional muted secondary line rendered under the label (a progress hint, an ETA). Stacks under the label inside the control.
stacked
boolean
Layout axis for the label. Omitted/false: the label sits BESIDE the indicator in a snug row (the inline pairing). `stacked`: the indicator sits over a centered label column (the panel / section-loader form).
small
boolean
Size (pick one; default sits between small and large).
large
boolean
Size (pick one; default sits between small and large).
primary
boolean
Tone (pick one; default is the foreground arc color).
muted
boolean
Tone (pick one; default is the foreground arc color).
foreground
boolean
Tone (pick one; default is the foreground arc color).
accessibilityLabel
string
Accessible description of what is loading. When absent, a string label (children) becomes the accessible name; when neither is present it defaults to "Loading".
testID
string
E2E hook forwarded to the root element.

Do & Don’t

Label

Don’t
A bare spinner with no label leaves users guessing what is happening and for how long.
Do
Loading…
Pair longer waits with a short label so the spinner has context.

sm

Don’t
The 4×4 spinner is too small to anchor a full panel; alone in open space it reads as a stray dot.
Do
Use the small size inline: inside a button or beside a line of text where its scale matches the type.

default

Don’t
Don't stretch it with conflicting width and height; a spinner must stay a perfect circle to spin cleanly.
Do
Loading…
Keep the default square and centered with a label for small content panels and cards.

lg

Don’t
The 8×8 spinner overflows a small control; cramming the large size into a button breaks its height.
Do
Loading dashboard…
Reserve the large size for section- or page-level loading, centered in the empty content area.