Skip to main content

Spinner

A visual loading indicator that communicates ongoing asynchronous activity. Designed for inline usage, button loading states, and page-level placeholders. Supports multiple sizes, color variants, and accessible status semantics.


Usage

Basic usage

import { Spinner } from '@nofinite/nui';

<Spinner />;

Custom size

<Spinner size="lg" />

Variant usage

<Spinner variant="muted" />
<Spinner variant="inverse" />

Button loading pattern

<button disabled>
<Spinner size="sm" variant="inverse" />
</button>

Props

PropTypeDefaultDescription
size'sm' | 'md' | 'lg' | 'xl'mdControls spinner dimensions
variant'primary' | 'muted' | 'inverse'primaryControls spinner color scheme
classNamestringAdditional styling
labelstringLoading...Accessible label for screen readers

Variants

Size variants

<Spinner size="sm" />
<Spinner size="md" />
<Spinner size="lg" />
<Spinner size="xl" />

Color variants

<Spinner variant="primary" />
<Spinner variant="muted" />
<Spinner variant="inverse" />

Available variants

  • Primary
  • Muted
  • Inverse
  • Small
  • Medium
  • Large
  • Extra large

Guidelines

  • Use primary for component-level loading
  • Use muted for page-level or background loading
  • Use inverse for dark surfaces and buttons
  • Prefer smaller sizes for inline usage
  • Avoid oversized spinners in dense layouts

States

  • Idle animation
  • Reduced motion
  • Button loading
  • Inline loading
  • Page loading

Accessibility

  • Uses role="status" for assistive announcement
  • Hidden descriptive label ensures screen reader clarity
  • Supports custom loading message via label
  • Respects prefers-reduced-motion
  • Color variants maintain sufficient contrast

Design Tokens

TokenUsage
--nui-color-primaryPrimary spinner color
--nui-fg-mutedMuted spinner color
currentColorHead + track rendering
opacity valuesTrack visual depth

Best Practices

Do

  • Pair spinner with contextual loading text for long operations
  • Use inverse spinner inside buttons or dark surfaces
  • Prefer skeleton loaders for complex layout loading
  • Use spinner sparingly to avoid perceived latency
  • Combine with optimistic UI where possible

Don’t

  • Show spinner for ultra-fast operations (less than 300ms)
  • Stack multiple spinners in one region
  • Use spinner as the only feedback for long processes
  • Place spinner without context in large empty layouts
  • Ignore reduced motion preferences