Contribution Heatmap React component
A year-long activity calendar in the style of a contribution graph: one square per day in week columns, five colour levels from quartiles, month and weekday labels, longest and current streaks, a best-day stat, day tooltips and a grid that fits any width.
About the Contribution Heatmap component
Contribution Heatmap is the familiar year-at-a-glance activity calendar: one square per day, arranged in week columns, with darker or brighter squares for busier days. The header adds the total, the longest and current streaks and the best day.
Colour levels come from quartiles of your active days, so one record day doesn't wash out the rest. Hover, tap or use the arrow keys to read any day, and the grid fits itself to the width, dropping the oldest weeks on small screens.
When to use it
Use it for commits and code reviews, writing or learning streaks, workouts, support tickets handled, logins or any daily count you want people to see as habits and gaps.
It shows patterns across a year; for exact day-to-day comparisons over a short period, a bar chart is clearer.
Installation
Add the Contribution Heatmap component to your project with the shadcn CLI. It lands in components/contribution-heatmap.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/contribution-heatmapOr copy the source by hand and install its dependencies:
npm install clsx tailwind-mergeProps
<ContributionHeatmap /> accepts 8 props, all optional. It also accepts the usual <div> attributes, like className, style, id and aria-*, and passes them to its root element.
| Prop | Type | Default |
|---|---|---|
| theme | "dark" | "light" | "dark" |
| title | string | "Contributions" |
| subtitle | string | — |
| data One entry per day with activity; missing days count as zero. | { date: string; count: number }[] | DEFAULT_DATA |
| endDate Last day shown (YYYY-MM-DD); the grid covers the 53 weeks up to it. | string | DEFAULT_END |
| color Colour of the busiest cells; quieter days blend it toward the empty-cell colour. | string | — |
| weekStart Week starts on Sunday (GitHub style) or Monday. | "sunday" | "monday" | "sunday" |
| unit Word for one unit of activity, used in the tooltip and stats. | [singular: string, plural: string] | ["contribution", "contributions"] |
- theme"dark" | "light"Default: "dark"
- titlestringDefault: "Contributions"
- subtitlestring
- data
One entry per day with activity; missing days count as zero.
{ date: string; count: number }[]Default: DEFAULT_DATA - endDate
Last day shown (YYYY-MM-DD); the grid covers the 53 weeks up to it.
stringDefault: DEFAULT_END - color
Colour of the busiest cells; quieter days blend it toward the empty-cell colour.
string - weekStart
Week starts on Sunday (GitHub style) or Monday.
"sunday" | "monday"Default: "sunday" - unit
Word for one unit of activity, used in the tooltip and stats.
[singular: string, plural: string]Default: ["contribution", "contributions"]
npm dependencies
Installed for you by the shadcn CLI.
Contribution Heatmap FAQ
- What data does it need?
- data is { date: "YYYY-MM-DD", count }[] for days with activity; any day not listed counts as zero. endDate sets the last day shown and the grid covers the 53 weeks before it.
- How are the colour levels chosen?
- Empty days use the base cell colour. Active days are split into four levels at the 25th, 50th and 75th percentile of the active days, and color sets the brightest shade.
- Can the week start on Monday?
- Yes, weekStart="monday" moves Monday to the top row. unit changes the words in the tooltip and stats, for example ["workout", "workouts"].
- What happens on small screens?
- Cells shrink to 10px; if a full year still doesn't fit, the oldest weeks are dropped and the footer says how many weeks are shown.