Unified UI

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 spinner
pnpm dlx @work-rjkashyap/unified-ui add spinner
npx @work-rjkashyap/unified-ui add spinner
bunx @work-rjkashyap/unified-ui add spinner

If 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-ui
pnpm add @work-rjkashyap/unified-ui
yarn add @work-rjkashyap/unified-ui
bun add @work-rjkashyap/unified-ui

Anatomy

import { Spinner } from "@work-rjkashyap/unified-ui";

Examples

Basic Usage

Loading

Sizes

Loading
xs (14px)
Loading
sm (16px)
Loading
md (20px)
Loading
lg (24px)
SizeDiameterUse Case
xs14pxInside buttons, badges, inline text
sm16pxTable cells, small buttons, compact UI
md20pxDefault loading state
lg24pxEmpty states, page loading, hero areas

Variants

Loading
Default
Loading
Primary
Loading
Secondary
Loading
Muted

With Label

Loading…
Fetching data…
Please wait…

Label Position

Inline label
right (default)
Stacked label
bottom

In Context

Loading
Loading your dashboard…
Loading
Refreshing data…

Custom Stroke Width

Loading
Thin (1.5)
Loading
Default (2.5)
Loading
Thick (4)

Props

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg""md"Size of the spinner.
variant"default" | "primary" | "secondary" | "muted""default"Color variant.
labelReactNodeVisible label text alongside the spinner.
labelPosition"right" | "bottom""right"Position of the label relative to the spinner.
strokeWidthnumber2.5Thickness of the spinner stroke.
aria-labelstring"Loading"Accessible label for screen readers.
classNamestringAdditional 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 the label prop if it's a string.
  • Screen-reader text — When no visible label is 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-motion via Framer Motion's useReducedMotion hook and falls back to CSS animate-spin which the browser can optimize or skip per OS settings.

Design Tokens

TokenUsage
--primaryPrimary variant spinner color
--foregroundSecondary variant spinner color
--muted-foregroundMuted variant spinner/label color
currentColorDefault variant (inherits)

On this page