Skip to content

Spinner

Show that work is running during a short wait.

import { Spinner } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use a spinner for a wait of a few seconds whose length you can't measure: a sync, a lookup, a check. If you know how far along the work is, use Progress. If you know the shape of what's loading, a Skeleton holds its place. On a button, use the button's own loading state instead of placing a spinner inside it.

import { Spinner } from '@youj/react'

export function Syncing() {
  return <Spinner label="Syncing issues" />
}

On its own, a spinner announces its label politely. The default is "Loading". Inside something that already announces the wait, such as a loading Button or an aria-busy region with its own status, pass label={null} to keep it silent: two announcements for one wait are worse than none.

Reference

Propslabel, size (2)

Props

Spinner props
PropType
labelstring | null

Announced politely. Pass null when the surrounding thing already announces the wait (a loading Button, an aria-busy region): two announcements for one wait are worse than none.

–
sizenumber

Rendered size in px.

default 16

16
Other props pass through: extends ComponentProps<'span'>.
MotionTurn, arc · reduced motion

Motion

Motion tokens
MomentTokens
Turna constant-rate rotation
duration.deliberateease.linear

560ms · cubic-bezier(0, 0, 1, 1) · × 1.25 per turn

560mscubic-bezier(0, 0, 1, 1)× 1.25 per turn
Arcthe arc breathes between 12% and 60% of the ring
duration.deliberateease.standard

560ms · cubic-bezier(0.2, 0, 0, 1) · × 2.2 per breath

560mscubic-bezier(0.2, 0, 0, 1)× 2.2 per breath

Reduced motion

A still quarter arc on a faint track. The label is still announced.

The turn and the breath run on different periods, so the loop never visibly repeats. It's Youj's LoaderRingIcon, so it follows the Speed control and pauses when it's offscreen or the tab is hidden.

Reduced motion

The ring stops turning and holds a quarter arc on a faint track, which still reads as "in progress". The spoken label doesn't change.

AccessibilityARIA, announcements

Accessibility

  • With a label, the spinner is a status role holding the label as visually hidden text, so the wait is announced politely.
  • With label={null} it has no role, and its ring is aria-hidden.
  • Say what's happening, not just that something is. "Checking DNS for docs.youj.io" is better than "Loading".