Skip to content

BbSpinner

The library's indeterminate wait, for when you cannot say how far along you are.

import { BbSpinner } from 'bitboss-ui';

On this page

Use it for

Reach for BbSpinner when something is happening and you cannot say how far along it is. A request in flight, a file being parsed, a panel with nothing to show yet.

Use something else when

  • BbProgress, when a fraction exists: bytes sent, steps completed, rows imported
  • Nothing at all: BbButton, BbTable and the form fields already carry their own loading state

Passthrough

Hover or tap a part to outline it. The toggles turn on loading, errors and warnings where the component has them; only parts get a row.

Display name

Load a region or row

Use a centred spinner for an empty region and a small inline one when the rest of the row remains usable. Always name what is loading.

Recent invoices

No invoices loaded yet.

Inline waits

A switch has no loading state of its own, so when turning one on starts a connection, that row says so under its label, at sm so the line height stays put.

  • Connected · paid invoices sync every hour
  • Not connected

Size and colour

size runs from xs to 2xl, 12 to 40px, and md is the default; it also takes a number of pixels or a CSS length. Beside helper text, use sm.

xssmmdlgxl2xl203rem

A spinner takes the text colour of whatever it sits in. To change it, colour the wrapper.

Checking availability Syncing catalogue Retrying after an error

Under prefers-reduced-motion: reduce the dots hold at full size instead of pulsing.

Coming from v2

The color prop is gone. Colour the surrounding text instead.

Where you no longer need one

Most waits belong to a component that already handles them. A @click handler returning a promise puts BbButton into its own loading state, and the form fields carry a loading of their own.

128 products in draft.

Nesting a BbSpinner inside a button paints the picture without the behaviour: the button stays clickable and assistive tech is told nothing.

A field with loading shows the spinner inside itself, so the status line under it can stay plain text.

Saves as you type

Where the shape of the incoming content is known and stable, placeholder rows say more than a spinner. BbTable ships them behind loading, and a column's skeleton option picks each placeholder's shape.

Coming from v2

BbButton tracking async click handlers is new in v3. The spinner you placed inside a button, and the ref that drove it, can both go.

Announcing the wait

Announce the wait exactly once: label and role="status" together read it out twice.

With visible text Loading recent activity…
Standing alone
ActivityLoading recent activity

When visible text sits beside the spinner, put role="status" on the container holding both and leave label unset. When the spinner stands alone, label wraps it in its own role="status" with the text rendered sr-only.

When the wait becomes measurable

Some waits change nature halfway through. A CSV import validates the file first, with nothing to count, then writes rows it can count.

Import team members team-export.csv · 25 rows

Spin while the number does not exist, and fill a bar from the moment it does. When a bar is already on screen, keep it and set indeterminate on BbProgress instead.