StatusIndicator
Rule-based status display with threshold coloring, pulse animation, and five size modes.
import { StatusIndicator } from "metricui";Use StatusIndicator for rule-based health checks — evaluate a numeric value against threshold rules and render the matching status with color, icon, label, and optional pulse animation. Supports five size modes from tiny inline dots to full card shells. For simple labeled badges, use Badge. For numeric KPIs with sparklines and comparisons, use KpiCard.
Basic Example
<StatusIndicator
value={95}
rules={[
{ min: 90, color: "emerald", label: "Healthy" },
{ min: 60, max: 90, color: "amber", label: "Degraded" },
{ max: 60, color: "red", label: "Critical", pulse: true },
]}
size="md"
/>All Sizes
Five size modes cover every use case: dot for inline table cells, sm for compact labels, md (default) for standard displays, lg for prominent standalone indicators, and card for full card shells matching KpiCard.
<StatusIndicator value={95} rules={rules} size="dot" />
<StatusIndicator value={95} rules={rules} size="sm" />
<StatusIndicator value={95} rules={rules} size="md" />
<StatusIndicator value={95} rules={rules} size="lg" />Threshold Rules
Rules are evaluated top-to-bottom; the first match wins. Each value below triggers a different rule, showing green/amber/red status with showValue enabled.
const rules: StatusRule[] = [
{ min: 90, color: "emerald", label: "Healthy" },
{ min: 60, max: 90, color: "amber", label: "Degraded" },
{ max: 60, color: "red", label: "Critical", pulse: true },
];
<StatusIndicator value={95} rules={rules} size="md" showValue />
<StatusIndicator value={75} rules={rules} size="md" showValue />
<StatusIndicator value={40} rules={rules} size="md" showValue />Pulse Animation
Set pulse: true on a rule to draw attention to critical states. The icon animates with a pulsing ring when the rule matches.
// pulse: true on the critical rule causes the icon to animate
const rules: StatusRule[] = [
{ min: 90, color: "emerald", label: "Healthy" },
{ max: 90, color: "red", label: "Critical", pulse: true },
];
<StatusIndicator value={40} rules={rules} size="md" />
<StatusIndicator value={40} rules={rules} size="lg" title="System Health" />Card Mode
Card mode renders a full card shell that sits naturally next to KpiCards. Combine with title, subtitle, showValue, and trend for a complete service health card.
Operational
Intermittent latency spikes
Partial Outage
Investigating root cause
Major Outage
<StatusIndicator
value={99.98}
rules={uptimeRules}
size="card"
title="API Gateway"
showValue
trend={[99.9, 99.95, 99.98]}
/>
<StatusIndicator
value={99.5}
rules={uptimeRules}
size="card"
title="Auth Service"
subtitle="Intermittent latency spikes"
showValue
trend={[99.9, 99.7, 99.5]}
/>
<StatusIndicator
value={97.2}
rules={uptimeRules}
size="card"
title="Database"
subtitle="Investigating root cause"
showValue
trend={[99.5, 98.8, 97.2]}
/>Data States
Every component handles loading states. Pass the loading prop to show a skeleton placeholder.
Loading (md)
Loading (card)
// Loading state — md size
<StatusIndicator value={0} rules={rules} size="md" loading />
// Loading state — card size
<StatusIndicator value={0} rules={rules} size="card" title="API Gateway" loading />Props
| Prop | Type | Default | Description |
|---|---|---|---|
value* | number | null | undefined | — | The value to evaluate against rules. Not displayed unless showValue is true. |
rules* | StatusRule[] | — | Rules evaluated top-to-bottom. First match wins. Last rule with no min/max is the fallback. |
size | StatusSize | "md" | Display mode: "dot", "sm", "md", "lg", or "card". |
showValue | boolean | false | Show the underlying numeric value. |
title | string | — | Title label (shown in "card" and "lg" sizes). |
description | string | React.ReactNode | — | Description popover. |
subtitle | string | — | Subtitle or secondary text. |
since | Date | — | How long the indicator has been in the current state. |
trend | number[] | — | History of recent values — shown as a trend arrow. |
tooltip | string | — | Tooltip content on hover. Defaults to the matched rule's label. |
onClick | () => void | — | Click handler. |
loading | boolean | — | Loading state — shows skeleton. |
className | string | — | Additional class names. |
classNames | { root?: string; icon?: string; label?: string; value?: string } | — | Sub-element class overrides. |
id | string | — | HTML id attribute. |
data-testid | string | — | Test id. |
Data Shape
interface StatusRule {
min?: number; // Minimum value (inclusive). Omit for fallback.
max?: number; // Maximum value (exclusive). Omit for no upper bound.
color: string; // Named color or CSS color string.
icon?: React.ReactNode;
label?: string; // e.g. "Healthy", "Critical"
pulse?: boolean;
}
type StatusSize = "dot" | "sm" | "md" | "lg" | "card";Notes
- Uses forwardRef — you can pass a ref to the root element.
- Rules are evaluated top-to-bottom; first match wins. The last rule acts as fallback if no min/max match.
- Named colors (emerald, green, red, amber, yellow, blue, gray, purple, cyan) map to CSS variables. Any other string is treated as a raw CSS color.
- Card mode uses the same CARD_CLASSES and HOVER_CLASSES as KpiCard for visual consistency.
- The dot size is ideal for inline use in tables or next to text. The card size is a full card shell.