Unified UI

Stat

A KPI card with animated count-up value, label, trend indicator, and sparkline slot. Built for dashboards and metrics displays.

Basic

A KPI metric card with animated count-up value, label, trend indicator (up/down/neutral), and an optional sparkline slot.

Total Revenue
$0
+12% this month
Active Users
0
+8% vs last week
Churn Rate
0%
-0.3% this month

Installation

Install the component via the CLI in one command.

npx @work-rjkashyap/unified-ui add stat
pnpm dlx @work-rjkashyap/unified-ui add stat
npx @work-rjkashyap/unified-ui add stat
bunx @work-rjkashyap/unified-ui add stat

If you haven't initialized your project yet, run npx @work-rjkashyap/unified-ui init first. See the CLI docs for details.

Or install the full package

Use this approach if you prefer to install the entire design system as a dependency instead of copying individual components.

npm install @work-rjkashyap/unified-ui
pnpm add @work-rjkashyap/unified-ui
yarn add @work-rjkashyap/unified-ui
bun add @work-rjkashyap/unified-ui

Anatomy

import { Stat } from "@work-rjkashyap/unified-ui";

Basic Usage

Pass a label and value to render a minimal stat card. Numeric values get the count-up animation automatically.

<Stat label="Total Users" value={12430} />
<Stat label="Revenue" value={84200} prefix="$" />
<Stat label="Uptime" value={99.9} suffix="%" />

Trend Indicator

Use trend to show a directional arrow icon and trendLabel for the description text. up renders green, down renders red, and neutral renders muted.

Monthly Revenue
$0
+18% vs last month
Avg. Session
0 min
No change
Error Rate
0%
-0.2% this week
TrendIconColorUse Case
upTrend Up ↗--successRevenue, users, positive metrics
downTrend Down ↘--dangerErrors, churn, negative metrics
neutral--muted-fgUnchanged metrics, no change

Prefix & Suffix

Add a prefix for currency symbols or a suffix for units. Both are rendered as part of the animated count-up value.

Revenue
$0
+5%
Conversion
0%
+0.4%

String Values

When value is a string, no count-up animation plays — the value is rendered as-is. This is useful for non-numeric KPIs.

Plan
Pro
Region
US East
Status
Healthy
All systems go

Sparkline Slot

Pass any ReactNode to the sparkline prop to render a chart or visual in the top-right corner of the card. The slot is 32px tall and right-aligned.

Weekly Signups
0
+34 this week
Errors
0
-3 vs yesterday

Without Animation

Set animated={false} to disable the count-up and slide animations entirely.

<Stat
	label="Total Users"
	value={12430}
	trend="up"
	trendLabel="+120 today"
	animated={false}
/>

Dashboard Grid

A typical 4-up KPI grid layout.

const stats = [
	{
		label: "Total Revenue",
		value: 128400,
		prefix: "$",
		trend: "up",
		trendLabel: "+12% this month",
	},
	{
		label: "Active Users",
		value: 8230,
		trend: "up",
		trendLabel: "+340 this week",
	},
	{
		label: "Avg. Order Value",
		value: 72,
		prefix: "$",
		trend: "up",
		trendLabel: "+$4 vs last month",
	},
	{
		label: "Churn Rate",
		value: 1.8,
		suffix: "%",
		trend: "down",
		trendLabel: "-0.2% this month",
	},
];

<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
	{stats.map((stat) => (
		<Stat key={stat.label} {...stat} />
	))}
</div>;

Props

PropTypeDefaultDescription
labelReactNodeRequired. The metric label rendered above the value.
valuestring | numberRequired. The metric value. Numbers get count-up animation.
previousValuenumberPrevious value (reserved for future delta calculation).
trend"up" | "down" | "neutral"Directional trend indicator.
trendLabelReactNodeDescriptive text rendered next to the trend icon.
sparklineReactNodeOptional mini chart slot rendered in the top-right corner.
prefixstringText prepended to the value (e.g., "$").
suffixstringText appended to the value (e.g., "%", " users").
animatedbooleantrueWhether to enable count-up and entrance animations.
classNamestringAdditional CSS classes on the root card element.

Motion

  • Count-up — Numeric values animate from 0 to the target using framer-motion's animate() with a 1s ease-out curve ([0.4, 0, 0.2, 1]). The displayed integer is derived from useMotionValue + useTransform.
  • Value entrance — The value block uses the countUp preset (y: 12 → 0, opacity: 0 → 1).
  • Trend entrance — The trend row uses slideUpSm with a 300ms delay, staggering after the value.
  • Reduced motion — All animations are disabled when prefers-reduced-motion is active. The final value is displayed immediately.

Accessibility

  • The animated count-up span is wrapped in aria-live="polite" and aria-atomic="true" so screen readers announce the final value after animation completes.
  • Trend icons are aria-hidden="true" — context is conveyed via trendLabel text.
  • The card element is a plain <div> — wrap in a <section> or add aria-label when used in a landmark region.

Design Tokens

TokenUsage
--cardCard background
--borderCard border
--successUpward trend color
--dangerDownward trend color
--muted-fgLabel and neutral trend color
--radius-lgCard border radius (rounded-lg)

On this page