Spinner
since v14.1.0Indeterminate loading indicator. Two modes:
• Inline (<Spinner aria-label="Loading" />) — sits in flow.
• Wrapper (<Spinner spinning>{children}</Spinner>) — dims + inerts the
children and overlays a centered spinner, preserving their footprint
(no reflow, local stacking only).
currentColor indicator (defaults to ink). Never brand. Reduced-motion users
get the static track ring (via {@link SpinnerIcon}) plus the text affordance.
Install
Add the package and import the component.
pnpm add @hey-mike/tungstenpnpm add @hey-mike/tungstenimport { Spinner } from '@hey-mike/tungsten';import { Spinner } from '@hey-mike/tungsten';Preview
Same fixtures used by the visual-regression suite.
Usage
apps/docs/app/snapshots/spinner/page.tsx
import { Spinner } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';
export default function SpinnerSnapshot() {
return (
<VariantGrid
title="Spinner"
hero={<Spinner size="lg" tip="Loading" />}
variants={[
{
label: 'sizes',
node: (
<div className="flex items-center gap-6">
<Spinner size="sm" aria-label="Loading" />
<Spinner size="md" aria-label="Loading" />
<Spinner size="lg" aria-label="Loading" />
</div>
),
},
{ label: 'with tip', node: <Spinner tip="Saving…" /> },
{
label: 'wrapper',
node: (
<div className="w-64">
<Spinner tip="Loading" spinning>
<div className="bg-surface-2 border-stroke text-ink-2 rounded-md border p-4 text-sm">
Content being loaded — dimmed and inert while the spinner overlays it.
</div>
</Spinner>
</div>
),
},
]}
/>
);
}
import { Spinner } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';
export default function SpinnerSnapshot() {
return (
<VariantGrid
title="Spinner"
hero={<Spinner size="lg" tip="Loading" />}
variants={[
{
label: 'sizes',
node: (
<div className="flex items-center gap-6">
<Spinner size="sm" aria-label="Loading" />
<Spinner size="md" aria-label="Loading" />
<Spinner size="lg" aria-label="Loading" />
</div>
),
},
{ label: 'with tip', node: <Spinner tip="Saving…" /> },
{
label: 'wrapper',
node: (
<div className="w-64">
<Spinner tip="Loading" spinning>
<div className="bg-surface-2 border-stroke text-ink-2 rounded-md border p-4 text-sm">
Content being loaded — dimmed and inert while the spinner overlays it.
</div>
</Spinner>
</div>
),
},
]}
/>
);
}
Props
Surface specific to <Spinner />.
| Prop | Type | Default | Description |
|---|---|---|---|
| spinning | boolean | — | Whether the spinner is active. Default true. |
| size | "sm" | "md" | "lg" | — | Indicator size. Default 'md'. |
| delay | number | — | Delay in ms before showing the spinner — skips the flash on fast loads. Default 0. |
| children | ReactNode | — | Wrap content: dims + makes it inert and overlays the spinner while spinning. |
| className | string | — | — |
| tip | ReactNode | — | — |
| aria-label | string | — | — |
| aria-labelledby | string | — | — |