# ContributionGrid

> A year of days as a grid of weeks: workouts, commits, spending. Levels mix the brand into the card, and a day with no data is drawn apart from a day with none. One Tab stop, the arrow keys walk the days, Home and End jump to the ends, and every cell says its day in words. One tooltip, kept inside the viewport. On a phone it scrolls sideways at a size you can read, starting at the latest weeks.

Section: Data. Docs: https://entrepta.vercel.app/docs/components/contribution-grid

## Install

```bash
npx @entrepta/cli@latest add contribution-grid
```

Files: `data/contribution-grid.tsx`, `feedback/skeleton.tsx`, `lib/format.ts`, `hooks/use-format.ts`, `lib/overlay.ts`.
No npm packages.
Comes with: `skeleton`, `format-lib`, `use-format`, `overlay-lib`.

## Usage

```tsx
import { ContributionGrid } from "@/components/entrepta/contribution-grid"

<ContributionGrid
  label="Workouts in the last year"
  days={days}                      // { date: "2026-09-12", level: 0-4 | null, state?: "3 workouts" }[]
  range={{ start: "2025-09-29", end: "2026-09-28" }}
  selected={day}
  onSelect={setDay}
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `days` | `{ date, level, state? }[]` | - | level 0 to 4, or null for no data; state is the day in words |
| `label` | `string` | - | What the grid shows, as its name |
| `range` | `{ start, end }` | - | Defaults to the first and last day given |
| `onSelect, selected` | `(date) => void, string` | - | Choosing a day |
| `renderTooltip` | `(day) => ReactNode` | - | The tooltip's content |
| `legend` | `boolean` | true | The Less to More key |
| `loading` | `boolean` | false | A skeleton in its shape |
| `labels` | `{ levels?, noData?, less?, more? }` | - | Every word |
