Spinner
The one loading glyph in the system. It takes its size from whatever holds it and its color from the text around it, and it is announced once, never twice.
Installation#
Usage#
import { Spinner } from "@/components/ui/spinner"
export function Example() {
return <Spinner />
}Follows its host#
With no size, the spinner carries no size class, so the component holding it decides: 16px in a Button or an input, 14px in a Badge, the same box every other icon in that slot gets. Outside any host it is 1em, so it scales with the text beside it.
Sizes#
Pin a size when there is no host rule to follow: sm 14px, md 16px, lg 20px, and xl 40px for an overlay such as a video buffering or a panel loading.
Color#
The ring is currentColor, so it is whatever text color it sits in. Set it with a text utility, never a fill.
Accessibility#
On its own the spinner is a status named “Loading”; give it a precise name with label. When the element around it already says it is busy (a Button with loading, a row that reads “Loading more results”), pass aria-hidden: the role and the name are dropped, so the state is announced once. Under reduced motion the ring stops turning and stays on screen, which still reads as in progress.
API reference#
size:sm|md|lg|xl. Omit it to let the host size the glyph.label: the accessible name while announced. Defaults to “Loading”.aria-hidden: silences the spinner when its host already announces the busy state.- Every other prop (
className, SVG attributes) passes through to the PhosphorCircleNotchglyph it renders, withclassNamemerged last.