Skip to content

shadcn.io is an independent project built on shadcn/ui

Heatmap Chart with a Gradient Legend

Six months of contributions with a continuous gradient bar for a legend instead of swatches. For React with TanStack Charts, in your shadcn/ui theme: the live chart, its code and a one-line install.

Charting library: TanStack Charts

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Usage

import { ChartHeatmapGradientLegend } from "@/components/charts/chart-heatmap-gradient-legend";
<ChartHeatmapGradientLegend />

API Reference

HeatmapInteractionProvider

PropType
childrenReactNode
coordinator?HeatmapHoverCoordinator

HeatmapInteractionBoundary

PropType
childrenReactNode
className?string
style?CSSProperties

HeatmapChart

PropType
dataHeatmapColumn[]

Column data: one entry per week (or category) with the row bins inside.

xDomain?[Date, Date]

Visible time range. Only week columns that overlap the domain are drawn.

sizingColumnCount?number

Accepted for bklit compatibility; it has no effect.

layout?"fluid" | "fill"

"fluid": the width drives square cells and the chart height hugs the grid (GitHub style). "fill": cells expand to fill the parent.

Type
"fluid" | "fill"
Default
"fluid"
margin?Readonly<Partial<HeatmapMargin>>

Chart margins in pixels. Omitted sides keep their default.

Type
Readonly<Partial<HeatmapMargin>>
Default
{ top: 28, right: 16, bottom: 0, left: 40 }
binSize?number

Fixed cell size in pixels. When 0, cells are square and sized to fit the available width.

Default
0
gap?number

Gap between cells in pixels.

Default
2
colorScale?(count: number | null | undefined) => string

Replaces the default level color scale. Receives a count and returns a CSS color.

Type
(count: number | null | undefined) => string
levelColors?HeatmapLevelColors

Colors for the five levels of the Less to More scale (empty plus four activity levels).

Default
the `--chart-scale-01` to `--chart-scale-05` CSS variables
levelStyles?HeatmapLevelStyles

Per-level fill styles (color and optional pattern). Takes precedence over levelColors.

aspectRatio?string

CSS aspect ratio of the outer container, for example "2 / 1". Omit to fill the parent.

className?string

Additional class name for the chart container.

status?ChartStatus

Data status. "loading" draws the shimmering skeleton cells.

Default
"ready"
loadingLabel?string

Centered label shown while status is "loading".

animationDuration?number

Enter animation duration in milliseconds. 0 disables the cell entrance.

Default
1600
enterTransition?HeatmapEnterTransition

Enter transition. duration is in seconds and ease a cubic-bezier tuple.

Default
{ type: "tween", duration: 1.6, ease: [0.85, 0, 0.916, 0.282] }
revealSignature?string

Changing this string replays the enter animation.

Default
""
enterStaggerScale?number

Scales the wave stagger between cells (1 is the default pacing).

Default
1
animate?boolean

Plays the enter fade-in and the loading shimmer. Set to false for no motion.

Default
true
loadingOpacity?number

Chart opacity while loading. Ours is 1; bklit-ui uses 0.5.

Default
1
showLoadingCells?boolean

Shows the shimmering skeleton cells while loading.

Default
true
loadingCellMaxOpacity?number

Highest opacity (0 to 1) the loading cells animate toward. Ours is 0.85; bklit-ui uses 0.5.

Default
0.85
loadingCellRandomness?number

Share of cells (0 to 1) that take part in the loading shimmer. Ours is 1; bklit-ui uses 0.65.

Default
1
columnSeparators?HeatmapSeparatorParsedConfig

Inserts horizontal gaps between groups of columns. A HeatmapSeparator child overrides it.

weekStartDay?HeatmapWeekStartDay

First row of the grid: 0 is Sunday (GitHub default), 1 Monday, and so on. Rotates the rows for display without reshaping your data.

Default
0
children?ReactNode

HeatmapCells, HeatmapXAxis, HeatmapYAxis, HeatmapTooltip and HeatmapSeparator configuration children. HeatmapCells is required for the grid to draw.

ariaLabel?string

Accessible name of the chart.

Default
"Heatmap chart"
ariaDescription?string

Accessible description of the chart. Falls back to the ariaDescription of HeatmapCells.

HeatmapCells

PropType
cornerRadius?number

Corner radius of each cell in pixels.

