- Gallery
- Dashboard & Analytics
- HeatmapGrid
New
HeatmapGrid
GitHub-style contribution heatmap with intensity coloring and tooltip labels
Dashboard & Analyticsheatmapcontributionsgridactivity
Dependencies
shadcn/ui components needed:
npx shadcn@latest add cardnpx shadcn@latest add tooltipHow 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, CardHeader, CardTitle } from "@/components/ui/card"5import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"6import { cn } from "@/lib/utils"78interface HeatmapGridProps {9 data?: number[][]10 className?: string11}1213const intensityColors = [14 "bg-muted",15 "bg-emerald-200",16 "bg-emerald-400",17 "bg-emerald-500",18 "bg-emerald-700",19]2021export function HeatmapGrid({ data = Array.from({ length: 7 }, () => 22 Array.from({ length: 24 }, () => Math.floor(Math.random() * 5))23), className }: HeatmapGridProps) {24 const days = ["Mon", "Wed", "Fri"]25 const months = ["Jan", "Feb", "Mar", "Apr"]2627 return (28 <Card className={cn("w-full", className)}>29 <CardHeader>30 <CardTitle>Contributions</CardTitle>31 </CardHeader>32 <CardContent>33 <TooltipProvider>34 <div className="flex gap-1">35 <div className="flex flex-col justify-around pr-2 text-xs text-muted-foreground">36 {days.map((day, i) => (37 <span key={i} className="h-3 flex items-center">{day}</span>38 ))}39 </div>40 <div className="flex-1 overflow-x-auto">41 <div className="flex gap-1 min-w-max">42 {data[0].map((_, colIndex) => (43 <div key={colIndex} className="flex flex-col gap-1">44 {colIndex % 6 === 0 && (45 <span className="text-xs text-muted-foreground h-3 flex items-center">46 {months[Math.floor(colIndex / 6)] || ""}47 </span>48 )}49 {data.map((row, rowIndex) => {50 const intensity = row[colIndex]51 return (52 <Tooltip key={rowIndex}>53 <TooltipTrigger asChild>54 <div55 className={cn(56 "w-3 h-3 rounded-sm transition-all duration-200 hover:ring-2 ring-primary/50 cursor-pointer",57 intensityColors[intensity]58 )}59 />60 </TooltipTrigger>61 <TooltipContent>62 <p>{intensity} contributions</p>63 </TooltipContent>64 </Tooltip>65 )66 })}67 </div>68 ))}69 </div>70 </div>71 </div>72 <div className="flex items-center justify-end gap-2 mt-4 text-xs text-muted-foreground">73 <span>Less</span>74 {intensityColors.map((color, i) => (75 <div key={i} className={cn("w-3 h-3 rounded-sm", color)} />76 ))}77 <span>More</span>78 </div>79 </TooltipProvider>80 </CardContent>81 </Card>82 )83}