You're in the Library

Spinner

An indeterminate activity indicator for short waits and busy controls. For content that is loading into a layout, use Skeleton; for long tasks, use Progress.
Stable
Edit

Preview appears after the next Storybook update.

Spinner example
<Spinner />
Rendered with the real componentFrom the code
Light
Dark

When to use

Use it for

  • Inside a control that is working: Button and IconButton show it automatically with loading.
  • Small regions that refresh in place, for waits up to a few seconds.
  • tone signal when it stands alone, current when it sits in text or a control.

Not for

  • First load of a list or a page: use Skeleton in the shape of the content.
  • Tasks with measurable progress or that take longer than a few seconds: use Progress.

Do and don't

Every example is rendered with the real component, so it always matches what ships.

Do

Name what is loading

A standalone spinner needs a label so screen readers hear "Loading tokens".

Don't

A spinner in the middle of an empty page

It hides the layout and makes the wait feel longer. Show the frame and use skeletons.

Accessibility

  • With label it renders role="status" and is announced; without label it is aria-hidden (use it inside a control that sets aria-busy).
  • Under reduced motion it keeps turning, slower: a frozen spinner looks like a crash.
  • The arc is drawn in currentColor or the signal color, which keeps 3:1 against surfaces.

Content guidelines

  • Labels name the content: "Loading tokens", "Checking contrast". Never just "Loading...".

From the code Generated from the component, not editable here.

Anatomy and tokens

Read from packages/react/src/components/Spinner/Spinner.module.css at build time. Every value is a token: open one to see its alias chain in both themes.

6 tokens6 semantic or component, change with theme and brand0 from the shared scales

Motion and interaction

Spinner loops while it is shown. Try it in the preview at the top.

WhenWhat changesDurationEasing
While shownLoops (spin)motion.duration.spin700 msPart of the loop

With reduced motion turned on, the spinner keeps turning, slower, so it never looks frozen.

From the code Generated from the component, not editable here.

Props

Parsed from the TypeScript types in packages/react/src/components/Spinner/Spinner.tsx, so this table cannot drift from the code. It also accepts every native <span> attribute.

PropTypeDefaultDescription
size'xs' | 'sm' | 'md' | 'lg''sm'Token size: xs 12, sm 16, md 20, lg 24. Default `sm`.
tone'current' | 'signal''current'`current` inherits the text color (inside buttons); `signal` uses the signal color. Default `current`.
labelstringnoneAccessible label announced as a status, for example "Loading tokens". Omit when the spinner sits inside a control that already exposes aria-busy: it is then hidden from assistive tech.

Playground

Change the props and see the real Spinner update. Controls are generated from the TypeScript props; nothing here changes the system.

Code for these props
<Spinner
  size="md"
  tone="signal"
  label="Loading tokens"
/>

size

tone

Workbench

For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Spinner in Storybook).

Embed Storybook stories here (2)

Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay empty.

Default

AllStates

From the code Generated from the component, not editable here.

Changelog

  • New

    Feedback: Alert (five tones, actions, dismiss, correct live region), Toast (ToastProvider and useToast with success, error, warning, info, promise, update and close), Progress (linear and circular, determinate and indeterminate), Skeleton, EmptyState, plus Spinner stories and guidance

    v1.0.0, Nov 11, 2026

All release notes