Spinner
An animated loading spinner with Framer Motion rotation, multiple sizes and color variants, optional label text, and reduced-motion support.
Overview
The Spinner component provides an animated loading indicator for communicating in-progress states. It uses Framer Motion for smooth, GPU-accelerated rotation with automatic prefers-reduced-motion support. Includes 4 sizes, 4 color variants, optional label text, and proper role="status" semantics.
Installation
Install the component via the CLI in one command.
npx @work-rjkashyap/unified-ui add spinnerpnpm dlx @work-rjkashyap/unified-ui add spinnernpx @work-rjkashyap/unified-ui add spinnerbunx @work-rjkashyap/unified-ui add spinnerIf you haven't initialized your project yet, run npx @work-rjkashyap/unified-ui init first. See the CLI docs for details.
Or install the full package
Use this approach if you prefer to install the entire design system as a dependency instead of copying individual components.
npm install @work-rjkashyap/unified-uipnpm add @work-rjkashyap/unified-uiyarn add @work-rjkashyap/unified-uibun add @work-rjkashyap/unified-uiAnatomy
import { Spinner } from "@work-rjkashyap/unified-ui";Examples
Basic Usage
Sizes
| Size | Diameter | Use Case |
|---|---|---|
xs | 14px | Inside buttons, badges, inline text |
sm | 16px | Table cells, small buttons, compact UI |
md | 20px | Default loading state |
lg | 24px | Empty states, page loading, hero areas |
Variants
With Label
Label Position
In Context
Custom Stroke Width
Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | "xs" | "sm" | "md" | "lg" | "md" | Size of the spinner. |
variant | "default" | "primary" | "secondary" | "muted" | "default" | Color variant. |
label | ReactNode | — | Visible label text alongside the spinner. |
labelPosition | "right" | "bottom" | "right" | Position of the label relative to the spinner. |
strokeWidth | number | 2.5 | Thickness of the spinner stroke. |
aria-label | string | "Loading" | Accessible label for screen readers. |
className | string | — | Additional CSS classes for the root element. |
Accessibility
The Spinner includes a screen-reader-only fallback text that announces the loading state even when no visible label is present.
role="status"— Announces the loading state as a live region to screen readers.aria-label— Defaults to "Loading" or thelabelprop if it's a string.- Screen-reader text — When no visible
labelis provided, a visually hidden<span className="sr-only">is rendered for screen readers. - SVG is decorative — The spinner SVG uses
aria-hidden="true"since the status text conveys meaning. - Reduced motion — Automatically detects
prefers-reduced-motionvia Framer Motion'suseReducedMotionhook and falls back to CSSanimate-spinwhich the browser can optimize or skip per OS settings.
Design Tokens
| Token | Usage |
|---|---|
--primary | Primary variant spinner color |
--foreground | Secondary variant spinner color |
--muted-foreground | Muted variant spinner/label color |
currentColor | Default variant (inherits) |