Components
Spinner
Animated loading indicators with ring, dots, and pulse variants, five sizes, intent colors including brand primary, optional track, label positions, and LTR/RTL support.
Playground
Installation
pnpm add @tessinaui/uiUsage
import { Spinner } from "@tessinaui/ui";{/* Default ring */}
<Spinner />
{/* Brand primary color */}
<Spinner intent="primary" />
{/* Arc-only (no track), Atlassian style */}
<Spinner track={false} />
{/* Label above */}
<Spinner labelPosition="top" />
{/* Label to the right */}
<Spinner labelPosition="right" label="Saving…" />
{/* RTL — label maps to inline-start (visually right) */}
<Spinner labelPosition="left" dir="rtl" label="جارٍ التحميل" />
{/* Dots, large, error */}
<Spinner variant="dots" size="lg" intent="error" />
{/* Pulse, success */}
<Spinner variant="pulse" intent="success" />Examples
Default
A basic ring spinner with the default size and intent.
Variants
Three animation styles — ring, dots, and pulse.
Sizes
Five size tokens from xs to xl.
Intents
Color intents including the brand primary, plus feedback colors.
Track
The ring variant with the background track on (default) versus off for an arc-only style.
With label
A visible label placed beside or beneath the spinner, with RTL support.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "ring" | "dots" | "pulse" | "ring" | Visual style of the animation |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Size of the spinner |
intent | "none" | "primary" | "error" | "warning" | "success" | "info" | "none" | Color intent; primary uses the brand color |
track | boolean | true | Show the full-circle background track. ring variant only. Set false for an arc-only style |
label | string | "Loading" | Text shown visually (when labelPosition ≠ "none") and read by screen readers |
labelPosition | "none" | "top" | "bottom" | "left" | "right" | "none" | Where to render the visible label. "none" hides it visually (screen-reader only) |
dir | "ltr" | "rtl" | "ltr" | Text direction. In RTL mode "left" maps to inline-start (visually right) and "right" to inline-end (visually left) |
className | string | — | Additional class on the wrapper span |
Variants
| Variant | Description |
|---|---|
ring | Rotating arc (~75% of circumference) on an optional dimmed circular track |
dots | Three bouncing dots with 150ms stagger delays |
pulse | Pulsing circle with animate-ping outer ring and solid inner circle |
Label positions
| Value | Layout |
|---|---|
none | Label hidden — screen reader only via aria-label |
top | flex-col, label above the spinner |
bottom | flex-col, label below the spinner |
left | flex-row, label to the left (inline-start in RTL) |
right | flex-row, label to the right (inline-end in RTL) |
Notes
- Accessibility: Wrapper renders
role="status"andaria-label. WhenlabelPosition="none"asr-onlyspan carries the text. - track=false: Removes the background circle — only the rotating arc is visible. Mirrors the Atlassian spinner style.
- primary intent: Uses
text-primary(brand color) for the arc/dots/pulse andtext-primary/30for the ring track. - RTL: Set
dir="rtl"together withlabelPosition="left"or"right". The component appliesflex-row-reverseso that"left"visually becomes the inline-start (right side) and"right"becomes inline-end (left side), matching standard RTL layout expectations.