Heatmap Calendar
A GitHub-style contribution heatmap. Buckets dated values into color levels across a weeks × weekdays grid, with month/weekday axis labels, a Less→More legend, per-cell tooltips, and custom palettes. Driven purely by data — no card or title scaffolding.
A GitHub-style contribution heatmap. It lays a year (or any rangeDays) of dated
values onto a weeks × weekdays grid, buckets each day's value into a color level,
and labels the months and weekdays. Days outside the range are dimmed. It is
driven purely by data — there is no card, title, or other scaffolding, so you
compose it wherever you need it.
Installation
One-time setup: add the @ikui registry to your components.json.
{
"registries": {
"@ikui": "https://ik-ui.pages.dev/r/{name}.json"
}
}Then install the component:
pnpm dlx shadcn@latest add @ikui/heatmap-calendarUsage
import { HeatmapCalendar } from "@/components/heatmap-calendar";const data = [
{ date: "2026-05-01", value: 3 },
{ date: "2026-05-02", value: 7 },
];
<HeatmapCalendar data={data} />;Each datum is a { date, value } pair; date is a Date or a YYYY-MM-DD
string (parsed as a local day). Multiple entries on the same day are summed.
Examples
Custom palette
Pass palette — an array of CSS colors for levels 0..N — to override the default
semantic classes. The legend and cells both use it, and the number of colors
defines the number of levels.
Legend placement
Configure the legend with an object. It sits below the grid by default;
placement="right" moves it to the right instead. You can also set direction,
lessText/moreText, or showText.
Custom tooltip
Use renderTooltip to control the content shown on hover. It receives the full
HeatmapCell (date, value, level, label).
Compact
Trim the range with rangeDays, shrink cellSize, and turn axisLabels and
legend off for a dense inline strip.
Props
| Prop | Type | Default |
|---|---|---|
data | HeatmapDatum[] | - |
rangeDays | number | 365 |
endDate | Date | new Date() |
weekStartsOn | 0 | 1 | 1 |
cellSize | number | 12 |
cellGap | number | 3 |
onCellClick | (cell: HeatmapCell) => void | - |
palette | string[] | - |
levelClassNames | string[] | - |
getLevel | (value: number) => number | - |
legend | boolean | LegendConfig | true |
axisLabels | boolean | AxisLabelsConfig | true |
renderLegend | (args) => React.ReactNode | - |
renderTooltip | (cell: HeatmapCell) => React.ReactNode | - |
className | string | - |
LegendConfig
| Prop | Type | Default |
|---|---|---|
show | boolean | true |
placement | "right" | "bottom" | "bottom" |
direction | "row" | "column" | "row" |
showText | boolean | true |
lessText | React.ReactNode | "Less" |
moreText | React.ReactNode | "More" |
swatchSize | number | - |
swatchGap | number | - |
AxisLabelsConfig
| Prop | Type | Default |
|---|---|---|
show | boolean | true |
showWeekdays | boolean | true |
showMonths | boolean | true |
weekdayIndices | number[] | [1, 3, 5] |
monthFormat | "short" | "long" | "numeric" | "short" |
minWeekSpacing | number | 3 |