Azalea

Spinner

Something is happening and there is nothing to show yet.

Reach for Skeleton first

When you know the shape of what is coming — a list of rows, a card — a placeholder that matches the layout stops the page jumping when the content lands. A spinner is for when you genuinely do not know: a form submitting, a check running, a connection being tested.

LoadingLoadingLoading

Skeleton, for comparison

Sized to the content it replaces, so the page does not jump. A skeleton of the wrong height is worse than a spinner, because it promises a layout and then breaks it.

In both themes

light

LoadingLoading

dark

LoadingLoading

Guidance

Use it when

  • An action in flight whose duration is unknown.
  • A label saying what is loading, whenever a page can have more than one.
  • Button's own loading prop when the wait belongs to a button — it disables and spins in one.

Reach for something else when

  • A known proportion. That is Progress, and a spinner throws away information you have.
  • A whole page. A screenful of nothing with a spinner in the middle tells the reader less than a skeleton of what is coming.
  • Anything under about 300ms. A spinner that flashes reads as a glitch.

Props

PropTypeDefaultDescription
labelstring"Loading"Announced, not drawn. Say what is loading when the page has more than one.
size"sm" | "default" | "lg""default"Glyph size.

Accessibility

role="status" with the label in an sr-only span and the glyph aria-hidden. Without the label a spinner is a silent animation — a blind user gets no signal at all that the page is busy, which is precisely the group that most needs telling. The rotation is safe under prefers-reduced-motion because tokens.css neutralises animation globally, so it becomes a static glyph rather than something each component has to remember.