Activity Grid
A grid of intensity-shaded cells showing activity or frequency over time (a contribution graph).
@garn/ui/activity-gridDefault
13 weeks of activity in stepped intensities.
Installation
garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.
npx garn-ui add activity-grid- Registry
activity-grid- Source
- activity-grid.tsx
- Deps
- None
- Registry deps
utils
Import
import { ActivityGrid } from "@garn/ui/activity-grid";Props
Generated from the component's TypeScript types.
color- Description
- Cell tint (token ref); empty cells use `bg-muted`.
- Type
string
itemsRequired- Description
- No description.
- Type
ActivityCell[]
levels- Description
- Intensity buckets incl. the empty level (default 5 → empty + 4 shades).
- Type
number
max- Description
- Value mapped to the highest intensity (default: the largest value).
- Type
number
rows- Description
- Grid rows; cells fill column-major (default 7 — days of a week).
- Type
number
Plus 278 inherited native <div> attributes.
Styling
Target these data-slots and remap these tokens to restyle without forking the component.
[data-slot="activity-grid"][data-slot="activity-cell"]Overview
Activity Grid is the contribution-graph widget — a compact grid where each cell's shade encodes how much happened that day (commits, logins, events). It bins values into a few intensity levels and lays cells out column-major (weeks as columns), giving the familiar at-a-glance density map. Pure CSS grid, so it renders on the server with no engine.
Guidelines
Bin, don't scale precisely. The grid shows relative intensity across a few levels, not exact counts — pair it with a total or a hover title for the real number.
One hue, stepped opacity. Cells tint a single --garn-chart-* token at increasing opacity; empty cells are muted. That keeps the density readable; don't map cells to unrelated hues.
Summarise for assistive tech. It's one role=img — give it an aria-label stating the span and takeaway; per-cell detail lives in the title.
Best practices
- Give it an
aria-labelsummary; set per-celllabelfor the hover title. - Tune
levelsandmaxto the data's range.
- Don't expect exact counts to be readable from shade alone.
- Don't use unrelated colours per cell — intensity is one hue.
Accessibility
- Role
img
- • role=img with an `aria-label` summary (e.g. "Activity — last 13 weeks").
- • Each cell carries a hover `title` and reflects its bucket via `data-level`.
- • Intensity is stepped opacity of a `--garn-chart-*` token; empty cells use `bg-muted`.
- Status
- Stable
- Version
v0.3.0- Introduced
v0.2.0
garn doesn't yet record a per-release version history. This reflects the component's current lifecycle state; full changelog entries will appear once the metadata pipeline emits a lifecycle.history field.