Default
2
colorScale?(count: number | null | undefined) => string

Overrides the chart color scale for the cells. Receives a count and returns a CSS color.

Type
(count: number | null | undefined) => string
inactiveOpacity?number

Opacity of the cells that are not highlighted while hovering a cell or a legend level.

Default
0.3
inactiveScale?number

Scale of the cells that are not highlighted while hovering.

Default
1
activeScale?number

Scale of the highlighted cell while hovering.

Default
1
rowOpacity?number | readonly number[]

Opacity per display row (row 0 is the top row after weekStartDay rotation). A single number applies to every row; an array gives one value per row. Pass the same value to HeatmapYAxis to keep labels aligned.

Type
number | readonly number[]
Default
1
interactive?boolean

Enables pointer hover, dimming, tooltip and keyboard focus on the cells.

Default
true
hideGhostCells?boolean

Hides the out-of-range cells at the start and end of the grid (GitHub style).

Default
true
ariaLabel?string

Accessible name of the chart. HeatmapChart ariaLabel takes precedence.

ariaDescription?string

Accessible description of the chart. HeatmapChart ariaDescription takes precedence.

HeatmapXAxis

PropType
className?string

Accepted for bklit compatibility; it has no effect.

HeatmapYAxis

PropType
className?string

Accepted for bklit compatibility; it has no effect.

tickFilter?HeatmapYAxisTickFilter

Which rows get a weekday label: every row, odd rows (Mon, Wed, Fri with a Sunday start) or even rows.

Default
"odd"
labelFormat?HeatmapYAxisLabelFormat

"full" shows the abbreviated weekday (Mon); "initial" shows its first letter (M).

Default
"full"
rowOpacity?number | readonly number[]

Opacity per display row for the labels. Pass the same value as HeatmapCells so faded rows and their labels stay aligned.

Type
number | readonly number[]

HeatmapTooltip

PropType
formatLabel?(count: number, date: Readonly<Date>) => string

Custom text for the contribution line of the tooltip. Receives the count and the cell date.

Type
(count: number, date: Readonly<Date>) => string
Default
`N contribution(s)`
className?string

Additional class name for the tooltip panel.

panelStyle?Readonly<CSSProperties>

Inline styles for the tooltip panel.

Type
Readonly<CSSProperties>
backgroundColor?string

Background of the tooltip panel (a CSS color or variable).

instant?boolean

Shows and hides the tooltip without enter or exit motion; the hide is still held for hideDelay.

Default
false
showDelay?number

Delay in milliseconds before the tooltip first appears. Moving between cells updates it immediately.

Default
0
hideDelay?number

Hold in milliseconds after the pointer leaves a cell before the tooltip hides. Reduces flicker between adjacent cells.

Default
120

HeatmapLegend

PropType
lessLabel?string

Label before the swatches.

Default
"Less"
moreLabel?string

Label after the swatches.

Default
"More"
cellSize?number

Swatch size in pixels.

Default
11
gap?number

Gap between swatches in pixels.

Default
2
cornerRadius?number

Corner radius of the swatches in pixels.

Default
2
align?"start" | "center" | "end"

Horizontal alignment of the legend.

Type
"start" | "center" | "end"
Default
"end"
variant?HeatmapLegendVariant

Discrete swatches or a continuous gradient bar. The gradient uses solid colors only; patterns are ignored.

Default
"swatches"
gradientSpan?number

Width of the gradient bar in swatch units when variant is "gradient".

Default
5
fontSize?number

Font size in pixels of the Less and More labels.

Default
12
labelClassName?string

Additional class name for the Less and More labels.

levelStyles?HeatmapLevelStyles

Level colors and patterns. Pass the same value as the chart so swatches match the cells.

colorScale?(count: number | null | undefined) => string

Color scale used when levelStyles is omitted.

Type
(count: number | null | undefined) => string
Default
the default level colors
inactiveOpacity?number

Opacity of the swatches that are not highlighted while hovering.

Default
0.3
inactiveScale?number

Scale of the swatches that are not highlighted while hovering.

Default
1
activeScale?number

Scale of the highlighted swatch while hovering.

Default
1
interactive?boolean

Syncs the swatch dimming with the chart hover.

Default
true inside a HeatmapInteractionProvider, false otherwise
className?string

Additional class name for the legend container.