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.
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" />Playground
Preview
Showcase
Preview
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.
IconButton
A square button that renders a single icon, with optional external label and notification badge.
Badge
A small notification indicator that overlays other components. Two variants — Dot (plain circle) and Label (pill with text). Two appearances — Solid and Outline. Four sizes. Six colors. Five corner-rounding options.