Heatmap
Calendar-style heatmap grid with 4-level cyan-intensity palette, Radix tooltips, and keyboard-activatable cells.
Heatmap
Grid of colored cells with configurable cell size, gap, radius, and color scale. 4-level default palette interpolates from dim cyan → brand cyan → bright cyan (Vandoko cool spectrum). Radix tooltips on hover, keyboard-activatable cells when onCellClick is provided, and a cross-hair marker for empty cells.
Installation
$npx shadcn@latest add @vandoko/heatmapUsage
import { Heatmap } from "@/components/heatmap";
const values = [
[0, 0.2, 0.5, 0.8, 1.0],
[0.1, 0.3, 0.7, 0.9, 0.4],
[null, 0.2, 0.6, 0.3, 0.8],
];
export default function Page() {
return (
<Heatmap
values={values}
cellLabel={(v, r, c) =>
`Row ${r + 1}, Col ${c + 1}: ${v?.toFixed(2) ?? "—"}`
}
aria-label="Activity heatmap"
/>
);
}Interactive Cells
<Heatmap
values={values}
onCellClick={(v, r, c) => console.log("clicked", { v, r, c })}
onCellHover={(v, r, c) => console.log("hover", { v, r, c })}
/>Custom Palette
<Heatmap
values={values}
colors={[
"oklch(0.40 0.08 285)",
"oklch(0.60 0.11 285)",
"oklch(0.80 0.15 285)",
"oklch(0.93 0.18 285)",
]}
/>Blueprint Composition (Cyan Ramp)
For editorial / prestige surfaces — small grids that read as texture rather than
data — pass the --rank-* cyan ramp via the colors prop and tighten the cell
geometry. Pair with a parent group class so hover illumination uses
group-hover: Tailwind transitions.
<Heatmap
values={values}
cellSize={14}
cellGap={3}
cellRadius={2}
colors={[
"var(--rank-2)",
"var(--rank-3)",
"var(--rank-4)",
"var(--brand-cyan)",
]}
showTooltip={false}
/>This is the composition the registry's own landing uses inside its BlueprintPanel
section — heatmap renders still on mount, hover illumination is the ritual.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
values | (number | null | undefined)[][] | — | 2D grid of cell values (required) |
min | number | 0 | Minimum value (maps to level 0) |
max | number | auto | Maximum value. Auto-detected from values when omitted |
colors | string[] | Cyan ramp (4) | Color per level — array length = level count |
cellSize | number | 14 | Cell width/height (px) |
cellGap | number | 3 | Gap between cells (px) |
cellRadius | number | 2 | Cell border radius (px) |
cellLabel | (value, row, col) => string | — | Custom tooltip/ARIA label per cell |
onCellClick | (value, row, col, event) => void | — | Enables keyboard + mouse interaction |
onCellHover | (value, row, col) => void | — | Fires on mouse-enter + focus |
showTooltip | boolean | true | Render Radix tooltips on hover |
tooltipDelay | number | 100 | delayDuration for Radix Tooltip.Provider |
tooltipClassName | string | — | Extra classes on tooltip content |
Features
- 4-level cyan-intensity scale — Vandoko cool spectrum via oklch
- Radix tooltips — Optional, with Portal + Arrow + collision padding
- Keyboard accessible —
Enter/SpacetriggeronCellClickwhen interactive - Empty-cell marker — Cross-hair glyph for
null/undefined/zero cells - Auto-sized — Columns widen to the longest row; max is inferred from data when omitted
Lineage
| Property | Value |
|---|---|
| Source | @vandoko/heatmap |
| Curated | 2026-04-21 |
| License | MIT |
| Dependencies | radix-ui |