LoadingSpinner

Signals an operation is in progress when its duration is unknown.

Installation

  1. Install the package.
npm install @hashintel/ds-components
  1. Import the component.
import { LoadingSpinner } from "@hashintel/ds-components";

export const EntityTableLoading = () => <LoadingSpinner size="md" />;

When to use

  • Do: Use a spinner for indeterminate waits — fetching entities, syncing a type, running a flow — where progress can't be quantified.
  • Do: Place it where the loaded content will appear, so the user's eye is already there when it lands.
  • Do: Use one spinner per loading region — simultaneous spinners compete for attention and imply separate processes.

When not to use

  • Don't: Don't show a spinner for sub-second work — render the result directly; a spinner that flashes in and out reads as flicker.
  • Don't: Don't use a spinner when progress is measurable — state it as text, like "3 of 5 imports complete", so users can gauge the wait.
  • Don't: Don't leave a spinner running after a request fails — swap in an error state, such as a Banner, that says what went wrong.

Examples

Basic

The default spinner is a smooth circular sweep at md. Drop it into the space the pending content will fill.

Sizes

Five fixed sizes from xxs to lg, sharing the scale Button and the form inputs use — match the control or region the spinner stands in for.

Bars variant

bars replaces the smooth sweep with twelve spokes that tick in discrete steps.

Color

Both variants draw entirely with currentColor, so the spinner takes the CSS color of its container.

With a label

A spinner alone doesn't say what's loading. Pair it with text naming the work, and wrap both in role="status" so screen readers announce it too.

Loading entities…

Behavior

  • The animation keeps running under prefers-reduced-motion — a frozen spinner reads as a stalled process.
  • Sizes are fixed sizes; the spinner doesn't scale with surrounding text or its container.

Accessibility

LoadingSpinner provides a decorative SVG with no role, accessible name, or live region. You must set these yourself.

What you must do

  • Announce loading in text: wrap the spinner and a label in an element with role="status" so screen readers hear the state change.
  • Name the work in the label — "Loading entities…", not "Please wait".

API reference

PropTypeDescription
size
"xxs" |⁠ "xs" |⁠ "sm" |⁠ "md" |⁠ "lg"
default: "md"
variant
"bars" |⁠ "default"
default: "default"

Was this page helpful?

On this page