Activity heatmap
See a year of activity at a glance, one square per day.
npm install https://animui.stracture.net/__local/package.tgzcontributions in 1,170 contributions in 2025
Tuesday, March 18: 4 commits, 2 pull requests and 2 reviews, mostly in design-tokens.
- Daily rhythm over a long range, like contributions or workouts.
- Views where streaks and quiet weeks matter more than exact comparison.
- Use bar-chart when the exact comparison is the point.
- Use calendar to pick dates.
Installation
Install animui once, then import any component or block from its typed package entry.
React 19 and React DOM 19 are required. The package includes Free and Pro entries, styles and TypeScript declarations.
npm install https://animui.stracture.net/__local/package.tgzLoad the stylesheet once at your app root, then use the typed component import:
import 'animui/styles.css';
import { ActivityHeatmap } from 'animui/activity-heatmap';Read the Code tab for the implementation files and the API reference below for required props.
Download animui 0.3.0 · Agent guideimport { useState } from "react";import { ActivityHeatmap } from "animui/activity-heatmap"; export function Contributions({ days }: { days: { date: string; count: number }[] }) { const [selected, setSelected] = useState<string | null>(null); return ( <ActivityHeatmap days={days} label="Contributions in 2026" period="2026" selectedDate={selected} onSelectDate={setSelected} /> );}ActivityHeatmap
A contribution style calendar with one tinted square per day and a hover or focus tooltip.
daysRequired{ date: string; count: number }[]–One entry per day as YYYY-MM-DD, oldest first. Missing days count as zero.labelRequiredstring–Accessible name for the grid, such as "Contributions in 2025".periodRequiredstring–Finishes the summary: "1,284 contributions in {period}".unit{ one: string; other: string }{ one: "contribution", other: "contributions" }Nouns for the count.thresholds[number, number, number]–Upper bounds for levels one to three. Defaults to quarters of the busiest day.weekStartsOn0 | 10Sunday or Monday as the first row.selectedDatestring | nullnullDay drawn with a selection ring.onSelectDate(date: string) => void–Called on click, Enter, or Space.actionsReactNode–Controls beside the summary, such as a range switch.localestring"en-US"Formatting locale.classNamestring–Class for the root.- ArrowUporArrowDown
- Moves one day back or forward.
- ArrowLeftorArrowRight
- Moves one week back or forward.
- HomeorEnd
- Jumps to the first or last day.
- EnterorSpace
- Selects the focused day.
- Escape
- Hides the tooltip.
- The grid is role="grid" with labelled gridcells and a hidden legend explaining the levels.
- Legend swatches are toggle buttons with aria-pressed that highlight days of one level.
- The total and hovered day are announced through status and polite live regions; the tooltip itself is aria-hidden.
- Cells wave in once on view and a new range recolors the grid in a sweep.
- The tooltip glides between cells and its text rolls; the total counts to new values.
- Reduced motion drops the wave, sweep, and glide in favor of short fades.
- Cells scale between 9px and 15px with the container, then the grid scrolls horizontally from the newest week.
- Below a 440px container the caption switches to a short form.
- On touch the tooltip lingers after a tap instead of hiding at once.
- Every day is its own cell, so a year is about 370 elements; the reveal wave is capped in total time.
- One shared tooltip serves the whole grid.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use when rhythm, streaks, and quiet weeks matter more than exact comparison. Use bar-chart when the exact comparison is the point.
- Pass a range switch through actions and swap days to change the period.
The full library index for assistants is at /llms.txt.