Spinner
An indeterminate ring for a wait with no known length. Sized in text units, so it fits wherever a glyph would.
API
Props
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "span" | the element or component to render |
label? | string | "Loading" | the accessible name of the status |
className? | string | — | merged over the defaults, so it wins |
Examples
Usage
<Spinner />
<Spinner className="size-6 text-primary" />Details
Size and colour
The ring is an inline SVG drawn in currentColor and filling its box, so it takes the colour of the text around it and the size you give the element. The default is size-4, the same square a Button icon occupies, which is what lets a spinner replace an icon without the control changing width.
<Button clickable={!isSaving} onClickBlur={handleSave}>
<Button.IconLabel
icon={<Button.Icon icon={<Swap.Boolean swapOn={isSaving} components={[MdSave, Spinner]} />} />}
label={<Button.Label label={isSaving ? "saving" : "save"} />}
/>
</Button>What it announces
It renders as role="status" with an accessible name, so assistive technology reports it as a live status rather than as a decorative image. Rename it when the page has more than one wait, or when saying what is loading is useful.
<Spinner label="Loading invoices" />Spinner, ProgressBar or NavigationBar
Three components for three different waits. A Spinner belongs where the wait is local and has no length — a button mid-request, a panel fetching its data. A ProgressBar is for a quantity you actually know, a file uploading or a step counter. A NavigationBar is for a page transition, where nothing is measurable but the whole screen is about to change.
The failure mode worth avoiding is a spinner that spins for something you could have measured: an indeterminate animation tells the user only that the app is not dead.