VisorVisor
ComponentsData Display

Spinner

Inline loading indicator — a rotating ring with a subtle track and tone-colored leading edge.

Default

A md spinner with the default tone (text-tertiary leading edge).

Sizes

Three sizes — xs (12px), sm (16px), and md (24px) — fit inline alongside text or inside buttons.

Tones

default uses --text-tertiary for the leading edge. primary uses the --primary brand token.

With Label

Pass a label to make the spinner meaningful to screen readers. It renders role="status" with a visually-hidden label string. Without a label the spinner is aria-hidden="true" (decorative).

Loading results…

Installation

npx visor add spinner

This copies two files into your project:

  • components/ui/spinner/spinner.tsx — the component
  • components/ui/spinner/spinner.module.css — the styles

Usage

import { Spinner } from '@/components/ui/spinner/spinner';

{/* Decorative — inside a button */}
<Spinner size="sm" tone="primary" />

{/* Accessible — standalone loading indicator */}
<Spinner size="md" tone="primary" label="Loading data…" />

API Reference

SpinnerProps

PropTypeDefaultDescription
size'xs' | 'sm' | 'md''md'Ring size. xs=12px, sm=16px, md=24px.
tone'default' | 'primary''default'Color treatment for the leading edge. default uses --text-tertiary, primary uses the --primary brand token.
labelstringAccessible label. When provided, renders role="status" with visually-hidden text. When omitted, aria-hidden="true" (decorative).

The component also accepts all standard <span> HTML attributes.