HySpinner
Usage examples on this page are written for Lit / plain HTML (
<hy-spinner>). The same component ships asHySpinnerin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
A visual loading indicator that shows an indeterminate spinning animation.
The spinner component displays an animated circular indicator to communicate that content is loading or a process is in progress. It's purely indeterminate— for showing progress percentages, use the Progress component instead.
Key Features:
- Three size variants (small, medium, large)
- A page variant that draws the logo a design system uploads as its page loader
- Customizable colors via CSS custom properties
- Accessible with proper ARIA attributes
- CSS-based animation for performance
- SSR compatible
Accessibility: built in
- Uses
role="status"for screen reader announcements - High contrast and forced colors mode support
- Respects
prefers-reduced-motion(stops animation)
Accessibility: your part
- Set
label: it is the name screen readers announce.
When to Use:
- Loading content (< 10 seconds expected)
- Submitting forms
- Processing actions
- Fetching data
The page variant: variant="page" is for a whole page or app view waiting on data. It draws the logo the design system uploaded as its page loader, at the height the design system set (size is ignored), and a large ring when the design system has none. Every other place keeps the inline ring. It waits a moment before it shows, so a quick load never flashes it.
When to use
- A short wait of unknown length in a small region: a panel refreshing, a list loading more.
- A whole page or app view waiting on data, with
variant="page".
Do
- Show it where the content will appear.
When not to use
- Waiting on an action started from a button: the button's own
loadingattribute (hy-button). - A region whose loaded layout is known, such as a list or card grid:
hy-skeletonin that shape. - Work that finishes in under about a second: show no indicator.
- Progress that can be measured, or a very long operation:
hy-progresswith a percentage. - A whole page or app view waiting on data, with no layout known yet:
variant="page", not a large ring. variant="page"on a panel, a card or one region of a page: the default ring, orhy-skeletonwhere the layout is known.
Examples
Basic usage
<hy-spinner label="Loading"></hy-spinner>Different sizes
<hy-spinner size="small" label="Loading"></hy-spinner>
<hy-spinner size="medium" label="Loading"></hy-spinner>
<hy-spinner size="large" label="Loading"></hy-spinner>A page waiting on data
<hy-spinner variant="page" label="Loading your projects"></hy-spinner>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
size | size | 'small' | 'medium' | 'large' | 'medium' | The size of an inline spinner. On variant="page" the size is the design system's. |
variant | variant | 'inline' | 'page' | 'inline' | Which job the spinner does. |
label | label | string | 'Loading' | Accessible label describing what is loading. |
CSS Parts
| Part | Description |
|---|---|
base | The SVG element containing the spinner |
track | The background track circle |
indicator | The animated spinning indicator |
logo | The design system's logo on the page variant |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-spinner-stroke-sm | var(--hy-stroke-md) | Stroke width for small size |
--hy-spinner-stroke-md | var(--hy-stroke-lg) | Stroke width for medium size |
--hy-spinner-stroke-lg | var(--hy-stroke-xl) | Stroke width for large size |
--hy-spinner-motion-loop-spin-duration | var(--hy-motion-loop-spin-duration) | Rotation duration of the spinner |
--hy-spinner-motion-loop-spin-easing | var(--hy-motion-loop-spin-easing) | Rotation easing of the spinner |
--hy-spinner-motion-loop-pulse-duration | var(--hy-motion-loop-pulse-duration) | Pulse duration of the page variant's logo |
--hy-spinner-motion-loop-pulse-easing | var(--hy-motion-loop-pulse-easing) | Pulse easing of the page variant's logo |