Installation
Use the shadcn CLI to copy the component source and its dependencies into your own project. Installs motion and @number-flow/react, plus the Ovio theme, world, motion, rolling-number, format items.
npx shadcn add JanaSundar/ovio/contribution-graphUsage
Set the visual world on the component, or wrap the page in an OvioProvider to set a default for everything inside it.
import { ContributionGraph } from "@/components/ovio/contribution-graph/contribution-graph"
<ContributionGraph
variant="minimal"
data={contributions}
/>Built with: CSS grid · Motion for React (Toy: CSS 3D drum)
Motion in Minimal: Small springs, opacity and layout shifts that show state.
Data
Fetch it on the server with getContributions(login) and pass the result as props. The helper is lib/github.ts, added with the CLI.
npx shadcn add JanaSundar/ovio/github| Source | GitHub's GraphQL API: the contribution calendar on a user's profile. |
| Auth | Required. GraphQL rejects anonymous requests; any GITHUB_TOKEN works. |
| Limits | One query per refresh, against 5,000 points an hour per token. |
| Caching | Cached for an hour by default (revalidate: 3600), so traffic adds no API calls. A failed refresh keeps serving the last good data, and a spent limit throws RateLimitError with the time it resets. |
| This demo | Live data from shadcn, through the same helper. If the API fails, the sample shows instead. |
Props
Control the data, selected world, animation behavior, and callbacks.
| Prop | Type | Description |
|---|---|---|
| data | { date: string; count: number }[] | Daily counts as YYYY-MM-DD. Gaps become zero; duplicate dates are summed. |
| variant | | "minimal" | "craft" | "retro" | "toy" | Which world to render. Defaults to the nearest OvioProvider, then minimal. |
| animation | | "none" | "enter-exit" | "always" | Default "enter-exit". "always" adds the Retro flicker and roll bar. Forced to "none" under reduced motion. |
| endDate | string | Last day shown. Defaults to the latest date in data. |
| compactMonths | number | Months shown on screens under 1024px so cells stay large. Left out, the full year scrolls sideways there. Toy always shows the year. |
| onDayHover | (day: ContributionCell | null) => void | Hover and keyboard focus; null when they leave. |
| className | string | Merged onto the root. |