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.

Default size

Custom sizes

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 loading prop 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-motion and skip stacking extra animation around the Spinner.