- Gallery
- Dashboard & Analytics
- MetricCard
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 badgeHow 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"23import * as React from "react"4import { Card, CardContent } from "@/components/ui/card"5import { Badge } from "@/components/ui/badge"6import { cn } from "@/lib/utils"78interface MetricCardProps {9 title: string10 value: string11 change: number12 data?: number[]13 className?: string14}1516export function MetricCard({ title, value, change, data = [40, 70, 45, 90, 65, 85, 75, 95], className }: MetricCardProps) {17 const isPositive = change >= 018 const max = Math.max(...data)19 const min = Math.min(...data)20 const range = max - min || 12122 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) * 10038 return (39 <div40 key={i}41 className={cn(42 "flex-1 rounded-t-sm transition-all duration-500 ease-out",43 isPositive44 ? "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}