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.

Syncing

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add spinner

Usage#

usage.tsxTSX
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.

Syncing

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.

Loading more results

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 Phosphor CircleNotch glyph it renders, with className merged last.

FAQ#

Use a Skeleton when you know the shape of what is coming (a card, a table row) and want the layout to hold still while it loads. Use a Spinner for an action in flight whose result has no shape yet: a save, a search, an upload.