Componentdata1.02 KB gzipZero dependencies
Kpi Strip
Responsive grid strip of KPI metric tiles with deltas and spark bars.
Preview
Live Preview
TOTAL ADMITTED
4,820
+18%
VIP CLAIMS
1,204
+6%
STANDBY
312
-3%
GATE SCANS
9,410
+24%
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add kpi-stripOr install the full npm package:
npm install bigbulluiUsage
Open in StackBlitzimport { KpiStrip } from "@/components/ui/kpi-strip";
<KpiStrip tiles={[{ label: "TOTAL ADMITTED", value: "4,820", delta: { value: "+18%", up: true } }]} />Usage guidance
Use Kpi Strip when a ticket stub surface needs Responsive grid strip of KPI metric tiles with deltas and spark bars. Keep props minimal and prefer composition with sibling stubs.
Avoid Kpi Strip for long form flows or dense data grids where a dedicated layout block fits better.
Source code
kpi-strip.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
"use client";
import * as React from "react";
import { cn } from "./lib/utils";
export interface KpiStripTile {
label: string;
value: string | number;
delta?: { value: string; up: boolean };
spark?: number[];
}
export interface KpiStripProps extends React.HTMLAttributes<HTMLDivElement> {
tiles: KpiStripTile[];
}
/** Horizontal KPI summary strip: responsive grid of metric tiles with delta and spark bars. */
export function KpiStrip({ tiles, className, ...props }: KpiStripProps) {
return (
<div
role="list"
aria-label="Key metrics"
className={cn("grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4", className)}
{...props}
>
<style>{`@keyframes kpiRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }`}</style>
{tiles.map((tile, i) => (
<div
key={tile.label}
role="listitem"
className="rounded-lg border-2 border-foreground bg-card p-4 shadow-xs outline-1 outline-dashed outline-offset-[-5px] outline-border animate-[kpiRise_0.4s_ease-out_both] motion-reduce:animate-none"
style={{ animationDelay: `${i * 80}ms` }}
>
<p className="font-mono text-[10px] uppercase tracking-[0.15em] text-muted-foreground">{tile.label}</p>
<div className="mt-1.5 flex items-end justify-between gap-2">
<span className="font-mono text-2xl font-bold tabular-nums text-foreground">{tile.value}</span>
{tile.spark && tile.spark.length > 0 && (
<span className="flex h-6 items-end gap-0.5" aria-hidden="true">
{tile.spark.map((v, j) => (
<span
key={j}
className="w-1 rounded-t-sm bg-accent/70"
style={{ height: `${Math.max(10, Math.min(100, v))}%` }}
/>
))}
</span>
)}
</div>
{tile.delta && (
<p
className={cn(
"mt-1 inline-flex items-center gap-1 font-mono text-[10px] tabular-nums",
tile.delta.up ? "text-emerald-700 dark:text-emerald-400" : "text-destructive"
)}
>
<span aria-hidden="true">{tile.delta.up ? "▲" : "▼"}</span> {tile.delta.value}
</p>
)}
</div>
))}
</div>
);
}
Props
| Prop | Type | Description |
|---|---|---|
| tiles | KpiStripTile[] | Metric tiles with label, value, delta and spark (required). |
| className | string | Grid wrapper styling override. |