Spinner
Indicate an action running in the background. Unlike the loading dots, this should generally be used to indicate loading feedback in response to a user action, like for buttons, pagination, etc.
Best Practices
When to use
- Use a Spinner for indeterminate, single-action waits of roughly one to three seconds: submit buttons, inline icon refresh, row-level retries.
- For submit buttons, set the
loadingprop on Button so the spinner, sizing, and busy state stay aligned; don’t hand-roll a Spinner inside a button. - Pick Skeleton when async data fills a known layout, LoadingDots for inline copy, and Progress when total work is known.
Behavior
- Mount the Spinner only after the action starts. Pre-rendering and toggling visibility leaves a partial rotation visible at idle and reads as jank.
- Pair any wait longer than ~1s with copy that names the work (
Verifying…,Deploying…) so the user knows what’s blocking. - Match the Spinner size to the surrounding type or icon size, not the parent container.
Accessibility
- Set
aria-busy="true"on the element wrapping the in-flight action so screen readers announce the state change. - Keep the trigger focusable while loading; swapping it for a separate spinner element loses keyboard focus.
- Honor
prefers-reduced-motionand skip stacking extra animation around the Spinner.
Was this helpful?