Skip to content
EspañolEnglish
All components (204)

Spinner

Status · Spinner · .amset-spinner

What it is and when to use it

A loading spinner, for what takes a while and it is not known how long.

When to use it

  • When there is no percentage. If it is known how much is left, use Progress, which says so.
  • Inside a Center when it fills a whole area of the screen.
  • With children it wraps a block: it leaves it gray and inert, with the spinner on top, as long as spinning stays true.
  • delay (in milliseconds) so that it does not appear on short loads: a spinner that appears and disappears in an instant flickers. visibleLabel writes the name next to it.

When not to

  • While a whole list or record loads, Skeleton almost always looks better: it shows the shape of what is coming instead of a spinning dot.
  • Inside a button that submits it is not needed: Button already brings loading.

Keyboard: it does not take part.

Accessibility: label is required, and not for formality - a spinner without a name is, for whoever cannot see it, a screen that does nothing. It is a real indeterminate progressbar, not a <div> that spins, so the reader announces it as busy. With reduced motion it does NOT stop: it only goes slower (2.4 s per turn), because a stopped spinner is a broken spinner.

Fine-tuning: --amset-spinner-size, --amset-spinner-thickness, --amset-spinner-color and --amset-spinner-track.

What it looks like

Loading orders

<Spinner label="Loading orders" visibleLabel />
<Spinner label="Loading" size="lg" tone="accent" />

Props

Import it with import { Spinner } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
labelrequiredstringWhat is being loaded: "Loading orders". Required, and not as a formality: a spinner without a name is, for whoever cannot see it, a page that does nothing.
childrenReactNodeA block that turns grey with the spinner on top while it loads. Without it, it is the plain spinner as always.
classNamestringMerged with the library classes; it does not replace them.
delaynumberMilliseconds that must pass before it appears. A 120 ms load with a spinner that shows up and leaves is worse than no spinner: it flickers. With 200 or 300 you only see what really takes time.
size"sm" | "md" | "lg" | "xs" | "xl"—
spinningbooleanOnly with `children`: whether the block is loading right now. By default, yes.
tone"neutral" | "accent" | "secondary" | "tertiary" | "info" | "success" | "warning" | "error"—
visibleLabelbooleanShows the text beside the spinner. By default it is hidden from view (never from the reader) because the context almost always says it already.

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

CSS variables

These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.

VariableDefault
--amset-spinner-size1.25rem
--amset-spinner-thickness2px
--amset-spinner-colorvar(--amset-accent-text)
--amset-spinner-trackvar(--amset-border)

How to change it

.amset-spinner {
  --amset-spinner-size: ...;
  --amset-spinner-thickness: ...;
}

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: