Status Icon
A small status indicator icon for the canonical task states — todo, in progress, blocked, and done.
- Status
- Since
0.1.0- Accessibility pattern
- img role with derived label
Last updated
Install
Add Status Icon from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/status-iconUsage
import { StatusIcon } from "@/components/ui/status-icon";
<StatusIcon status="progress" />;Examples
States
Each status maps to a lucide-react icon and a semantic color token: todo (Circle,
muted), progress (spinning Loader, info), blocked (CircleAlert, destructive), and done
(CircleCheck, success).
Sizes
xs (14px), sm (16px), md (20px), lg (24px) — the --icon-* role tokens
(inline / default / action / feature), the same ladder Spinner uses.
Each status renders at every size — only progress animates (its spinning Loader):
With a text label
When adjacent text already states the status, pass label="" so the icon is marked decorative
(aria-hidden) and the screen reader announces the text once rather than twice. This is the
recommended accessible pattern.
<span className="flex items-center gap-2 text-info-text">
<StatusIcon status="progress" label="" />
In progress
</span>Playground
Pick a status and size to preview each state's icon and color, then copy the generated JSX.
<StatusIcon />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Accessible label announced by assistive tech. Defaults to a human-readable
name derived from status (e.g. "In progress"). Pass an empty string to
make the icon decorative (aria-hidden) — only do this when adjacent text
already conveys the status. |
size | "lg" | "md" | "sm" | "xs" | 'md' | Size variant — mirrors the rest of the scale and maps to the --icon-* role
tokens: xs inline (14px), sm default (16px), md action (20px), lg
feature (24px). |
status | "blocked" | "done" | "progress" | "todo" | 'todo' | Status to display. Selects both the icon and its semantic color token:
- todo → Circle, text-muted-foreground
- progress → spinning Loader, text-info-text
- blocked → CircleAlert, text-destructive-text
- done → CircleCheck, text-success-text |
Data attributes and CSS variables on StatusIcon
| Attribute | Values |
|---|---|
data-size | mirrors a prop or state value |
data-slot | "status-icon" |
data-status | mirrors a prop or state value |
Accessibility
- By default the icon renders
role="img"with anaria-labelderived fromstatus(e.g."In progress"), so assistive tech announces the state. Override the wording with thelabelprop. - When adjacent text already states the status — for example a label next to the icon — pass
label=""to make the icon decorative (aria-hidden) and avoid a redundant announcement. - Color is conveyed through a semantic token (
currentColor) only — never rely on color alone to communicate the status; the distinct icon shapes carry the meaning too. - The
progressspin stops underprefers-reduced-motion: reducethrough the global reset inbase.css, which every component inherits rather than restating.
| Concern | Behavior |
|---|---|
| Role | role="img" unless label="" (decorative, aria-hidden) |
| Accessible name | aria-label from label, or a default derived from status |
| Reduced motion | progress animation frozen by the global base.css reset |
| Contract | States tested |
|---|---|
| Behaviour | default, empty, error, success |
| Accessibility | labeled |
| Visual | default, error, success, empty |