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
Centerwhen it fills a whole area of the screen. - With
childrenit wraps a block: it leaves it gray and inert, with the spinner on top, as long asspinningstaystrue. delay(in milliseconds) so that it does not appear on short loads: a spinner that appears and disappears in an instant flickers.visibleLabelwrites the name next to it.
When not to
- While a whole list or record loads,
Skeletonalmost 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:
Buttonalready bringsloading.
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
<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.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | What 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. |
children | ReactNode | A block that turns grey with the spinner on top while it loads. Without it, it is the plain spinner as always. |
className | string | Merged with the library classes; it does not replace them. |
delay | number | Milliseconds 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" | — |
spinning | boolean | Only with `children`: whether the block is loading right now. By default, yes. |
tone | "neutral" | "accent" | "secondary" | "tertiary" | "info" | "success" | "warning" | "error" | — |
visibleLabel | boolean | Shows 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.
| Variable | Default |
|---|---|
--amset-spinner-size | 1.25rem |
--amset-spinner-thickness | 2px |
--amset-spinner-color | var(--amset-accent-text) |
--amset-spinner-track | var(--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:
