Diwa Design System

Spinner

A CSS-only animated loading indicator. Communicates asynchronous activity to both sighted users and screen readers via role="status" and an accessible label.

When to use

Do

  • Use to indicate an ongoing background operation such as data fetching, file upload, or form submission.
  • Place inline with text for subtle progress feedback (sm size).
  • Use the lg size for full-page or panel-level loading states.
  • Always provide a meaningful label for screen readers — avoid the generic default when context is available.
  • Pair with a disabled button to prevent duplicate submissions during async operations.

Don't

  • Don't show a spinner for operations that complete in under 300ms — a flash of spinner is more disruptive than no feedback.
  • Don't use a spinner as a skeleton-screen replacement — use skeleton components for layout-level loading.
  • Don't leave the spinner on screen indefinitely — always handle errors and timeouts.
  • Don't use the spinner purely decoratively without a live region — it won't be announced to screen readers.
  • Don't omit the label prop when the surrounding context doesn't describe the operation.

Size guidance

sm (14px) — Inline with text, inside buttons, or inside compact UI controls. Use when the surrounding text already communicates context.

md (16px) — Default. Use for component-level loading states such as loading a card, a table row, or a form field.

lg (20px) — Use for full-panel or full-section loading states where the spinner is the primary visual focus.

Label guidance

The label prop sets the aria-label on the host element and is announced by screen readers when the spinner appears. The default value is "Loading". Provide a more specific value whenever possible:

  • label="Saving changes" - during form auto-save
  • label="Uploading file" - during file upload
  • label="Loading results" - while fetching search results