Spinner

An indeterminate loading indicator for short waits whose length is unknown. It inherits currentColor, so it matches whatever text or button it sits in.

StableSource

Import

tsx
import { Spinner } from "@merid/react";

Examples

Sizes

Diameters of 14px (sm), 18px (md, default) and 24px (lg).

Next to text

When visible text already says what is loading, pass label={null} to hide the spinner from assistive tech so the message is not announced twice.

Loading invoices…

Colour

Set color on the spinner or a parent. Give it a specific label when it stands alone.

API reference

Renders a span; forwards its ref and passes native attributes through.

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"Diameter: sm 14px, md 18px, lg 24px.
labelstring | null"Loading"Accessible name. Pass null when decorative — the spinner is then aria-hidden.

Styling

HookValues
.mrd-spinnerRoot <span>
.mrd-spinner__svgThe SVG
.mrd-spinner__trackFaint full circle
.mrd-spinner__arcRotating quarter arc
data-sizesm · md · lg

Component variable: --mrd-spinner-size, set per size.

css
.hero .mrd-spinner {
  --mrd-spinner-size: 32px;
}

Accessibility

  • With a label, the spinner has role="status" and aria-label, so screen readers announce it politely.
  • With label={null} it is aria-hidden. Mark the region that is loading with aria-busy="true".
  • Under prefers-reduced-motion, the rotation slows down rather than stopping, so progress stays visible.

Guidelines

Do

Use a spinner for waits under a few seconds. For longer or measurable work, show a Progress bar.

Avoid

Replace a whole page with a spinner when a Skeleton could show the shape of the content that is coming.

  • Button — loading shows this spinner inside the button.
  • Skeleton — placeholder for content that is loading.
  • Progress — for determinate progress.