Spinner
Shows that something is loading.
Installation
The CLI installs the Radix or Base UI file to match your project.
If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.
When to use
Use it
- Something is loading or running and you can't show its shape, like a search, a save or a refresh.
- A button starts a slow action and should show it's busy.
Usage
Render a Spinner where the content will appear and name it for what's loading. Inside a Button it takes the button's text color: disable the button and keep its label next to the spinner.
import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"<Button disabled>
<Spinner aria-label="Saving" />
Saving
</Button>Examples
Sizes
SLDS's xx-small, x-small, small, medium and large spinners, set with `size-3`, `size-4` (the default), `size-5`, `size-8` and `size-12`.
Colors
The brand spinner with `text-primary`, and the inverse spinner on a dark surface with `text-inverse-foreground`.
API reference
Spinner
Also takes every <svg> (opens in a new tab) prop.
SLDS mapping
Spinner is slds-spinner slds-spinner_inline: six dots that bounce outward in turn. Sizes follow SLDS's widths: size-3 is slds-spinner_xx-small, size-4 is _x-small, size-5 is _small, size-8 is _medium and size-12 is _large, as the Sizes example shows. className="text-primary" is slds-spinner_brand, and text-inverse-foreground is slds-spinner_inverse, as the Colors example shows.
Known gaps:
- SLDS's spinner container (
slds-spinner_container), the overlay that covers a region while it loads, isn't part of the spinner. Build it with a positioneddivif you need it. - SLDS's delayed spinner (
slds-spinner_delayed) isn't a prop. Render the spinner after 300ms instead. - SLDS's inline spinner centers its dots on the top edge of its box. This one centers them in the box.
- In Lightning Blue,
text-primaryis a little darker than SLDS's brand spinner.
Accessibility
- The spinner is a
role="status"named "Loading". Name it for what's loading witharia-label, like "Loading contacts". - Inside a button, keep the button's own text, like "Saving". It names the action; the spinner's label names the wait.
Motion
- The dots bounce outward in turn, once a second, in every theme.
- With reduced motion the dots hold still. The spinner's name still says something is loading.
Responsive behavior
- The spinner keeps its size in a flex row. Set it with
size-*classes, notwidthandheight. - The dots spill out of the box. Together they're about a quarter wider than it at rest, and half again as wide at the top of a bounce. Keep that much space free around it, more so for large spinners.
Rules
- Use only the gray default,
text-primaryfor the brand spinner andtext-inverse-foregroundon dark surfaces. - Don't add
animate-spin. The spinner has its own motion.