Skip to content
Component installs need the registry setup— the Base UI shadcn project, the @vegastack namespace and the Cloudflare Access service token.
VegaStack Design

Status Icon

A small status indicator icon for the canonical task states — todo, in progress, blocked, and done.

Status
stable
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-icon

Usage

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.

To doIn progressBlockedDone
<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

PropTypeDefaultDescription
labelstringAccessible 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: - todoCircle, text-muted-foreground - progress → spinning Loader, text-info-text - blockedCircleAlert, text-destructive-text - doneCircleCheck, text-success-text

Data attributes and CSS variables on StatusIcon

AttributeValues
data-sizemirrors a prop or state value
data-slot"status-icon"
data-statusmirrors a prop or state value

Accessibility

  • By default the icon renders role="img" with an aria-label derived from status (e.g. "In progress"), so assistive tech announces the state. Override the wording with the label prop.
  • 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 progress spin stops under prefers-reduced-motion: reduce through the global reset in base.css, which every component inherits rather than restating.
ConcernBehavior
Rolerole="img" unless label="" (decorative, aria-hidden)
Accessible namearia-label from label, or a default derived from status
Reduced motionprogress animation frozen by the global base.css reset
ContractStates tested
Behaviourdefault, empty, error, success
Accessibilitylabeled
Visualdefault, error, success, empty

Do / Don't

Do
Pair the icon with a text label, or give it a meaningful aria-label so the status is announced — distinct icon shapes back up the color.
Don't
Rely on color alone to convey status, or leave the icon unlabeled when no adjacent text describes the state.

On this page