Spinner
A lightweight, accessible loading indicator. Use it for in-place activity that has no measurable progress (a form submitting, a panel fetching) — when you can show a layout preview instead, reach for Skeleton; when you have a measurable percentage, reach for Progress.
The spinner announces its loading state to screen readers via role="status"
and a visually-hidden label, so assistive technology hears "Loading" regardless
of the animation.
Basic Usage
Sizes
Four sizes cover everything from inline-with-text to a page-center loader.
Color
By default the spinner inherits the surrounding text color (currentColor), so
it matches whatever context you drop it into. Set intent for a standalone
semantic color — every value maps to a theme token, so it restyles with the
active theme.
In Context
Because the spinner inherits currentColor, it sits naturally inside a button,
a badge, or any text run.
Livewire
Pair with wire:loading to show the spinner only while a request is in flight:
{{-- 1. The spinner shows only during the saveProfile() round-trip --}}
<div wire:loading wire:target="saveProfile">
<x-wirekit::spinner intent="accent" />
</div>
{{-- 2. The real content hides while loading --}}
<div wire:loading.remove wire:target="saveProfile">
{{-- saved state --}}
</div>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
size |
string | 'md' |
sm, md, lg, xl |
intent |
string|null | null |
null inherits currentColor; or accent, success, warning, danger, neutral |
label |
string | 'Loading' |
Screen-reader accessible name announced via the live region |
scope |
string|null | null |
Scoped personalization name |
Accessibility
- The wrapper carries
role="status"+aria-live="polite", so screen readers announce the loading state politely without interrupting. - The visually-hidden
label(default"Loading") is the accessible name — set it to something specific likelabel="Loading results"when helpful. - The SVG glyph is
aria-hidden="true"; the meaning is carried entirely by the live-region text, so the loading state is conveyed even when motion is reduced. - Pair with
aria-busy="true"on the region being loaded for the fullest assistive-technology signal.
Keyboard Interaction
This component is purely presentational and does not respond to keyboard input.
Pitfalls
- Don't use a spinner when you have a layout to preview. A Skeleton that mirrors the eventual content reduces perceived load time better than a bare spinner.
- Don't use a spinner when you know the percentage. A Progress bar communicates "how much longer" — a spinner cannot.
- Give long loads a specific label.
label="Loading invoices"is more useful to a screen-reader user than the generic default.
Design Tokens
| Element | Token |
|---|---|
| Default color | currentColor (inherited) |
intent="accent" |
--color-wk-accent |
intent="success" |
--color-wk-success |
intent="warning" |
--color-wk-warning |
intent="danger" |
--color-wk-danger |
intent="neutral" |
--color-wk-text-muted |
Glyph dimensions (h-4/h-5/h-6/h-8) are structural SVG sizes, matching the
icon-sizing convention used across WireKit.