Spinner
StableAn indeterminate activity indicator for short waits and busy controls. For content that is loading into a layout, use Skeleton; for long tasks, use Progress.
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.
Name what is loading
A standalone spinner needs a label so screen readers hear "Loading tokens".
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.
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.
- Signal tone
.signal - Size xs
.xs - Size sm (default)
.sm - Size md
.md - Size lg
.lg - Rotating drawing
.svg
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.
| Prop | Type | Default | Description |
|---|---|---|---|
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`. |
label | string | none | Accessible 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.
<Spinner
size="md"
tone="signal"
label="Loading tokens"
/>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
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. Adds alert and skeleton component tokens.
Unreleased (current version 0.1.0, no release tagged yet) , Oct 17, 2026