KpiCard
Display 1–4 metrics in a responsive grid with background sparklines, animated values, delta indicators, and locale-aware formatting.
Q4 Performance
October through December 2025
Installation
npx taw-ui add kpi-cardThis copies the component source and schema into your project. You own the code — customize anything.
Usage
import { tool } from "ai"
import { KpiCardSchema } from "@/components/taw/kpi-card"
export const getMetrics = tool({
description: "Get business metrics",
parameters: z.object({ metric: z.string() }),
outputSchema: KpiCardSchema,
execute: async ({ metric }) => {
const data = await fetchMetric(metric)
return {
id: metric,
stats: [{
key: metric,
label: data.name,
value: data.value,
format: { kind: "currency", currency: "USD" },
diff: { value: data.change },
sparkline: { data: data.history },
}],
source: { label: "Stripe", freshness: "just now" },
}
},
})import { KpiCard } from "@/components/taw/kpi-card"
import type { TawToolPart } from "taw-ui"
function ToolOutput({ part }: { part: TawToolPart }) {
// Handles loading, error, and success states
return <KpiCard part={part} />
}Examples
The layout adapts automatically based on the number of stats. 1 stat renders as a hero, 2–4 as a 2-column grid.
Monthly Revenue
Current month to date
Growth Overview
Last 10 months trend
Infrastructure Health
Production cluster metrics
Q4 Performance
October through December 2025
Props
| Field | Type | Description |
|---|---|---|
| part* | TawToolPart | Tool call lifecycle state — handles loading, error, and success |
| animate | boolean | Enable spring animations and sparkline draw-in (default: true) |
| locale | string | BCP 47 locale for number/currency formatting (e.g. "en-US") |
| className | string | Additional CSS classes on the wrapper |
Schema
The tool output shape validated by the component. Invalid data renders a helpful error with field-level suggestions.
| Field | Type | Description |
|---|---|---|
| id* | string | Stable identifier |
| title | string | Card header title |
| description | string | Card header subtitle |
| stats* | StatItem[] | 1–4 metric items (see below) |
| confidence | number (0-1) | AI confidence badge |
| caveat | string | Uncertainty note from the AI |
| source | Source | Data provenance (label + freshness) |
| Field | Type | Description |
|---|---|---|
| key* | string | Unique identifier for this stat |
| label* | string | Label displayed above the value |
| value* | number | string | The metric value — numbers animate on entrance |
| format | StatFormat | Formatting: currency, number, percent, or text |
| diff | StatDiff | Delta indicator with value, decimals, upIsPositive |
| sparkline | StatSparkline | Background trend chart: { data: number[], color?: string } |
| Field | Type | Description |
|---|---|---|
| kind* | "currency" | "number" | "percent" | "text" | Format type |
| currency | string | ISO currency code (required for currency kind) |
| decimals | number | Decimal places |
| compact | boolean | Compact notation for large numbers (number kind) |
| basis | "unit" | "fraction" | Whether value is already a percentage or 0–1 (percent kind) |
Features
Values count up using spring physics, not linear interpolation
Full-bleed SVG area charts with draw-in animation and hover reveal
Color-coded badges with configurable upIsPositive for metrics like churn
Currency, percent, number, text — locale-aware with compact notation
1 stat = hero mode, 2–4 = 2-column grid with subtle dividers
Parse failures render field-level details with suggestions, never silent null