Mischief

61 / Feedback

Status Pill

A dot and a few words: operational, degraded, closed.

All systems operationalDegraded: search is slowIngest is downMarket closed

Installation

Copy the source into your project, or keep it behind a package.

npx shadcn@latest add Tinkerers-Labs/mischief-ui/status-pill
import { StatusPill } from "mischief-ui/status-pill"

Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.

registry/default/status-pill/status-pill.tsx
import * as React from "react" import { cn } from "@/lib/utils" export type StatusTone = "ok" | "warn" | "down" | "idle" export type StatusPillProps = Omit<  React.HTMLAttributes<HTMLSpanElement>,  "children"> & {  children: React.ReactNode  tone?: StatusTone  /** Makes the pill a link, for a status page or a health check. */  href?: string

Usage

export function Health({ status }) {
  return (
    <StatusPill href="/status" tone={status.tone}>
      {status.label}
    </StatusPill>
  )
}

The words do the work

The dot is decoration and the label is the state. That is not only for colour blindness: a green dot alone says nothing about whether the thing is up, degraded, or simply not open yet, and the reader has to know your palette to guess.

Write the label as the state rather than as a category. All systems operational reads better than Status: OK, and Market closed says more than Idle.

<StatusPill>All systems operational</StatusPill>
<StatusPill tone="warn">Degraded: search is slow</StatusPill>
<StatusPill tone="idle" plain>Market closed</StatusPill>

API

childrenReactNodeThe words. They carry the state, not the dot.
tone"ok" | "warn" | "down" | "idle"The dot colour. Defaults to "ok".
hrefstringMakes it a link, for a status page or a health check.
plainbooleanA quiet line rather than a bordered pill.

Accessibility

The dot is hidden from assistive technology and the label is read as ordinary text, so the state never depends on seeing a colour. With an href it becomes a link and inherits link semantics; without one it is a plain span rather than a control, because a status is something to read, not something to press. The tone is exposed as a data attribute for styling and for tests.