Contribution City
A year of contributions as a 3D city, one tower per day, as tall as the day was busy. Drag to orbit, double-click to reset.
Features
- Draws each day as a box on a canvas, with heights on a square-root scale so quiet days still rise beside busy ones.
- The towers grow in a wave across the year when the city first scrolls into view.
- Drag to orbit, with a little inertia. Double-click to reset, and use the arrow keys to turn it.
- Hover a tower, or tap it on touch screens, to see the day's count.
- Colors come from CSS variables and update live when the theme changes.
- No dependencies beyond React. It takes the same data shape as GitHub Contributions.
Installation
pnpm dlx shadcn@latest add @kenawak/contribution-city
Usage
import { ContributionCity } from "@/components/contribution-city"<ContributionCity data={contributions} />data is a list of days, oldest first, each with a date (YYYY-MM-DD), a count, and a level from 0 to 4. The GitHub Contributions API returns this shape.
Anything passed as children is laid over the city, which is useful for stats in its empty corners. The overlay lets pointer events through, so dragging still works under it.
<ContributionCity data={contributions}>
<p className="absolute top-3 right-0 text-4xl font-semibold">1,231</p>
</ContributionCity>Theming
Set these CSS variables on the component, or on any parent. Use opaque colors: towers look wrong when you can see through them.
| Variable | Used for |
|---|---|
--contribution-city-level-{0-4} | Each activity level |
--contribution-city-highlight | Mixed into a hovered tower |
--contribution-city-label | Month names |
API reference
ContributionCity
Prop
Type
Pass a stable months array, for example a constant. A new array on every render resets the view.