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 tooltip

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, CardHeader, CardTitle } from "@/components/ui/card"
5import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
6import { cn } from "@/lib/utils"
7
8interface HeatmapGridProps {
9 data?: number[][]
10 className?: string
11}
12
13const intensityColors = [
14 "bg-muted",
15 "bg-emerald-200",
16 "bg-emerald-400",
17 "bg-emerald-500",
18 "bg-emerald-700",
19]
20
21export 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"]
26
27 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 <div
55 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}

Related Dashboard & Analytics Components

Command Palette

Search for a command to run...