Heatmap
A value matrix — rows × columns of cells tinted by value — rendered as a navigable table.
@garn/ui/heatmapDefault
Weekly retention by signup cohort (%).
| W0 | W1 | W2 | W3 | W4 | |
|---|---|---|---|---|---|
| Jan | 100% | 62% | 48% | 40% | 34% |
| Feb | 100% | 70% | 55% | 47% | 41% |
| Mar | 100% | 58% | 44% | 38% | 30% |
| Apr | 100% | 66% | 52% | 45% | 39% |
| May | 100% | 73% | 60% | 51% | 45% |
Installation
garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.
npx garn-ui add heatmap- Registry
heatmap- Source
- heatmap.tsx
- Deps
- None
- Registry deps
utils
Import
import { Heatmap } from "@garn/ui/heatmap";Props
Generated from the component's TypeScript types.
captionRequired- Description
- Accessible table caption (visually hidden).
- Type
string
color- Description
- Cell tint (token ref).
- Type
string
columnsRequired- Description
- Column labels (x axis) — one per column.
- Type
string[]
max- Description
- Value mapped to full intensity (default: the largest value).
- Type
number
rowsRequired- Description
- Row labels (y axis) — one per row.
- Type
string[]
valueFormatter- Description
- Format a cell's value for the hover title + screen-reader text.
- Type
(value: number) => string
valuesRequired- Description
- Row-major matrix of values: `values[rowIndex][colIndex]`.
- Type
number[][]
Plus 287 inherited native <table> attributes.
Styling
Target these data-slots and remap these tokens to restyle without forking the component.
[data-slot="heatmap"][data-slot="heatmap-cell"]Overview
Heatmap renders a value matrix — cohort retention, correlation, hour×day activity — as an actual <table> with row and column headers, its cells tinted by value. Building it as a table (not an SVG) means it's navigable and readable to assistive tech for free, while the colour gives sighted users the at-a-glance pattern. For an unlabelled calendar-style density grid, use Activity Grid instead.
Guidelines
It's tabular data — keep it a table. Row/column headers and a caption make the matrix navigable; the colour is a second, decorative channel over an accessible base.
One hue, opacity by value. Cells tint a single --garn-chart-* token; intensity is value/peak (floored so low-but-nonzero cells stay visible). Provide a valueFormatter (e.g. %) so the hover/sr value reads right.
Constrain the width. It ships w-fit so a global full-width table style doesn't stretch the cells; keep cells squarish for a readable matrix.
Best practices
- Provide row/column labels + a
caption; use avalueFormatter. - Keep the matrix modest in size so cells stay legible.
- Don't drop the headers/caption — they're what makes it accessible.
- Don't map cells to unrelated hues; intensity is one token.
Accessibility
- Role
table
- • A real `<table>` with a `<caption>` and scoped row/column headers — navigable by assistive tech.
- • Each cell exposes its value via visually-hidden text; the colour is decorative.
- • Cell intensity = value / peak opacity of a `--garn-chart-*` token (floored so low values stay visible).
- Status
- Stable
- Version
v0.3.0- Introduced
v0.2.0
garn doesn't yet record a per-release version history. This reflects the component's current lifecycle state; full changelog entries will appear once the metadata pipeline emits a lifecycle.history field.