Spinner
A Spinner indicates that a process is ongoing and the user must wait, typically shown when content is loading or when interaction is temporarily blocked.
Code example
import { Spinner } from '@yleisradio/yds-components-react';
<Spinner />
Why to use
A Spinner communicates that the system is working and reduces uncertainty while users wait. It provides simple, lightweight feedback when progress cannot be measured precisely (for example when duration is unknown or no percentage can be shown).
When to use
Use a Spinner to indicate a temporary waiting state when the system is working in the background and progress cannot be clearly measured or predicted.
- Use a Spinner when content is loading or updating asynchronously.
- Use it when an operation is in progress and its duration is short or unpredictable.
- Use a Spinner when progress cannot be meaningfully expressed with a progress bar (no clear steps or percentage).
- Use it when part of the UI is temporarily unavailable while data is being fetched or processed.
- Don’t use a Spinner for long-running operations where progress can be measured — use a Progress Bar instead.
- Don’t block essential content with a Spinner for an extended time without additional explanation.
- Don’t use a Spinner when users need to understand how much work remains.
- Don't show multiple spinners in close proximity, as this can create visual clutter and confusion.
Content Guidelines
- Use a label only when the loading duration is long enough to read it.
- Use a label to clarify what is loading when it’s not otherwise obvious.
- Use short, descriptive labels (e.g., “Ladataan sisältöä…”).
- Don’t use placeholders like “Lataa…” or “Ladataan…” — they’re not helpful.
- Don’t use vague or verbose text (e.g., “Odota hetki, käsittelemme pyyntöäsi.”).
- Don’t rely on the label to explain long or complex operations.
Key Spinner Props
Use these props to configure the Spinner component.
size
Controls the dimensions of the spinner.
| Value | Example | Description |
|---|---|---|
sm | Small spinner (24px) for inline use | |
md | Default size (48px) for general use | |
lg | Large spinner (72px) for prominent loading states |
Code example
<Spinner size="sm" />
<Spinner size="md" />
<Spinner size="lg" />
variant
Defines the visual style and color scheme.
| Value | Example | Description |
|---|---|---|
default | Standard spinner using default text color | |
highlight | Highlighted spinner using accent color | |
default-negative | Default spinner for dark backgrounds | |
highlight-negative | Highlighted spinner for dark backgrounds |
Code example
<Spinner variant="default" />
<Spinner variant="highlight" />
<Spinner variant="default-negative" />
<Spinner variant="highlight-negative" />
hasBackground
Adds a background circle to improve visibility.
| Type | Example | Description |
|---|---|---|
boolean | Shows a subtle background circle behind the spinner |
Code example
<Spinner hasBackground />
<Spinner hasBackground={false} />
label
Provides descriptive text below the spinner.
| Type | Example | Description |
|---|---|---|
string | Loading content... | Addtitional text to clarify the reason for showing spinner |
Code example
<Spinner label="Loading content..." />
<Spinner label="Processing your request" />
colors
Custom color overrides for advanced styling.
| Type | Example | Description |
|---|---|---|
{ spinner?: string; background?: string } | Custom colors for spinner and background |
Code example
<Spinner colors={{ spinner: '#ff0000' }} />
<Spinner colors={{ spinner: '#0066cc', background: '#e6f3ff' }} hasBackground />
Behavior
- The spinner animates continuously to indicate an active process.
- It remains visible until loading completes or the view updates.
- Remove the spinner immediately once content is ready.
- Inline spinners should not block the surrounding UI.
- Larger spinners can indicate that the user must wait before continuing.
- Use a visible label only if the loading duration is long enough to be read.
- Enable
hasBackgroundwhen the spinner is placed on visually complex surfaces.
Accessibility
- Provide a descriptive label when no visible text is present (via
labeloraria-label). (WCAG 4.1.3 — Status Messages) - Mark content regions as busy using
aria-busy="true"when loading updates a specific area. (WCAG 4.1.3 — Status Messages) - Ensure sufficient contrast between the spinner, background circle, and surrounding UI. Use background circle (
hasBackground) to enhance contrast if needed. (WCAG 1.4.3 — Contrast)
API Reference
Props
The Spinner component accepts all standard HTML <div> attributes in addition to the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
size | 'sm' | 'md' | 'lg' | No | 'md' | Size of the spinner |
variant | 'default' | 'highlight' | 'default-negative' | 'highlight-negative' | No | 'default' | Visual style variant |
hasBackground | boolean | No | false | Whether to show background circle |
label | string | No | — | Text label displayed below spinner |
colors | { spinner?: string; background?: string } | No | — | Custom color overrides |
Type Definitions
export const spinnerSizes = ['sm', 'md', 'lg'] as const;
export const spinnerVariants = [
'default',
'highlight',
'default-negative',
'highlight-negative',
] as const;
interface colors {
spinner?: string;
background?: string;
}
export type SpinnerDSProps = {
size?: (typeof spinnerSizes)[number];
variant?: (typeof spinnerVariants)[number];
hasBackground?: boolean;
label?: string;
colors?: colors;
};
export type SpinnerProps = SpinnerDSProps & HTMLAttributes<HTMLDivElement>;