Stats Panel (Key Value Pairs)
The StatsPanel component renders a horizontal set of key–value pairs — a label above its value — used across the application to surface entity metadata such as created/updated timestamps, status, ownership, and counts.
Each value accepts a React element, so it can be plain text, a StatusBadge, a TimeAgoCard, an icon, and more. A missing value renders as -, and passing isLoading shows skeleton placeholders.
Variations
Loading
Pass isLoading to render skeleton placeholders while data is being fetched.
Installation
import { StatsPanel, StatusBadge, TimeAgoCard } from "@harnessio/ui/components";
<StatsPanel data={[ { label: "Created", value: <TimeAgoCard timestamp="Dec 6, 2024" /> }, { label: "Last updated", value: undefined }, // renders as "-" { label: "Connection status", value: ( <StatusBadge variant="status" theme="success"> Success </StatusBadge> ), }, ]}/>;Anatomy
StatsPanel takes a single data array and lays each entry out as a vertical label-over-value pair, arranging the pairs in a horizontal row.
- Each entry is
{ label: string; value?: JSX.Element }. Thelabelis rendered as small secondary text above thevalue. - The
valuemust be a React element — wrap plain strings or numbers (e.g.value: <span>jane.doe</span>). - When a
valueis missing, the panel renders a-placeholder so the layout stays aligned. gapcontrols the vertical spacing between each label and its value.- If
datais empty, the component renders nothing.
Best practices
Do
- Keep labels short and consistent (e.g. “Created”, “Owner”) so the row scans quickly.
- Use
isLoadingto show skeletons while fetching rather than briefly rendering empty-placeholders. - Reach for richer value nodes (
StatusBadge,TimeAgoCard) where they add meaning over plain text.
Don’t
- Don’t pack long, wrapping values into a stat — the panel is meant for compact metadata.
- Don’t rely on order alone to convey which value belongs to which label; every value needs its label.
Accessibility
Labeling
- Each pair’s meaning comes from its visible
labeltext sitting above the value, so always provide a clear, human-readablelabel. - Give icon-only or badge values their own accessible text where the visual alone isn’t sufficient.
Focus & states
StatsPanelrenders static text and has no interactive behavior of its own. Any interactive value you pass in (a link, a button) keeps its own focus and keyboard behavior.
Properties
Prop | Required | Default | Type |
|---|---|---|---|
| data | true | { label: string; value?: JSX.Element }[] | |
| isLoading | false | false | boolean |
| gap | false | '3xs' | 'none' | '4xs' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' |