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. scheduled reads as info (blue) — an upcoming/committed state — deliberately distinct from draft's muted neutral grey, so a committed-but-not-yet-live item never looks like an unpublished one.

Status: LiveStatus: WarnStatus: ScheduledStatus: SoldStatus: Draft

CRM / Pipeline Stages

A third vocabulary covers CRM and sales-pipeline stages — useful for deal boards, client lists, and any record that moves through a prospect → pitched → contracted → active → completed flow (plus paused and archived). Each stage maps to an existing semantic color group, so no new tokens are introduced. Stages that share a meaning share a color: contracted, active, and completed all read as in-good-standing success.

Status: ProspectStatus: PitchedStatus: ContractedStatus: ActiveStatus: PausedStatus: CompletedStatus: Archived

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' | 'live' | 'warn' | 'scheduled' | 'sold' | 'draft' | 'prospect' | 'pitched' | 'contracted' | 'active' | 'paused' | 'completed' | 'archived'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
queuedneutralneutralfilled-neutral
idleneutralneutralfilled-neutral
livesuccesssuccessfilled-success
warnwarningwarningfilled-warning
scheduledinfoinfofilled-info
soldsuccesssuccessfilled-success
draftneutralneutralfilled-neutral
prospectinfoinfofilled-info
pitchedwarningwarningfilled-warning
contractedsuccesssuccessfilled-success
activesuccesssuccessfilled-success
pausedwarningwarningfilled-warning
completedsuccesssuccessfilled-success
archivedneutralneutralfilled-neutral

Neutral statuses use Badge's neutral variant in subtle tone (a --surface-muted background) and the filled-neutral variant in filled tone (a solid --color-neutral-600 fill with white text and dot) — both legible in light and dark mode.

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.