Add CalendarHeatmap component for activity visualization#40
Merged
Conversation
… across a date range. Fills a gap in the library: there was no primitive for rendering GitHub-style contribution graphs / activity grids — a common dashboard need (audit log frequency, schema mutations, deploy cadence, login density, API usage). The existing data-viz primitives (sparkline, number-ticker, stat-card) cover 1D series and single-number KPIs, but not 2D date-grid intensity, so this complements them without overlap. Implementation is pure SVG-free DOM (CSS-grid-style columns of day cells) so it scales crisply, prints cleanly, and avoids any new dependency. Date math is UTC-only to dodge browser timezone drift around DST boundaries; ISO `yyyy-mm-dd` strings and Date instances are both accepted. Cells use a five-step intensity scale (level 0 = no activity → level 4 = peak); thresholds are auto-derived from the dataset's quartile distribution but can be overridden via the `thresholds` prop for stable colour mapping across multiple heatmaps in the same view. cva-driven `color` variant (default brand-blue, primary, positive, warning, destructive — all sourced from @schemavaults/theme tokens with /20, /40, /65, full opacity steps so light and dark modes look correct out of the box) and `size` variant (sm/md/lg controlling cell size, gap, and label font-size). Optional weekday and month labels follow the GitHub convention (alternating weekday rows, month labels above the first column where the month transitions). `weekStart` is configurable (Sunday default, ISO Monday for European locales). `tooltipText` is a render-prop so callers can format counts however they want (e.g. multiplying by a unit, using locale formatting); falls back to a sensible default. `legendExtra` slot lets composers add date-range hints or threshold legends without bespoke layout code. Out-of-range cells in the surrounding 7×N grid are rendered as transparent spacers so the grid stays rectangular regardless of where startDate/endDate fall in the week. role=figure on the root and role=gridcell + aria-label on each active cell so screen readers can read individual day activity. Storybook story covers Default, Primary/Positive/Warning/Destructive colour variants, Small/Large sizes, MondayWeekStart, NoLabels, ShortRange (Q1 only), Sparse (low-density data), WithCustomThresholds, WithCustomTooltip, ColorVariantMatrix and SizeMatrix grid views, InsideCard (dashboard composition with totals header), and Empty (no data path).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…the InsideCard Storybook story). The inner labels+grid row had no overflow handling, so when the root's `max-w-full` correctly capped its outer box at the parent's width, the fixed-pixel-width cells still bled past the right edge of the card. Two changes: (1) the inner labels+grid row is now `flex max-w-full min-w-0 overflow-x-auto`, so it becomes a horizontal scroll container when the natural grid width exceeds the available space — the legend underneath stays put and renders at the correct width; (2) `min-w-0` is added to the root variant so the heatmap can shrink below its intrinsic min-content when used as a flex/grid child elsewhere in the page. Standalone rendering (where the parent is wider than the grid) is unchanged: `w-fit` still makes the heatmap hug its content tightly, no scrollbar appears. Verified via typecheck, typecheck:storybook, lint — all clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces a new
CalendarHeatmapcomponent for visualizing daily activity data across date ranges, similar to GitHub's contribution graph. This component is useful for displaying metrics like contributions, deployments, API usage, or any time-series data where a single count per day is meaningful.Key Changes
New CalendarHeatmap component (
src/components/ui/calendar-heatmap/calendar-heatmap.tsx):default,primary,positive,warning,destructivesm,md,lgComprehensive Storybook stories (
src/components/ui/calendar-heatmap/CalendarHeatmap.stories.tsx):Module exports (
src/components/ui/calendar-heatmap/index.ts):Notable Implementation Details
Dateobjects and ISOyyyy-mm-ddstringsuseMemofor expensive computations (value mapping, threshold calculation, week grid generation)https://claude.ai/code/session_01Y6Vm8h6hqzmRiLZYhPmMkJ