StatGroup
A row/grid of mini stat cells, perfect for summary bars at the top of dashboards.
import { StatGroup } from "metricui";Use StatGroup when you need to display multiple metrics in a compact row or grid. It's perfect for summary bars at the top of dashboards — showing key numbers with trend indicators at a glance. For a single prominent metric with sparklines and goals, use KpiCard instead.
Basic Example
Pass an array of stats with label, value, and optional format. Columns auto-detect from the stat count.
<StatGroup
stats={[
{ label: "Revenue", value: 142300, format: "currency" },
{ label: "Users", value: 12450, format: "number" },
{ label: "Conversion", value: 4.2, format: "percent" },
]}
/>Comparisons & Icons
Add previousValue to each stat item for auto-computed trend badges. Include icon for visual context. Use invertTrend for metrics where down is good (e.g. cost, churn).
This Week
<StatGroup
title="This Week"
stats={[
{ label: "Revenue", value: 142800, previousValue: 128400,
format: "currency", icon: <DollarSign /> },
{ label: "Active Users", value: 3200, previousValue: 2710,
format: "number", icon: <Users /> },
{ label: "Conversion", value: 4.2, previousValue: 3.4,
format: "percent", icon: <MousePointerClick /> },
{ label: "Avg. Order", value: 84.6, previousValue: 78.2,
format: "currency", icon: <TrendingUp /> },
]}
/>Layout & Columns
By default, columns auto-detect from the stat count. Override with the columns prop. Use dense for a more compact layout, and variant to change the card style.
Dense + Ghost variant (2 columns)
Elevated variant (3 columns)
// Dense + ghost variant with explicit columns
<StatGroup stats={stats} dense variant="ghost" columns={2} />
// Elevated variant
<StatGroup stats={stats} variant="elevated" columns={3} />Data States
StatGroup supports loading state with skeleton placeholders. Also supports legacy change values and string values for pre-formatted data.
Loading
Legacy format (string values + change)
// Loading state
<StatGroup stats={stats} loading />
// Legacy format with string values and direct change percentages
<StatGroup stats={[
{ label: "Pageviews", value: "1.2M", change: 14.2 },
{ label: "Bounce Rate", value: "34.7%", change: -2.3 },
]} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
stats* | StatItem[] | — | Array of stat items to display. |
title | string | — | Group title above the grid. |
subtitle | string | — | Group subtitle below the title. |
variant | CardVariant | — | Visual variant: 'default', 'outlined', 'ghost', 'elevated', or any custom string. CSS-variable-driven via [data-variant]. Falls back to config.variant. |
dense | boolean | false | Compact/dense layout. CSS-variable-driven via [data-dense]. Falls back to config.dense. |
columns | 1 | 2 | 3 | 4 | 5 | 6 | — | Override column count. Auto-detected from stat count by default. |
format | FormatOption | — | Default format applied to all numeric values. Per-stat format overrides this. |
loading | boolean | false | Show skeleton placeholders. |
className | string | — | Additional CSS class names. |
classNames | { root?: string; header?: string; grid?: string; cell?: string; label?: string; value?: string } | — | Sub-element class name overrides. |
id | string | — | HTML id attribute. |
data-testid | string | — | Test id for testing frameworks. |
onStatClick | (stat: StatItem, index: number) => void | — | Click handler for individual stats. |
nullDisplay | NullDisplay | "dash" | What to show when a stat value is null/undefined. Falls back to config.nullDisplay. |
animate | boolean | true | Enable/disable animations. Currently reserved for future use. |
drillDown | boolean | ((event: { stat: StatItem; index: number }) => React.ReactNode) | — | Enable drill-down on stat click. `true` auto-generates a detail panel. Pass a render function for full control over the panel content. Requires DrillDown.Root wrapper. |
drillDownMode | DrillDownMode | "slide-over" | Presentation mode for the drill-down panel. "slide-over" (default) slides from the right, full height. "modal" renders centered and compact. |
Data Shape
interface StatItem {
label: string;
value: string | number;
change?: number; // Legacy change percentage
previousValue?: number; // For auto-computed comparison
comparisonMode?: ComparisonMode;
invertTrend?: boolean;
format?: FormatOption;
icon?: React.ReactNode;
}Notes
- Uses forwardRef.
- Grid columns auto-detect from stat count when `columns` is not set.
- Per-stat `format` overrides the group-level `format`.
- Supports both legacy `change` (direct percentage) and computed `previousValue` comparisons.
Playground
Experiment with every prop interactively. Adjust the controls on the right to see the component update in real time.
Live Preview
Code
<StatGroup
stats={[
{ label: "Total Revenue", value: 142800, previousValue: 128400, format: "currency", icon: <Icon /> },
{ label: "Active Users", value: 3200, previousValue: 2710, format: "number", icon: <Icon /> },
{ label: "Conversion Rate", value: 4.2, previousValue: 3.4, format: "percent", icon: <Icon /> },
{ label: "Avg. Order Value", value: 84.6, previousValue: 78.2, format: "currency", icon: <Icon /> },
]}
/>Props
Adjust props to see the component update in real time
Switch between sample datasets
Override responsive grid columns