Spinner
A small loading indicator with three visual variants and four sizes. Always announces itself via role="status" and aria-label. Honors prefers-reduced-motion by halting animation and dimming the indicator.
Live Preview
Import
import { Spinner } from 'entangle-ui';Usage
<Spinner /><Spinner variant="dots" size="lg" /><Spinner showLabel label="Fetching results..." />Variants
Variants
<Spinner variant="ring" /> {/* default — circular arc */}<Spinner variant="dots" /> {/* three pulsing dots */}<Spinner variant="pulse" /> {/* pulsing filled circle */}Sizes
Sizes
| Size | Pixel size | Use case |
|---|---|---|
xs | 12px | Inline next to short text |
sm | 14px | Compact button replacement |
md | 16px | Default |
lg | 20px | EmptyState or page-level loader |
<Spinner size="xs" /><Spinner size="sm" /><Spinner size="md" /><Spinner size="lg" />Colors
Named values map onto theme tokens. Any other string is used as a raw CSS color.
Colors
| Name | Maps to |
|---|---|
accent | colors.accent.primary |
primary | colors.text.primary |
secondary | colors.text.secondary |
muted | colors.text.muted |
<Spinner color="accent" /><Spinner color="muted" /><Spinner color="#9b59b6" />Visible Label
By default the label is provided via aria-label only. Set showLabel to render it visually next to the spinner.
Visible label
<Spinner showLabel label="Saving..." />Inside a Button
Replace the button content while an operation runs.
Inside a button
Click the button to simulate a 1.5s async operation.
<Button disabled={loading}> {loading ? ( <> <Spinner size="sm" color="primary" /> Saving... </> ) : ( 'Save' )}</Button>For the standard “loading button” pattern, prefer <Button loading>.
Reduced Motion
When the user enables prefers-reduced-motion: reduce in their OS, animation is suppressed and the indicator is rendered at 60% opacity instead. No code changes required.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'ring' | 'dots' | 'pulse' | 'ring' | Visual style. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'md' | Size scale. |
color | 'accent' | 'primary' | 'secondary' | 'muted' | string | 'accent' | Named theme color or any CSS color string. |
label | string | 'Loading...' | Visible text and aria-label content. |
showLabel | boolean | false | Show the label visually next to the spinner. |
className | string | — | Additional CSS class names. |
style | CSSProperties | — | Inline styles. |
testId | string | — | Test identifier for automated testing. |
ref | Ref<HTMLSpanElement> | — | Ref to the underlying span element. |
Accessibility
- Root element has
role="status"andaria-live="polite"so screen readers announce the loading state when the spinner appears aria-labeldefaults to"Loading..."and can be overridden vialabel- When
showLabelisfalse, the label is rendered in a visually-hidden span so it remains discoverable by assistive tech - Animation is automatically halted under
prefers-reduced-motion: reduce