-
-
Notifications
You must be signed in to change notification settings - Fork 0
Calendar Grid
GitHub's contribution calendar is always a fixed 53 weeks × 7 days grid. ContribKit builds that grid deterministically so rendering is stable regardless of which days GitHub actually returned. The logic lives in domain/services/calendar-grid.ts.
---
config:
look: handDrawn
theme: neutral
---
flowchart LR
start["year-01-01"] --> sunday["shift back to the<br/>Sunday on/before"]
sunday --> walk["walk forward<br/>371 days"]
walk --> grid["53 weeks × 7 days<br/>= 371 cells"]
SVG_GRID_CELL_COUNT = SVG_WEEKS (53) × SVG_DAYS_PER_WEEK (7) = 371 cells.
A year doesn't start on a Sunday, so the grid starts on the Sunday on or before January 1st of the target year:
start = (year-01-01) shifted back by getWeekday(year-01-01) days
From start, it walks forward exactly SVG_GRID_CELL_COUNT days, producing one ContributionDay per cell. Date math is pure ISO-string arithmetic in domain/services/dates.ts:
| Helper | Behavior |
|---|---|
getWeekday(iso) |
0–6 (Sun–Sat) via Date.getDay()
|
addDays({ iso, days }) |
shifts an ISO date by N days |
toIsoDate(date) |
YYYY-MM-DD slice |
All three construct dates at T12:00:00 (local noon) rather than midnight. Anchoring at noon avoids off-by-one errors where a DST transition or timezone offset would otherwise push a midnight timestamp into the previous/next day.
2024-01-01 is a Monday, so getWeekday("2024-01-01") === 1. The grid starts one day earlier, on Sunday 2023-12-31, then walks 371 days forward to fill 53 full weeks. Days that fall outside 2024 (the trailing Sunday of 2023, the leading days of 2025) simply have no entry in the map and render as level 0.
Parsed days are first turned into a lookup map keyed by ISO date:
---
config:
look: handDrawn
theme: neutral
---
flowchart LR
days["buildGridFromApi<br/>({ days, year })"] --> map["map: date →<br/>{ level, count }"]
map --> build["buildCalendarGrid<br/>({ map, year })"]
For each of the 371 positions:
- look up the date in the map,
- if present, use its
level(run throughclampLevel) andcount, - if absent, emit
{ level: 0, count: null }.
This guarantees a complete, gap-free grid even when GitHub omits leading/trailing days outside the year.
Because the grid is derived purely from the date and the parsed map, the same input always yields the same output. That keeps SVG rendering reproducible and cacheable, and makes the grid trivially unit-testable. (Placeholder/skeleton grids in the UI use a seeded PRNG for the same reason — see Deterministic Randomness.)
- HTML Parsing — produces the days fed into the grid
- SVG Rendering — chunks the grid back into weeks to draw it