New

MetricCard

Stat card with CSS sparkline, trend arrow, and percentage change indicator

Dashboard & Analyticsmetricsstatssparklinekpi

Dependencies

shadcn/ui components needed:

npx shadcn@latest add cardnpx shadcn@latest add badge

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client"
2
3import * as React from "react"
4import { Card, CardContent } from "@/components/ui/card"
5import { Badge } from "@/components/ui/badge"
6import { cn } from "@/lib/utils"
7
8interface MetricCardProps {
9 title: string
10 value: string
11 change: number
12 data?: number[]
13 className?: string
14}
15
16export function MetricCard({ title, value, change, data = [40, 70, 45, 90, 65, 85, 75, 95], className }: MetricCardProps) {
17 const isPositive = change >= 0
18 const max = Math.max(...data)
19 const min = Math.min(...data)
20 const range = max - min || 1
21
22 return (
23 <Card className={cn("relative overflow-hidden group hover:shadow-lg transition-all duration-300", className)}>
24 <CardContent className="p-6">
25 <div className="flex items-start justify-between mb-4">
26 <div>
27 <p className="text-sm font-medium text-muted-foreground">{title}</p>
28 <p className="text-3xl font-bold tracking-tight mt-1">{value}</p>
29 </div>
30 <Badge variant={isPositive ? "default" : "destructive"} className={cn("text-xs font-semibold", isPositive ? "bg-emerald-500/10 text-emerald-600 hover:bg-emerald-500/20 border-emerald-200" : "bg-red-500/10 text-red-600 hover:bg-red-500/20 border-red-200")}>
31 <span className={cn("inline-block mr-1 transition-transform", isPositive ? "rotate-0" : "rotate-180")}>↑</span>
32 {Math.abs(change)}%
33 </Badge>
34 </div>
35 <div className="flex items-end gap-[3px] h-12 mt-2">
36 {data.map((point, i) => {
37 const height = ((point - min) / range) * 100
38 return (
39 <div
40 key={i}
41 className={cn(
42 "flex-1 rounded-t-sm transition-all duration-500 ease-out",
43 isPositive
44 ? "bg-gradient-to-t from-emerald-500/60 to-emerald-400/90"
45 : "bg-gradient-to-t from-red-500/60 to-red-400/90",
46 "group-hover:opacity-90"
47 )}
48 style={{ height: `${Math.max(height, 8)}%` }}
49 />
50 )
51 })}
52 </div>
53 <div className={cn("absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none", isPositive ? "bg-gradient-to-br from-emerald-500/5 to-transparent" : "bg-gradient-to-br from-red-500/5 to-transparent")} />
54 </CardContent>
55 </Card>
56 )
57}

Related Dashboard & Analytics Components

Command Palette

Search for a command to run...