Command Palette

Search for a command to run...

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.

components.json
{
  "registries": {
    "@ikui": "https://ik-ui.pages.dev/r/{name}.json"
  }
}

Then install the component:

pnpm dlx shadcn@latest add @ikui/heatmap-calendar

Usage

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

PropTypeDefault
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

PropTypeDefault
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

PropTypeDefault
show
boolean
true
showWeekdays
boolean
true
showMonths
boolean
true
weekdayIndices
number[]
[1, 3, 5]
monthFormat
"short" | "long" | "numeric"
"short"
minWeekSpacing
number
3