Activity Heatmap
Calendar activity matrix showing contribution intensity over a year with keyboard navigation.
| Nov | Dec | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mon | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Tue | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Wed | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Thu | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Fri | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sat | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sun |
Keyboard
- โโโโ
- Move through the calendar grid
- HomeEnd
- First or last week in the row
- EnterSpace
- Select the focused day
- Escape
- Dismiss the hover or focus tooltip
The CLI also installs the npm packages and registry items it builds on, and reads the style in your components.json to pick the Base UI or Radix build.
import { ActivityHeatmap } from "@/components/ui/activity-heatmap"
const DATA = [
{ date: "2026-10-30", count: 3 },
{ date: "2026-10-31", count: 7 },
]
export function ContributionGraph() {
return (
<ActivityHeatmap
data={DATA}
weekStartsOn={1}
onDaySelect={(day) => console.log(day.date, day.count)}
/>
)
}ActivityHeatmap
Displays activity intensity over a year in a WAI-ARIA grid with 2D keyboard navigation and accessible cell labels.
| Prop | Type | Default |
|---|---|---|
dataRequiredActivityDayInput[]Array of daily activity objects with date (YYYY-MM-DD), count, and optional level override. | ActivityDayInput[] | |
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 6Default0Starting day of the week (0 for Sunday, 1 for Monday). | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 |
startDatestringEarliest calendar date in YYYY-MM-DD. Defaults to 52 weeks before endDate. | string | |
endDatestringLatest calendar date in YYYY-MM-DD. Defaults to latest date in data or today. | string | |
selectedDatestring | nullControlled selected date in YYYY-MM-DD. | string | null | |
defaultSelectedDatestring | nullInitial selected date when uncontrolled. | string | null | |
onDaySelect(day: ActivityDay) => voidCallback invoked when a day cell is selected. | (day: ActivityDay) => void | |
thresholdsnumber[]Four-element array of count thresholds separating intensity levels 1 through 4. | number[] | |
unitstringDefault"contributions"Noun describing the activity unit for screen readers and summary. | string | "contributions" |
showSummarybooleanDefaulttrueWhether to display the total activity summary header. | boolean | true |
summaryReactNode | ((total: number, start: string, end: string) => ReactNode)Custom summary content or render function. | ReactNode | ((total: number, start: string, end: string) => ReactNode) | |
showLegendbooleanDefaulttrueWhether to render the Less/More intensity level key. | boolean | true |
showMonthLabelsbooleanDefaulttrueWhether to render month labels above week columns. | boolean | true |
showWeekdayLabelsbooleanDefaulttrueWhether to render weekday labels along the left side. | boolean | true |
levelColorsRecord<number, string>Custom CSS class overrides for intensity levels 0 through 4. | Record<number, string> | |
showTooltipbooleanDefaulttrueWhether to render a floating tooltip on hover and focus. | boolean | true |
renderTooltip(day: ActivityDay) => ReactNodeCustom tooltip content render function receiving the active day. | (day: ActivityDay) => ReactNode | |
aria-labelstringDefault"Activity heatmap"Accessible label for the grid widget. | string | "Activity heatmap" |
Other props go to the div.
Basic activity calendar
Display daily activity levels over six months with a Monday week start.
| May | Jun | Jul | Aug | Sep | Oct | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mon | |||||||||||||||||||||||||||
| Tue | |||||||||||||||||||||||||||
| Wed | |||||||||||||||||||||||||||
| Thu | |||||||||||||||||||||||||||
| Fri | |||||||||||||||||||||||||||
| Sat | |||||||||||||||||||||||||||
| Sun |
Interactive day selection
Controlled day selection revealing detailed counts and intensity level in a callout.
| Oct | |||||
|---|---|---|---|---|---|
| Sun | |||||
| Mon | |||||
| Tue | |||||
| Wed | |||||
| Thu | |||||
| Fri | |||||
| Sat |
Selected date: 2026-10-31 with 9 commits (Intensity level 4 of 4).
Custom thresholds & units
Map discrete count bands to intensity levels with custom units and summary formatting.
| Oct | |||||
|---|---|---|---|---|---|
| Mon | |||||
| Tue | |||||
| Wed | |||||
| Thu | |||||
| Fri | |||||
| Sat | |||||
| Sun |
Custom tooltip formatting
Render a rich floating tooltip with intensity badges and activity breakdown on hover and focus.
| May | Jun | Jul | Aug | Sep | Oct | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mon | |||||||||||||||||||||||||||
| Tue | |||||||||||||||||||||||||||
| Wed | |||||||||||||||||||||||||||
| Thu | |||||||||||||||||||||||||||
| Fri | |||||||||||||||||||||||||||
| Sat | |||||||||||||||||||||||||||
| Sun |