Spinnerv1.0.8Ready for Production
A loading indicator component with smooth animation and variant options.
Prefer AI-assisted development?
Catalyst Spinner is an animated loading indicator built with a conic gradient and CSS rotation — giving you an accessible, GPU-accelerated spinner with motion-preference support out of the box.
Installation
npm install @pmi/catalyst-spinnerimport { Spinner } from '@pmi/catalyst-spinner';Variants
High Contrast
Use for better visibility on light backgrounds or in contexts where the default gradient lacks sufficient visual presence.
Sizes
The spinner defaults to size-6 (24 px). Apply any Tailwind size utility via className to scale it up or down.
Common Patterns
In a Button
Embed a small spinner inside a button to communicate a loading or processing state. The example below demonstrates the complete loading lifecycle: triggering the loading state, announcing it to assistive technologies via role="status", resolving the operation, and announcing the result via aria-live="polite".
API Reference
Prop
Type
The component also accepts all standard HTML div element attributes and forwards them to the root element.
Accessibility
Spinner is designed to meet WCAG 2.2 AA standards.
ARIA attributes
The spinner element carries no built-in ARIA role. Add role="status" and a visible or visually-hidden label so assistive technologies can announce the loading state:
<Spinner role="status" aria-label="Loading" />For richer context, pair with visually hidden text:
<div className="relative" role="status">
<Spinner />
<span className="sr-only">Loading content, please wait…</span>
</div>When the loading state resolves, role="status" carries an implicit aria-live="polite" and aria-atomic="true" — so any text updated inside that element is announced without interrupting the user. However, this live region behavior is scoped to the element's own subtree. Content that appears elsewhere in the DOM after the spinner is removed is not announced automatically. To communicate a final result or completion state, either keep a persistent role="status" element in the DOM and update its text in place, or place an aria-live="polite" region outside the spinner that remains mounted and receives the result message. See the In a Button example above for a live demonstration of this pattern.
Motion
The rotation animation uses motion-safe:animate-spin, which is suppressed for users who have enabled Reduce Motion in their system preferences (WCAG 2.2 SC 2.3.3 — Level AAA).
Choosing the Right Component
Use Spinner when the duration of the operation is unknown and no layout placeholder is available. Reach for a different primitive when:
| If you need… | Use instead |
|---|---|
| A content-shaped placeholder while data loads | Skeleton |
| A determinate progress indicator with a percentage | Progress Bar |
| A page-level loading bar | Loader |
| A completion notification after the task finishes | Toast |