Status Dot

A small colored dot for inline status indication. Six semantic statuses, three sizes, an optional pulse halo for "live" states, and an optional inline label that picks up the status color.

IdleOnlineHealthyDegradedDownStreaming
Customize
Status
active
md
Label & pulse
Online

Installation

npx shadcn@latest add https://craftbits.dev/r/status-dot.json

Usage

import { StatusDot } from "@craft-bits/core";
 
<StatusDot status="active">Online</StatusDot>

When status="active", the pulse halo is on by default — pass pulse={false} to force it off, or pulse on any other status to opt in:

<StatusDot status="success" pulse>Streaming</StatusDot>
<StatusDot status="active" pulse={false}>Online (quiet)</StatusDot>

The label is optional — drop the children and you get just the dot:

<StatusDot status="error" size="lg" aria-label="Service down" />

Understanding the component

  1. Status-driven palette. status selects six semantic colors (idle, active, success, warning, error, accent). The dot fills the color; if a label is present, it inherits the same color via a sibling <span> so the eye reads dot and word as one signal.
  2. Sizes. size="sm" (6px), "md" (8px, default), and "lg" (10px) — pick sm for inline-with-text use, lg for stand-alone status chips.
  3. Pulse via CSS, not JS. The @keyframes cb-status-dot-pulse rule is injected once into <head> the first time a pulsing dot mounts. It's wrapped in @media (prefers-reduced-motion: no-preference) so reduced-motion users see a static dot automatically — no JS branch.
  4. Smart pulse default. When status="active", pulse is on by default — that's the only status whose semantic meaning is "actively happening." Every other status defaults to static. Pass pulse explicitly to override either way.
  5. Inline-flex layout. align-middle keeps the dot optically centered against surrounding text; the label is a sibling <span> so it can be styled independently if needed.

Props

PropTypeDefaultDescription
status'idle' | 'active' | 'success' | 'warning' | 'error' | 'accent''idle'Semantic status color.
size'sm' | 'md' | 'lg''md'Dot diameter.
pulsebooleantrue when status="active", else falseAdds a halo that respects prefers-reduced-motion.
childrenReactNodeOptional inline label rendered after the dot.
classNamestringMerged onto the rendered <span>.

Accessibility

  • The component renders a single <span> whose label (if provided) is announced as-is by screen readers. The dot itself is marked aria-hidden="true" so assistive tech reads only the label.
  • For dynamic status updates, wrap the StatusDot in an element with role="status" or aria-live="polite" so screen readers announce changes.
  • When used without a label, supply aria-label so the dot has an accessible name — otherwise it's invisible to assistive tech.
  • The pulse animation is automatically disabled when prefers-reduced-motion: reduce is set — the rule is scoped under @media (prefers-reduced-motion: no-preference). Reduced-motion users see a static dot.

Credits

  • Extracted from: craftingattention (app/src/components/ui/StatusDot.tsx). The status name set (idle | active | success | warning | error | accent) blends CA's runtime tones with terminal-dreams' literal-union shape.