How to Use
Loader
Loader displays an animated indicator while content is processing or fetching. It comes in 6 animated variants: ring-inset, ring-clip, ring-outset, pulse, dots-roll, and dots-sweep. Each variant has a unique animation style — ring variants spin a circular arc, dots variants bounce or sweep through circular dots, and pulse animates opacity. Use trackColor to set a semantic color on the track portion of the loader. Loaders are inline elements by default — center them with flexbox for full-page loading states.
Loading State Pattern
The standard pattern: a state variable tracks loading status, a Loader shows while loading is true, and the content renders when data arrives. Use useEffect for data fetching and set loading true before the fetch, false after. For full-page loading, center the Loader with flexbox. For inline loading within buttons or cards, the Loader naturally sits inline.
function DataLoader() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data")
.then((r) => r.json())
.then(setData)
.finally(() => setLoading(false));
}, []);
if (loading) {
return (
<div className="flex items-center justify-center p-12">
<Loader variant="ring-inset" />
</div>
);
}
return <div>{data && <p>Data loaded</p>}</div>;
}Variants
Each variant has a distinct animation intended for different contexts. "ring-inset" spins a ring with a gap — the most standard and widely recognized loading indicator. "ring-clip" shows a clipped circular arc that rotates — cleaner and more minimal than full ring. "ring-outset" the ring appears outside the track — a modern alternative. "pulse" fades the loader in and out — subtle and less distracting for background operations. "dots-roll" animates dots in sequence — compact and suitable for inline use within buttons or text. "dots-sweep" animates all dots in a wave — playful and good for full-page loading.
<div className="flex flex-wrap items-center gap-6">
<Loader variant="ring-inset" />
<Loader variant="ring-clip" />
<Loader variant="ring-outset" />
<Loader variant="pulse" />
<Loader variant="dots-roll" />
<Loader variant="dots-sweep" />
</div>Colored Loaders
The trackColor prop applies a semantic color to the loader's track (the path of the ring or the dots). This is separate from the loader's foreground color (which defaults to the current text color). Use trackColor="primary" to match your brand, trackColor="success" for loading success states, trackColor="danger" for destructive operations, and trackColor="warning" for cautionary operations.
<div className="flex flex-wrap items-center gap-6">
<Loader variant="ring-inset" />
<Loader variant="ring-inset" trackColor="primary" />
<Loader variant="ring-inset" trackColor="success" />
<Loader variant="ring-inset" trackColor="warning" />
<Loader variant="ring-inset" trackColor="danger" />
</div>Accessibility
Loader sets aria-busy="true" on its container to signal ongoing activity. The animation respects prefers-reduced-motion by disabling animation. Use a textual loading indicator alongside the Loader for screen reader users — e.g., add a visually hidden <span>Loading...</span> next to or inside the Loader wrapper. The Loader itself is a decorative element — it should not receive focus.
Props Reference
All available props for Loader. See the full API reference page for interactive playground examples.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "ring-inset" | "ring-clip" | "ring-outset" | "ring-dual" | "pulse" | "dots-roll" | "dots-sweep" | "ring-inset" | Loader animation style. |
| color | "default" | "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "white" | "default" | Loader color. |
| trackColor | "default" | "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "white" | "default" | Track color (for ring variants). |
| indicatorColor | "default" | "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "white" | "default" | Indicator color override. |
Best Practices
- ◆Use ring-inset or ring-clip for standard loading indicators — they are the most universally recognized patterns
- ◆Use dots-roll for compact spaces like inline text or button-adjacent loading states where ring variants feel too large
- ◆Set trackColor to match the semantic context — primary for general loading, danger for destructive operations, success for completion transitions
- ◆Loaders are inline elements by default — center them with flexbox (flex + items-center + justify-center) for full-page loading screens
- ◆Avoid showing loaders for operations that complete in under 300ms to prevent visual flicker; add a minimum delay before showing the loader
- ◆For button loading, use Button's isLoading prop instead of rendering a separate Loader — it handles sizing and positioning automatically