Stat
Display a labelled metric with an optional change indicator, plus a responsive group wrapper.
Installation
Usage
Stat renders a single label and value pair. StatGroup arranges several Stats into a responsive grid, ideal for KPI strips like a cluster overview.
import { Stat, StatGroup } from "@/components/redpanda-ui/stat"<StatGroup columns={4}>
<Stat label="Brokers" value="3" mono />
<Stat label="Topics" value="128" tone="muted" mono />
<Stat label="Throughput" value="42 MB/s" size="lg" tone="success" mono />
<Stat label="Under-replicated" value="4" tone="warning" mono />
</StatGroup>Anatomy
Stat Structure:
┌───────────────────────────────────┐
│ <StatGroup> (responsive grid) │
│ ┌───────────────────────────────┐ │
│ │ <Stat> │ │
│ │ • label (uppercase caption) │ │
│ │ • value (+ optional delta) │ │
│ │ • sublabel (optional) │ │
│ └───────────────────────────────┘ │
└───────────────────────────────────┘Variants
Sizes
<Stat label="Small" value="42" size="sm" />
<Stat label="Medium" value="42" size="md" />
<Stat label="Large" value="42" size="lg" />Tones
<Stat label="Default" value="42" tone="default" />
<Stat label="Muted" value="42" tone="muted" />
<Stat label="Success" value="42" tone="success" />
<Stat label="Warning" value="42" tone="warning" />
<Stat label="Destructive" value="42" tone="destructive" />Monospaced
Use mono for tabular figures that should not jitter as values update.
<Stat label="Throughput" value="42 MB/s" mono />Delta indicator
delta adds an optional change affordance. direction drives both the icon and the default color (up → success, down → destructive, neutral → muted). Override with tone.
<Stat label="Throughput" value="42 MB/s" delta={{ value: "+12%", direction: "up" }} />
<Stat label="Consumer lag" value="312" delta={{ value: "-4.3%", direction: "down" }} />
<Stat label="Partitions" value="640" delta={{ value: "0%", direction: "neutral" }} />Sublabel
sublabel hangs a muted secondary line below the value (e.g. a partition count under a topic count). It does not affect the value's baseline, so stats with and without a sublabel stay top-aligned inside a StatGroup.
<Stat label="Topics" value="6" sublabel="6 partitions" size="lg" />Linked label
labelLink turns the label into a link. Pass a single link element with no children — the label text and a trailing arrow are injected, and the caption styling plus a hover affordance are merged onto it. Client-side routing stays with the caller, so any link component works (<a>, TanStack/Next <Link>, etc.).
<Stat label="Topics" value="6" labelLink={<a href="/topics" />} />
<Stat label="Topics" value="6" labelLink={<Link to="/clusters/$clusterId/topics" params={{ clusterId }} />} />Group columns and gap
<StatGroup columns={2} gap="sm">{/* ... */}</StatGroup>
<StatGroup columns={3} gap="md">{/* ... */}</StatGroup>
<StatGroup columns={4} gap="lg">{/* ... */}</StatGroup>Props
Stat
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Caption shown above the value (uppercased, muted). |
value | React.ReactNode | — | The metric value. |
sublabel | React.ReactNode | — | Muted secondary line below the value. |
size | 'sm' | 'md' | 'lg' | 'md' | Value type scale. lg is bold with tight tracking. |
tone | 'default' | 'muted' | 'success' | 'warning' | 'destructive' | 'default' | Value color. |
mono | boolean | false | Use monospaced, tabular figures for the value. |
delta | { value: string; direction: 'up' | 'down' | 'neutral'; tone? } | — | Optional change indicator. |
labelLink | React.ReactElement | — | Link element (no children) that the label renders as, with a trailing arrow. |
testId | string | — | Maps to data-testid. |
Also accepts all div props.
StatGroup
| Prop | Type | Default | Description |
|---|---|---|---|
columns | 2 | 3 | 4 | 4 | Responsive column count. |
gap | 'sm' | 'md' | 'lg' | 'md' | Gap between stats. |
testId | string | — | Maps to data-testid. |
Also accepts all div props. Children should be Stat items.
Recent changes
- patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
- minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
- minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
- majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
- minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109