Spinner
An animated indicator for an indeterminate loading state.
@garn/ui/spinnerDefault
The default spinner.
Sizing
Glyph size 14/16/20/24/32px — identity (mirrors the button icon ramp).
xssmmdlgxlLabeled
Override the default aria-label.
Installation
garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.
npx garn-ui add spinner- Registry
spinner- Source
- spinner.tsx
- Deps
class-variance-authoritylucide-react- Registry deps
utils
Import
import { Spinner } from "@garn/ui/spinner";Props
Generated from the component's TypeScript types.
size- Description
- No description.
- Type
"lg" | "md" | "sm" | "xl" | "xs"- Default
md
Plus 489 inherited native <svg> attributes.
Styling
Target these data-slots and remap these tokens to restyle without forking the component.
[data-slot="spinner"]Overview
Spinner indicates an indeterminate loading or pending state — inline, beside a label, or inside a control — when you can't report a percentage. Its size follows the same glyph ramp as button icons so it sits cleanly within text and buttons. Use it for short, unknown-duration waits; for a known fraction use Progress, and to reserve a known content shape use a Skeleton.
Guidelines
Use a spinner when duration is unknown and brief. It says "working" without a number; if you can show real progress, a determinate bar is more reassuring, and for laying out incoming content a Skeleton prevents the jump.
Show it in context and accompany long waits. Put the spinner where the result will appear (in the button, beside the row) rather than blanking the whole screen; past a couple of seconds, add a word of context so users aren't left guessing.
Announce loading and respect motion. Give the loading region an accessible "loading" state (e.g. aria-busy/label) so it's not a silent spin, and honor reduced-motion. Don't leave a spinner running forever — resolve to content, empty, or an error.
Best practices
- Give it an accessible name describing what's loading.
- Match the size to the surrounding control.
- Don't block the whole UI with a bare spinner where a skeleton would preserve layout.
Content guidelines
- Give it an accessible name that says what's loading (“Loading results”), not just “Loading”.
- When it sits beside visible text, let that text carry the message and keep the label concise.
Accessibility
- Role
status
- • role=status with a default aria-label of “Loading”.
- • Override aria-label to describe the specific action (e.g. “Saving changes”).
- • Animation is paused under prefers-reduced-motion (library-wide guard).
- Status
- Stable
- Version
v0.3.0- Introduced
v0.1.0
garn doesn't yet record a per-release version history. This reflects the component's current lifecycle state; full changelog entries will appear once the metadata pipeline emits a lifecycle.history field.