Spinner
A small turning ring that says something is at work, in the colour of the text around it.
- TypecheckPassed
- Unit testsRunning
- End-to-end, WebKitRunning
- BuildQueued
Deploying payload-cache to production
Releases
- The spinner takes the colour of its text: the deploy line is in the accent's text colour, and so is its ring.
- Beside words that say what is happening it is hidden from screen readers; alone, with a label, it is a status.
- With reduced motion it keeps turning, at 1.5 seconds a turn instead of one.
Field marks
- Import
import { Spinner } from "cennge-ui";- Size
- 0.7 KB gzip for this import, its dependencies aside
- Pattern
- An
<svg aria-hidden>;role="status"with anaria-labelwhen you passlabel - SSR
- Rendered on the server in the Next.js check; hydrates without a warning
- Sizes
- 14, 16 and 20 px: sm, md and lg
- Source
- src/components/spinner
When to use#
A Spinner marks something that is at work right now and has no amount to show: a job running, a panel fetching, a deploy on its way. It is sized to sit in a line of text or a list row. When you can say how much is done, a progress bar says more.
Similar#
- Progress shows how far a task has got; without a value its ring spins too, but it is a progressbar and comes in larger sizes.
- Skeleton holds the shape of content that is loading, so the page does not move when it arrives.
- Button has its own spinner: pass
isLoadinginstead of putting a Spinner inside.
Sizes and colours#
By default the ring is currentColor, so it matches the text it sits in. color picks a role colour instead; default is the muted grey.
smmdlg
defaultprimarysecondarysuccesswarningdangerinfo
sizes.tsx
import { Spinner, type CenngeColor, type CenngeSize } from "cennge-ui";
const sizes: CenngeSize[] = ["sm", "md", "lg"];
const colors: CenngeColor[] = ["default", "primary", "secondary", "success", "warning", "danger", "info"];
export default function SpinnerSizes() {
return (
<div className="flex flex-col gap-6 text-sm text-muted">
<div className="flex flex-wrap items-center gap-x-6 gap-y-3">
{sizes.map((size) => (
<span key={size} className="flex items-center gap-2 text-foreground">
<Spinner size={size} />
{size}
</span>
))}
</div>
<div className="flex flex-wrap items-center gap-x-6 gap-y-3">
{colors.map((color) => (
<span key={color} className="flex items-center gap-2">
<Spinner color={color} size="lg" />
{color}
</span>
))}
</div>
</div>
);
}With a label, or without#
Without label the spinner is hidden from screen readers, which suits a spinner next to words that already say what is going on. When it stands alone, label makes it a role="status" element named by that text.
Syncing 3 forks
label.tsx
import { Spinner } from "cennge-ui";
export default function SpinnerLabel() {
return (
<div className="flex w-full flex-wrap items-center gap-x-10 gap-y-6">
{/* The text says what is happening: the spinner stays hidden from screen readers. */}
<p className="flex items-center gap-2 text-sm text-muted">
<Spinner />
Syncing 3 forks
</p>
{/* Nothing else says it: the label makes it a status. */}
<div className="grid h-28 w-full max-w-xs place-items-center rounded-large bg-surface-3">
<Spinner size="lg" color="primary" label="Loading the changelog" />
</div>
</div>
);
}