# shadcn-calendar-heatmap > A customizable calendar heatmap component built on top of react-day-picker, following shadcn/ui patterns. Accessible, unstyled by default, and fully customizable with Tailwind CSS. ## Overview shadcn-calendar-heatmap is a React component that transforms the DayPicker calendar into a heatmap visualization. It allows you to display dates with varying intensities using custom color variants - perfect for GitHub contribution graphs, temperature heatmaps, activity tracking, and more. ## Installation The component is designed to be copied directly into your project following the shadcn/ui philosophy. Copy the component from: https://github.com/gurbaaz27/shadcn-calendar-heatmap/blob/main/components/ui/calendar-heatmap.tsx ### Dependencies - react-day-picker (^8.10.1) - tailwind-merge - class-variance-authority - lucide-react (for icons) ## Component API ### CalendarHeatmap Props The component extends all props from `react-day-picker`'s DayPicker, plus: | Prop | Type | Required | Description | |------|------|----------|-------------| | `variantClassnames` | `string[]` | Yes | Array of Tailwind CSS classes for each intensity level | | `datesPerVariant` | `Date[][]` | One of these | 2D array where each inner array contains dates for that variant | | `weightedDates` | `WeightedDateEntry[]` | One of these | Array of `{ date: Date, weight: number }` objects | | `numberOfMonths` | `number` | No | Number of months to display (default: 1) | | `showOutsideDays` | `boolean` | No | Show days from adjacent months (default: true) | **Note:** You must provide either `datesPerVariant` OR `weightedDates`, not both. ### WeightedDateEntry Type ```typescript type WeightedDateEntry = { date: Date weight: number } ``` ## Usage Examples ### Basic GitHub-style Contribution Graph ```tsx import { CalendarHeatmap } from "@/components/ui/calendar-heatmap" ``` ### Using Weighted Dates (Auto-categorization) When you have numeric data associated with dates, use `weightedDates`. The component automatically categorizes dates into variants based on their weights: ```tsx ``` ### Multi-month Display ```tsx ``` ### Rainbow Variant Example ```tsx const Rainbow = [ "text-white hover:text-white bg-violet-400 hover:bg-violet-400", "text-white hover:text-white bg-indigo-400 hover:bg-indigo-400", "text-white hover:text-white bg-blue-400 hover:bg-blue-400", "text-white hover:text-white bg-green-400 hover:bg-green-400", "text-white hover:text-white bg-yellow-400 hover:bg-yellow-400", "text-white hover:text-white bg-orange-400 hover:bg-orange-400", "text-white hover:text-white bg-red-400 hover:bg-red-400", ] ``` ## How It Works 1. **Variant Classes**: Each string in `variantClassnames` represents a color/style intensity level. The component creates DayPicker modifiers for each variant. 2. **Date Mapping**: - With `datesPerVariant`: Dates in the first array get the first variant class, second array gets second class, etc. - With `weightedDates`: The component sorts dates by weight, divides the range into equal segments based on the number of variants, and assigns each date to its corresponding variant. 3. **Styling**: The component uses Tailwind CSS classes. Include both normal and hover states in your variant classes for consistent interaction feedback. ## Customization ### Custom Styling Override default calendar styles via the `classNames` prop: ```tsx ``` ### Additional Props Since the component extends DayPicker, you can use any DayPicker prop: ```tsx console.log(day)} /> ``` ## Links - Demo: https://shadcn-calendar-heatmap.vercel.app - GitHub: https://github.com/gurbaaz27/shadcn-calendar-heatmap - Component Source: https://github.com/gurbaaz27/shadcn-calendar-heatmap/blob/main/components/ui/calendar-heatmap.tsx ## License MIT