Folio

Components

Spinner

An indeterminate loading indicator for waits of unknown length. A brand arc rotates on a neutral track, spinning continuously until the wait ends.

Smooth by construction. The arc spins with a single linear rotation from 0 to 360 degrees, so the loop closes on itself with no seam or stutter. The arc maps to background-primary and the track to border-default, so both remap in dark mode.

Preview

Processing payment...

Rendered with live Folio tokens. Toggle the theme and the arc and track remap, no dark: classes.

Variants

<Spinner className="size-4" />
<Spinner />
<Spinner className="size-8" />

Three sizes at 16, 24, and 32 pixels. The default is 24; set size-4 or size-8 with className. Stroke weight scales with the diameter.

States

Spinning. The single, perpetual state until the wait resolves.

Saving changes...

Inline beside a label.

Inside a disabled button.

The spinner is indeterminate, so it has one continuous state. Pair it with text or a control to signal what is loading.

API

Prop
Type
Default
Description
className
string
"size-6"
Size and layout overrides on the svg. Use size-4 inline and size-8 for a large wait.
aria-label
string
"Loading"
Accessible label announced to screen readers via role=status.
...props
React.ComponentProps<"svg">
--
Other svg attributes pass through to the lucide Loader2Icon.

Sets role="status" with an aria-label so the wait is announced.

Don't and Do

Don't

Don't reach for a spinner when the final layout is already known. A spinner leaves the reader staring at a blank region and then jolts them with a content shift. Where the shape of the result is predictable, a Skeleton holds the space and reads as calmer.

Do
<Spinner />
<Spinner className="size-4" />   // inline, e.g. in a button
<Spinner className="size-8" />

Use it for waits of unknown length where there is no layout to preview, such as a submit in flight or a background task finishing.

import { Spinner } from "@/components/shadcn/spinner";

export function SavingState() {
  return (
    <div className="flex items-center gap-2 text-description">
      <Spinner className="size-4" />
      Saving changes...
    </div>
  );
}
Folio v1.2 · June 2026