- Gallery
- Data Display
- StatsGrid
New
StatsGrid
2x3 grid of varied stat cards with different internal layouts
Data Displaystatsgriddashboardmetrics
Dependencies
shadcn/ui components needed:
npx shadcn@latest add cardnpx shadcn@latest add badgenpx shadcn@latest add progressHow 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 { Progress } from "@/components/ui/progress"7import { cn } from "@/lib/utils"89interface StatsGridProps {10 className?: string11}1213export function StatsGrid({ className }: StatsGridProps) {14 const sparklineData = [40, 65, 45, 80, 55, 90, 70]15 const maxSparkline = Math.max(...sparklineData)1617 return (18 <Card className={cn("w-full", className)}>19 <CardContent className="p-6">20 <div className="grid grid-cols-3 grid-rows-2 gap-4">21 {/* Card 1: Large number with sparkline */}22 <Card className="hover:shadow-md transition-shadow">23 <CardContent className="p-4">24 <p className="text-sm text-muted-foreground mb-1">Total Revenue</p>25 <p className="text-2xl font-bold mb-2">$84,520</p>26 <div className="flex items-end gap-1 h-8">27 {sparklineData.map((val, i) => (28 <div29 key={i}30 className="flex-1 bg-gradient-to-t from-blue-500/60 to-blue-400 rounded-t-sm transition-all hover:opacity-80"31 style={{ height: `${(val / maxSparkline) * 100}%` }}32 />33 ))}34 </div>35 </CardContent>36 </Card>3738 {/* Card 2: Circular progress */}39 <Card className="hover:shadow-md transition-shadow">40 <CardContent className="p-4 flex flex-col items-center justify-center h-full">41 <div className="relative w-20 h-20">42 <svg className="w-full h-full -rotate-90" viewBox="0 0 36 36">43 <path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="rgb(226 232 240)" strokeWidth="3" />44 <path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="rgb(139 92 246)" strokeWidth="3" strokeDasharray="78, 100" strokeLinecap="round" />45 </svg>46 <div className="absolute inset-0 flex items-center justify-center">47 <span className="text-lg font-bold">78%</span>48 </div>49 </div>50 <p className="text-sm text-muted-foreground mt-2">Completion</p>51 </CardContent>52 </Card>5354 {/* Card 3: Number with trend */}55 <Card className="hover:shadow-md transition-shadow">56 <CardContent className="p-4">57 <p className="text-sm text-muted-foreground mb-1">Active Users</p>58 <div className="flex items-center gap-2">59 <p className="text-2xl font-bold">12,458</p>60 <Badge className="bg-emerald-500/10 text-emerald-600 border-emerald-200 text-xs">61 ↑ 12%62 </Badge>63 </div>64 <p className="text-xs text-muted-foreground mt-2">vs last month</p>65 </CardContent>66 </Card>6768 {/* Card 4: Progress bar */}69 <Card className="hover:shadow-md transition-shadow">70 <CardContent className="p-4">71 <div className="flex items-center justify-between mb-2">72 <p className="text-sm text-muted-foreground">Storage Used</p>73 <span className="text-sm font-semibold">67%</span>74 </div>75 <Progress value={67} className="h-2" />76 <p className="text-xs text-muted-foreground mt-2">67 GB of 100 GB</p>77 </CardContent>78 </Card>7980 {/* Card 5: Two numbers with divider */}81 <Card className="hover:shadow-md transition-shadow">82 <CardContent className="p-4">83 <div className="flex items-center justify-around h-full">84 <div className="text-center">85 <p className="text-2xl font-bold text-blue-500">842</p>86 <p className="text-xs text-muted-foreground">New</p>87 </div>88 <div className="h-8 w-px bg-border" />89 <div className="text-center">90 <p className="text-2xl font-bold text-violet-500">156</p>91 <p className="text-xs text-muted-foreground">Closed</p>92 </div>93 </div>94 </CardContent>95 </Card>9697 {/* Card 6: Number with trend dots */}98 <Card className="hover:shadow-md transition-shadow">99 <CardContent className="p-4">100 <p className="text-sm text-muted-foreground mb-1">Conversion Rate</p>101 <p className="text-2xl font-bold mb-2">3.24%</p>102 <div className="flex gap-1">103 {[1, 1, 1, 0.8, 0.6, 0.9, 1].map((opacity, i) => (104 <div105 key={i}106 className="w-2 h-2 rounded-full bg-emerald-500"107 style={{ opacity }}108 />109 ))}110 </div>111 </CardContent>112 </Card>113 </div>114 </CardContent>115 </Card>116 )117}