From edca8d4921680f0448e2e187990c41eab3e9a7fb Mon Sep 17 00:00:00 2001 From: Visaka123 Date: Tue, 19 May 2026 22:02:53 +0530 Subject: [PATCH] fix(ui): implement exact absolute coordinate alignment for month labels on heatmap --- src/components/ContributionHeatmap.tsx | 190 +++++++++++++++---------- 1 file changed, 117 insertions(+), 73 deletions(-) diff --git a/src/components/ContributionHeatmap.tsx b/src/components/ContributionHeatmap.tsx index a56358e4..8c81db44 100644 --- a/src/components/ContributionHeatmap.tsx +++ b/src/components/ContributionHeatmap.tsx @@ -1,8 +1,7 @@ "use client"; import { useEffect, useMemo, useState } from "react"; -import type { CSSProperties } from "react"; -import { useHeatmapTheme, getHeatmapCellStyle } from "@/hooks/useHeatmapTheme"; +import { useHeatmapTheme } from "@/hooks/useHeatmapTheme"; interface ContributionHeatmapProps { days?: number; @@ -24,17 +23,19 @@ const CELL_SIZE = 12; const CELL_GAP = 2; const LABEL_WIDTH = 42; const HEADER_HEIGHT = 18; + const DAY_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; +// Memoized formatting engine to avoid recreation garbage collection cycles inside render loops +const monthFormatter = new Intl.DateTimeFormat("en-US", { month: "short" }); + function formatDateKey(date: Date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); - return `${year}-${month}-${day}`; } - function buildHeatmap(days: number, contributions: Record) { const endDate = new Date(); endDate.setHours(23, 59, 59, 999); @@ -56,21 +57,21 @@ function buildHeatmap(days: number, contributions: Record) { while (cursor <= lastWeekEnd) { const dateKey = formatDateKey(cursor); - cells.push({ date: new Date(cursor), dateKey, count: contributions[dateKey] ?? 0, inRange: cursor >= startDate && cursor <= endDate, }); - cursor.setDate(cursor.getDate() + 1); } return cells; } -export default function ContributionHeatmap({ days = DEFAULT_DAYS }: ContributionHeatmapProps) { +export default function ContributionHeatmap({ + days = DEFAULT_DAYS, +}: ContributionHeatmapProps) { const [data, setData] = useState>({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -84,15 +85,14 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio fetch(`/api/metrics/contributions?days=${days}`) .then((response) => { - if (!response.ok) { - throw new Error("API error"); - } - + if (!response.ok) throw new Error("API error"); return response.json(); }) .then((result: ContributionResponse) => { if (!active) return; setData(result.data ?? {}); + setLastUpdated(new Date()); + setMinutesAgo(0); }) .catch(() => { if (!active) return; @@ -101,8 +101,6 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio .finally(() => { if (!active) return; setLoading(false); - setLastUpdated(new Date()); - setMinutesAgo(0); }); return () => { @@ -112,39 +110,51 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio useEffect(() => { if (!lastUpdated) return; - const interval = setInterval(() => { setMinutesAgo(Math.floor((Date.now() - lastUpdated.getTime()) / 60000)); }, 60000); - return () => clearInterval(interval); }, [lastUpdated]); const { themeConfig, theme, setTheme } = useHeatmapTheme(); const cells = useMemo(() => buildHeatmap(days, data), [days, data]); const weekCount = Math.ceil(cells.length / 7); + + // 100% MATHEMATICALLY PRECISE MONTH TRACKING SYSTEM const monthMarkers = useMemo(() => { - const seen = new Set(); + const markers: Array<{ label: string; weekIndex: number }> = []; + const seenMonths = new Set(); - return cells.reduce>((markers, cell, index) => { - if (!cell.inRange) return markers; + for (let w = 0; w < weekCount; w++) { + const weekCells = cells.slice(w * 7, (w + 1) * 7); - const monthKey = `${cell.date.getFullYear()}-${cell.date.getMonth()}`; - if (seen.has(monthKey)) return markers; + for (const cell of weekCells) { + if (!cell.inRange) continue; - seen.add(monthKey); - markers.push({ - label: cell.date.toLocaleDateString("en-US", { month: "short" }), - weekIndex: Math.floor(index / 7), - }); + const currentMonth = cell.date.getMonth(); + const currentYear = cell.date.getFullYear(); + const monthKey = `${currentYear}-${currentMonth}`; - return markers; - }, []); - }, [cells]); + if (!seenMonths.has(monthKey)) { + seenMonths.add(monthKey); + + markers.push({ + label: monthFormatter.format(cell.date), + weekIndex: w, + }); + break; // Move immediately to scanning the next column track block + } + } + } + return markers; + }, [cells, weekCount]); + + // Shared matrix geometries matching baseline canvas dimensions + const totalGridWidth = LABEL_WIDTH + (weekCount * CELL_SIZE) + ((weekCount - 1) * CELL_GAP); const gridStyle = { gridTemplateColumns: `${LABEL_WIDTH}px repeat(${weekCount}, ${CELL_SIZE}px)`, - gridTemplateRows: `${HEADER_HEIGHT}px repeat(7, ${CELL_SIZE}px)`, + gridTemplateRows: `repeat(7, ${CELL_SIZE}px)`, columnGap: `${CELL_GAP}px`, rowGap: `${CELL_GAP}px`, } as const; @@ -153,34 +163,34 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio return (
-
+

Contribution Heatmap

Last {days} days of commit activity.

-
- - -
+
+ + +
Less -
+
{[0, 1, 3, 6, 10].map((count) => { const swatch = count === 0 @@ -207,7 +217,7 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio
{loading ? ( -
+
) : error ? (

{error} Please try refreshing.

@@ -215,24 +225,44 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio ) : ( <>
-
-
-
- {monthMarkers.map((marker) => ( -
- {marker.label} -
- ))} +
+ + {/* MATHEMATICAL COORDINATE TIMELINE HEADER BANNER CONTAINER */} +
+ {monthMarkers.map((marker) => { + const absoluteLeftOffset = LABEL_WIDTH + (marker.weekIndex * (CELL_SIZE + CELL_GAP)); + + return ( +
+ {marker.label} +
+ ); + })} +
+ {/* Grid System Area mapping identical columns */} +
{DAY_LABELS.map((label, rowIndex) => (
{rowIndex % 2 === 0 ? label : ""}
@@ -256,14 +286,26 @@ export default function ContributionHeatmap({ days = DEFAULT_DAYS }: Contributio title={isFuture ? "" : tooltip} aria-label={isFuture ? `${cell.dateKey}: future date` : tooltip} disabled={isFuture} - className={`group relative z-0 h-3 w-3 rounded-[3px] border transition-transform hover:z-20 hover:scale-110 focus:z-20 focus:outline-none focus:ring-2 focus:ring-[var(--heatmap-focus-ring)] disabled:cursor-default disabled:opacity-30 ${cell.inRange ? "" : "opacity-35"}`} - style={{ - gridRow: dayIndex + 2, - gridColumn: weekIndex + 2, - backgroundColor: isFuture ? "transparent" : (cell.count === 0 ? themeConfig.missed : cell.count < 3 ? themeConfig.levelOne : cell.count < 6 ? themeConfig.levelTwo : cell.count < 10 ? themeConfig.levelThree : themeConfig.levelFour), - borderColor: themeConfig.border, - ["--heatmap-focus-ring" as any]: themeConfig.accent, - }} + className={`group relative z-0 h-3 w-3 rounded-[3px] border transition-transform hover:z-20 hover:scale-110 focus:z-20 focus:outline-none focus:ring-2 focus:ring-[var(--heatmap-focus-ring)] disabled:cursor-default disabled:opacity-30 ${ + cell.inRange ? "" : "opacity-35" + }`} + style={{ + gridRow: dayIndex + 1, + gridColumn: weekIndex + 2, + backgroundColor: isFuture + ? "transparent" + : cell.count === 0 + ? themeConfig.missed + : cell.count < 3 + ? themeConfig.levelOne + : cell.count < 6 + ? themeConfig.levelTwo + : cell.count < 10 + ? themeConfig.levelThree + : themeConfig.levelFour, + borderColor: themeConfig.border, + ["--heatmap-focus-ring" as any]: themeConfig.accent, + }} > {!isFuture && ( {cells.filter((cell) => cell.inRange).reduce((total, cell) => total + cell.count, 0)} commits shown across {days} days.

- {lastUpdated &&

{minutesAgo === 0 ? "Updated just now" : `Updated ${minutesAgo} min ago`}

} + {lastUpdated && ( +

{minutesAgo === 0 ? "Updated just now" : `Updated ${minutesAgo} min ago`}

+ )}
)}