BlockDex

Components

Registries

Free blocks

Method

BlockDex

Components

Registries

Free blocks

Method

Open API

BlockDex

Components

Registries

Free blocks

Method

Open API

Components/Iconiq UI/contribution-graph

Contribution Graph

iconiq-ui/contribution-graph
FreeComponent

GitHub-style contribution calendar with compound calendar, block, total-count, and legend parts — pass raw Activity data or just a GitHub username and it fetches and caches the last year of contributions itself, shimmers a skeleton grid while loading, then fades the muted grid in and lights the greens up level by level — lightest to darkest — with springy pops, plus custom per-day tooltips and reduced-motion aware behavior.

Live preview

live · rendered by the registry
Rendered by Iconiq UI on their own page — this is the component running, not a screenshot of it.

Install it

npx shadcn@latest add https://www.iconiqui.com/r/contribution-graph.json

Source

contribution-graph.tsxwww.iconiqui.com/r/contribution-graph.json · first 6 KB
1"use client";
2
3import type { Day as WeekDay } from "date-fns";
4import {
5 differenceInCalendarDays,
6 eachDayOfInterval,
7 formatISO,
8 getDay,
9 getMonth,
10 getYear,
11 nextDay,
12 parseISO,
13 subDays,
14 subWeeks,
15} from "date-fns";
16import {
17 type CSSProperties,
18 createContext,
19 type FocusEvent,
20 Fragment,
21 type HTMLAttributes,
22 type MouseEvent,
23 type ReactNode,
24 useContext,
25 useEffect,
26 useMemo,
27 useRef,
28 useState,
29} from "react";
30import { createPortal } from "react-dom";
31import { cn } from "@/lib/utils";
32
33export type Activity = {
34 date: string;
35 count: number;
36 level: number;
37};
38
39type Week = Array<Activity | undefined>;
40
41export type Labels = {
42 months?: string[];
43 weekdays?: string[];
44 totalCount?: string;
45 legend?: {
46 less?: string;
47 more?: string;
48 };
49};
50
51type MonthLabel = {
52 weekIndex: number;
53 label: string;
54};
55
56const DEFAULT_MONTH_LABELS = [
57 "Jan",
58 "Feb",
59 "Mar",
60 "Apr",
61 "May",
62 "Jun",
63 "Jul",
64 "Aug",
65 "Sep",
66 "Oct",
67 "Nov",
68 "Dec",
69];
70
71const DEFAULT_LABELS: Labels = {
72 months: DEFAULT_MONTH_LABELS,
73 weekdays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
74 totalCount: "{{count}} activities in {{year}}",
75 legend: {
76 less: "Less",
77 more: "More",
78 },
79};
80
81/** Rolling-window label used when data comes from a GitHub username. */
82const ROLLING_TOTAL_LABEL = "{{count}} contributions in the last year";
83
84/** GitHub-style green level ramp, shared by blocks and the legend. */
85const LEVEL_CLASSES = cn(
86 'data-[level="0"]:fill-muted',
87 'data-[level="1"]:fill-emerald-200 dark:data-[level="1"]:fill-emerald-900',
88 'data-[level="2"]:fill-emerald-400 dark:data-[level="2"]:fill-emerald-700',
89 'data-[level="3"]:fill-emerald-600 dark:data-[level="3"]:fill-emerald-500',
90 'data-[level="4"]:fill-emerald-800 dark:data-[level="4"]:fill-emerald-300'
91);
92
93/** Entrance timing: the muted grid fades in as a canvas, then colored blocks
94 * light up in rounds by activity level — lightest greens first, darkest
95 * last — so the year reads as charging up. */
96const LEVEL_REVEAL_BASE = 220;
97const LEVEL_REVEAL_STEP = 170;
98const LEVEL_REVEAL_JITTER = 110;
99
100/** Small deterministic per-block offset so each level's round shimmers in
101 * instead of snapping on as one frame. */
102const revealJitter = (weekIndex: number, dayIndex: number) =>
103 Math.round(
104 ((((weekIndex * 7 + dayIndex) * 137) % 97) / 97) * LEVEL_REVEAL_JITTER
105 );
106
107const ENTRANCE_KEYFRAMES = `@keyframes iconiq-cg-fade {
108 from { opacity: 0; }
109// … truncated

What it pulls in

npm packages

  • date-fns

Files it writes

  • contribution-graph.tsx

Facts

Registry
Iconiq UI
Type
registry:ui
Access
Free
Files written
1
Licence
MIT
First indexed
2026-08-03
Last confirmed
yesterday

Go to the source

Docs on Iconiq UI www.iconiqui.com edwinvakayil/iconiq on GitHub Raw registry item This item as JSON

More from Iconiq UI

All 119 items
Same registry, same kind — the ones you would have found next
ComponentRegistryKindAccessInstallsCommand
AccordionaccordionIconiq UIComponentsFree2 deps
AI Inputai-inputIconiq UIComponentsFree3 deps
AlertalertIconiq UIComponentsFree2 deps
AvataravatarIconiq UIComponentsFree3 deps
Accordion (Base UI)b-accordionIconiq UIComponentsFree2 deps
Alert Dialog (Base UI)b-alert-dialogIconiq UIComponentsFree3 deps
Autocomplete (Base UI)b-autocompleteIconiq UIComponentsFree3 deps
Avatar (Base UI)b-avatarIconiq UIComponentsFree2 deps
BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex