Animated React charts and dashboard widgets
Activity grid
A year of daily activity as a heatmap that sweeps in while the totals count up. Hover a day to light its row and column; it fits whatever width you give it.
Charts, in view, then hover, keys and resize, Motion
Install
npm i clsx motion tailwind-merge && curl -o components/activity-grid.tsx https://motion-brew.com/r/activity-grid.tsxOne self contained file for React and Tailwind CSS: activity-grid.tsx. Or ask your AI agent to add it through the MCP server.
Usage
import { ActivityGrid } from "@/components/activity-grid";
// One value per day, oldest first; the last one is today.
const sessions: number[] = await getDailySessions();
export default function Page() {
return <ActivityGrid title="Focus sessions" unit="session" data={sessions} className="max-w-3xl" />;
}Props
| Prop | Type | Default | Description | |||||
|---|---|---|---|---|---|---|---|---|
| title | string | "Focus sessions" | Card title | |||||
| data | number[] | a sample year | One value per day, oldest first, the last one is today | |||||
| endDate | Date | today | The last day in data | |||||
| unit | string | "session" | What is counted, singular | |||||
| palette | "ink" \ | "green" \ | "violet" \ | "mint" \ | "amber" \ | "sky" | "ink" | One colour in four tints and shades; ink turns light in dark mode |
| colors | [string, string, string, string] | Your own four level colours, quietest to busiest; overrides palette | ||||||
| cellSize | number | 11 | Preferred square size in px; grows to 16 when the year fits | |||||
| showStats | boolean | true | Show the total and streak tiles | |||||
| className | string | Placement and width; the grid fits whatever width it is given |
More charts
- Channel mix: A marketing card where a row of slim ticks splits the week's sessions by channel.
- Device traffic: Visitors by device on tall gauges, one color each, that fill to each share.
- Range chart: A daily range chart, like heart rate, over 7, 15 or 30 days.
- Deploy streak: A shipping streak: the count rolls up while a grid of daily deploys pops in as a wave.