no. 26 · extras
Contribution grid
A github-style activity grid tinted with your accent colour.
Install
npx shadcn@latest add https://curio-components.vercel.app/r/contribution-grid.jsonFirst curio component? Also add @import "./curio.css"; to your global CSS. See installation.
Usage
import { ContributionGrid } from '@/components/curio/extras/contribution-grid'
// weeks[w][d] is a level from 0 to 4 (or -1 for no day)
export function Activity({ weeks }: { weeks: number[][] }) {
return <ContributionGrid weeks={weeks} total={612} title="@you" href="https://github.com/you" />
}Tip: github-contributions-api.jogruber.de returns these levels for any username, no token needed.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| weeks | number[][] | - | Levels 0 to 4 per day, grouped by week. |
| total | number | - | Shown top-right. |
| title | string | - | Shown top-left. |
| cell | number | 11 | Cell size in px. |
Source
This is exactly what the command copies into your project.
components/curio/extras/contribution-grid.tsx
// github-style activity grid. weeks[w][d] = level 0..4, or -1 for "no day"
// colours are mixed from --curio-accent so it follows your theme.
const level = (l: number) =>
l < 0
? 'transparent'
: l === 0
? 'color-mix(in srgb, var(--curio-fg) 8%, transparent)'
: l === 4
? 'var(--curio-accent)'
: `color-mix(in srgb, var(--curio-accent) ${[0, 28, 52, 76][l]}%, var(--curio-bg))`
export function ContributionGrid({
weeks,
total,
title,
href,
cell = 11,
}: {
weeks: number[][]
total?: number
title?: string
href?: string
cell?: number
}) {
return (
<a href={href} target="_blank" rel="noopener noreferrer" className="block w-fit p-3.5" style={{ color: 'var(--curio-fg)' }}>
{(title || total !== undefined) && (
<div className="mb-3 flex items-baseline justify-between gap-6 text-[13px]">
<span className="font-medium">{title}</span>
{total !== undefined && (
<span className="text-xs" style={{ color: 'var(--curio-muted)' }}>
{total.toLocaleString()} contributions
</span>
)}
</div>
)}
<div className="flex gap-[3px]">
{weeks.map((week, w) => (
<div key={w} className="flex flex-col gap-[3px]">
{week.map((l, d) => (
<span key={d} className="block" style={{ width: cell, height: cell, background: level(l) }} />
))}
</div>
))}
</div>
<div className="mt-2.5 flex items-center justify-end gap-[3px] text-[11px]" style={{ color: 'var(--curio-muted)' }}>
Less
{[0, 1, 2, 3, 4].map((l) => (
<span key={l} className="block h-[8px] w-[8px]" style={{ background: level(l) }} />
))}
More
</div>
</a>
)
}