Heatmap Grid

A calendar heatmap — weeks as columns, weekdays as rows. UptimeStrip is the one-dimensional case; this is the grid.

src/components/ui/heatmap-grid.tsx

About

From the component's own source, where it was written.

A calendar heatmap — the contribution grid.

Weeks are columns and weekdays are rows, which is the layout everyone reads without a legend. Building it means padding to a week boundary at both ends; without that the first column starts on the wrong weekday and every row is shifted by a day.

Intensity is bucketed rather than continuous. Five steps is what the eye can actually distinguish in a 10px square, and a smooth gradient just makes neighbouring cells look identical.

Install

npx astralyx-ui add heatmap-grid

Usage

import { HeatmapGrid } from '@/components/ui/heatmap-grid'

<HeatmapGrid cells={cells} />

Composer

Change the props and the source below follows.

MonWedFri
MarAprMayJunJulAug
LessMore
Props
tsx
<HeatmapGrid
  cells={cells}
  showMonths={true}
  showWeekdays={true}
/>

Examples

Contributions

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

HeatmapGrid

Extends Omit<ComponentProps<'div'>, 'children'>.

PropTypeDefaultDescription
colorstring'var(--green)'—
cellsHeatmapCell[]required{ date, value, detail? }. Gaps are filled with zero-value days so the grid stays continuous.
levelsnumber5Intensity buckets. A smooth gradient makes neighbouring 11px squares look identical.
localestring'en-GB'—
showMonthsbooleantrue—
showWeekdaysbooleantrue—
lessLabelReactNode'Less'Ends of the intensity legend.
moreLabelReactNode'More'—
summaryLabel(total: number, days: number) => stringDEFAULT_SUMMARY_LABELAccessible summary of the whole grid.

Types

HeatmapCell

A calendar heatmap — the contribution grid.

FieldTypeDescription
dateDate—
valuenumber—
detail?ReactNode—

Behaviour

TopicDetailDescription
week alignmentMonday-firstPadded to a week boundary at both ends; without that the first column starts on the wrong weekday and every row is shifted a day.