Spinners are animated icons used to indicate a content area's loading state.

Spinner

Usage

  • Use Spinner to indicate a short background process is running and incomplete, such as submitting a form or loading a data set.
  • Reserve Spinner for use cases that expect shorter wait times.
  • Place Spinner within any area that needs a loading state — buttons, modals, panels, and pages — matching the placement to the scope the loading is associated with.
  • Center the Spinner within content areas such as panels or pages until data loads.
  • Place inline Spinners next to the content expected to load, and enable the label when extra context helps.
  • Nest Spinner inside a Blanket to create a loading modal.
  • Use Spinner when the loading area's layout is unknown or unpredictable. Use Skeleton instead to reserve space for data in predictable layouts such as cards or tables. They are not interchangeable.

Appearance

  • Color (color) — sets the spinner icon color from a semantic text color token. Defaults to "base". Values shown in the design doc: "base", "bold", "subtle", "accent", "success", "caution", "critical", "information", "feature", "disabled".
  • Set color="inherit" to have the spinner icon take the currently set text color.
  • Use color only to convey semantic meaning. Never change color to match a color scheme or theme.

Behaviors

  • Reduced motion — when the user's OS enables reduced motion, the rotating animation is automatically replaced with a static dotted circle. No prop controls this; it is handled in CSS via prefers-reduced-motion.

Content

  • Enable label text (shouldShowLoadingText) only when the Spinner has no other surrounding context describing what is in progress.
  • Keep labels to single words or short phrases, especially where content space is limited.
  • Omit the label when context is clear, or when the Spinner sits inside a button or next to another status indicator.

Implementation Notes

  • Spinner extends Box — all Box layout and sprinkle props are available, and the component is polymorphic via as (default "div").
  • Label visibility requires two props together: set shouldShowLoadingText to true and provide a non-empty label. Nothing renders when shouldShowLoadingText is false (default) or label is an empty string.
  • label defaults to "Loading…" when omitted.
  • color styles the spinner icon only. The label renders as Text and inherits the surrounding text color regardless of color.
  • Passing color={null} skips the color class entirely, leaving the icon at currentColor.
  • Spinner has no size prop. Override sizing and animation through the CSS variables exported from spinner.style-exports.ts: spinnerSize, spinnerColor, spinnerWidth, spinnerWidthDotted, spinnerAnimationDuration.
  • React: <Spinner color="accent" shouldShowLoadingText label="Saving…" />.
  • Ember: <PlumaSpinner @color="accent" @shouldShowLoadingText={{true}} @label="Saving…" />.

On this page