VisorVisor
ComponentsAdmin

Status Badge

Semantic wrapper over Badge that maps admin status names to visual variants with a colored indicator dot and optional pulse animation — copy it into your project and own it completely.

Basic

Status: Healthy

All Statuses (Subtle)

Status: HealthyStatus: DegradedStatus: DownStatus: RunningStatus: PendingStatus: QueuedStatus: IdleStatus: FailedStatus: Complete

Admin-UI Event Tones

A second vocabulary covers admin-ui event lifecycle states — useful for events tables, ticket listings, and any content that moves through a publish / schedule / live / sold-out / archived flow. Each tone maps to an existing semantic color group, so no new tokens are introduced.

Status: LiveStatus: WarnStatus: ScheduledStatus: SoldStatus: Draft

All Statuses (Filled)

Status: HealthyStatus: DegradedStatus: DownStatus: RunningStatus: PendingStatus: QueuedStatus: IdleStatus: FailedStatus: Complete

Pulsing Indicator

Use pulse on in-flight states like running or pending to draw the eye. The animation is skipped automatically when the user has prefers-reduced-motion enabled.

Status: RunningStatus: Pending

Custom Label

Status: All systems nominal

Without Indicator

Status: Complete

Installation

npx visor add status-badge

This copies the component into your project and pulls badge as a transitive registry dependency:

  • components/ui/status-badge/status-badge.tsx — the component
  • components/ui/status-badge/status-badge.module.css — the styles
  • components/ui/badge/badge.tsx — the underlying Badge (auto-installed)
  • components/ui/badge/badge.module.css — Badge styles (auto-installed)

Usage

import { StatusBadge } from '@/components/ui/status-badge/status-badge';

export default function Example() {
  return <StatusBadge status="healthy" />;
}

API Reference

StatusBadgeProps

PropTypeDefaultDescription
status*'healthy' | 'degraded' | 'down' | 'failed' | 'running' | 'pending' | 'queued' | 'idle' | 'complete'Semantic admin status. Drives the underlying Badge variant, the indicator dot color, and the default label.
labelReact.ReactNodeVisible text. Defaults to the capitalized status key (e.g. "Healthy", "Running").
tone'subtle' | 'filled''subtle'Which Badge variant family to use. Filled uses saturated backgrounds; subtle uses tinted surfaces.
indicatorbooleantrueRender the leading colored indicator dot.
pulsebooleanfalseAnimate the indicator dot with a soft pulse. Respects prefers-reduced-motion.
classNamestringAdditional CSS class names to merge onto the root element.
...propsOmit<React.HTMLAttributes<HTMLSpanElement>, "children">All standard HTML attributes (except children) are forwarded to the underlying Badge element.

Status → Variant Mapping

StatusColor groupSubtle variantFilled variant
healthysuccesssuccessfilled-success
completesuccesssuccessfilled-success
degradedwarningwarningfilled-warning
pendingwarningwarningfilled-warning
downdestructivedestructivefilled-destructive
faileddestructivedestructivefilled-destructive
runninginfoinfofilled-info
queuedneutralsecondarysecondary
idleneutralsecondarysecondary
livesuccesssuccessfilled-success
warnwarningwarningfilled-warning
scheduledinfoinfofilled-info
soldsuccesssuccessfilled-success
draftneutralsecondarysecondary

Neutral statuses fall through to secondary in both tones because Badge does not expose a filled-secondary variant.

Accessibility

Color alone is never sufficient to communicate a status. StatusBadge always renders a visually-hidden Status: prefix before the label so screen readers announce the full phrase — e.g. "Status: Healthy" — regardless of which tone or indicator state is active. The indicator dot is marked aria-hidden so assistive tech ignores the decorative glyph.

The pulse animation is wrapped in a prefers-reduced-motion guard and is paused entirely for users who have requested reduced motion.

Source Files

After running npx visor add status-badge, you'll have:

status-badge.tsx

A forwardRef component that composes <Badge> unchanged and layers on the semantic status → variant mapping, the indicator dot, and the accessible prefix.

status-badge.module.css

Only the additions on top of Badge: the indicator dot (sized and colored via CSS custom properties), the pulse keyframes, and the visually-hidden utility. Everything else — padding, radius, typography, background — is inherited from Badge.

Customization

After copying the component, you own it completely. Common customizations:

  • Add a new status (e.g. maintenance) by extending the color group map.
  • Localize statusBadgeLabels by importing and overriding specific keys.
  • Swap the indicator dot for a Phosphor icon per status (e.g. CheckCircle, WarningCircle).
  • Tune the pulse timing by editing the @keyframes block in the CSS module.