Heatmap
Installation
Usage
Pass daily counts with dates in YYYY-MM-DD format. Root renders the complete calendar by default. No GitHub connection is required.
Custom composition
This example omits weekday labels, moves the legend before the detail, and reads the same total as Summary. Tooltip follows the hovered or focused cell and inherits the theme’s border and glass settings. Select a day with Enter, Space, or a click.
Without a tooltip
The automatic layout includes Tooltip. In a custom layout, omit it to keep native browser titles instead. Every cell retains its accessible date and count label.
Changing the range
Keep the reporting end date fixed while switching the number of visible weeks. Summary counts only dates in that range. On narrow screens, scroll the calendar horizontally.
Data and range
Root accepts days, loading, weeks, endDate, weekStartsOn, locale, animation, and onDaySelect. Weeks defaults to 26 and supports 1 to 104. WeekStartsOn defaults to Sunday, 0, and accepts 0 through 6. Locale defaults to en-US.
Dates use UTC. Input order does not matter, missing dates receive a zero count, and the last entry wins when dates repeat. EndDate defaults to the latest supplied date, or today for an empty dataset. Set it explicitly for a stable reporting period.
The calendar starts at the beginning of the first week and stops at endDate. Totals include only visible dates. Counts must be finite and non-negative. Optional level accepts an integer from 0 to 4; otherwise intensity follows the largest visible count. Invalid values throw a RangeError.
Animation
Animation defaults to rows. Choose columns for a left-to-right stagger, live for a repeating column highlight, or none for immediate rendering. Live motion preserves contribution counts and pauses during inspection, offscreen, and in hidden documents. Entrance timing follows the theme motion setting, and reduced motion skips the entrance. The replay control remounts the example with the selected direction.
Parts
Root owns the data and provides a children snippet with days and total. Header, Calendar, and Footer arrange content. Summary provides its total to a children snippet. Grid provides computed days to a children snippet; render Cell with a day from that list. Detail provides the active day to a children snippet.
MonthLabels, WeekdayLabels, and Legend provide default labels that children can replace. Each part accepts native attributes and class. Keep Grid inside Calendar for aligned month and weekday labels.
Keyboard and accessibility
Tab enters the calendar once. Arrow keys move between dates, Home focuses the first visible date, and End focuses the last. Left and right follow the layout in RTL. Each cell announces its full date and count, so color is not the only source of information.
Hover or focus updates Detail and opens Tooltip. Escape dismisses the tooltip. Activation calls onDaySelect with the computed day. The chart scrolls horizontally when its cells cannot fit the available width.
Data and animation states
API reference
Heatmap.Root
| Prop | Type | Default |
|---|---|---|
days Required | readonly Day[] | — |
weeks | number | undefined | 26 |
loading | boolean | undefined | false |
animation | "none" | "rows" | "columns" | "live" | undefined | 'rows' |
endDate | string | undefined | — |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined | 0 |
locale | string | undefined | 'en-US' |
onDaySelect | ((day: Cell) => void) | undefined | — |
children | Snippet<[{ days: readonly Cell[]; total: number; }]> | undefined | — |
Heatmap.Calendar
Heatmap.Cell
| Prop | Type | Default |
|---|---|---|
day Required | { date: string; count: number; level: number; column: number; row: number; label: string; } | — |
Heatmap.Detail
| Prop | Type | Default |
|---|---|---|
children | Snippet<[Cell | undefined]> | undefined | — |
Heatmap.Footer
Heatmap.Grid
| Prop | Type | Default |
|---|---|---|
children | Snippet<[readonly Cell[]]> | undefined | — |
Heatmap.Header
Heatmap.Legend
Heatmap.MonthLabels
Heatmap.Summary
| Prop | Type | Default |
|---|---|---|
children | Snippet<[number]> | undefined | — |
pnpm dlx @mielui/svelte add heatmap