Component reference

Contribution Graph

A year of activity, one cell per day. From an editorial heatmap to a drum you can spin.

<ContributionGraph variant="minimal" />Clean surfaces and measured motion.

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-graph
↳You own the source. Ovio components arrive in your codebase so you can edit any part of their style, behavior, or data flow.

Usage

Set the visual world on the component, or wrap the page in an OvioProvider to set a default for everything inside it.

TSXvariant="minimal"
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
SourceGitHub's GraphQL API: the contribution calendar on a user's profile.
AuthRequired. GraphQL rejects anonymous requests; any GITHUB_TOKEN works.
LimitsOne query per refresh, against 5,000 points an hour per token.
CachingCached 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 demoLive 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.

PropTypeDescription
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.
endDatestringLast day shown. Defaults to the latest date in data.
compactMonthsnumberMonths 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) => voidHover and keyboard focus; null when they leave.
classNamestringMerged onto the root.