MetricUIMetricUI
Cards

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.

Revenue
$0
Users
0
Conversion
0%
<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

Revenue
$0
+11.2%
Active Users
0
+18.1%
Conversion
0%
+23.5%
Avg. Order
$0
+8.2%
<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)

Revenue
$0
Users
0
Conversion
0%
Avg. Order
$0

Elevated variant (3 columns)

Uptime
0%
Requests/sec
0
Error Rate
0%
// 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)

Pageviews
1.2M
Bounce Rate
34.7%
Avg. Session
4m 32s
// 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

PropTypeDescription
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

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

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

What to show when a stat value is null/undefined. Falls back to config.nullDisplay.

animate
boolean

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

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.
  • The aiContext prop (inherited from BaseComponentProps) adds business context for AI Insights analysis. See the AI Insights guide for details.

Playground

Experiment with every prop interactively. Adjust the controls on the right to see the component update in real time.

Live Preview

Total Revenue
$0
+11.2%
Active Users
0
+18.1%
Conversion Rate
0%
+23.5%
Avg. Order Value
$0
+8.2%

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