1 звезда на GitHub = 1 новый компонент.

Поставить звезду
Отображение данныхdataheatmapactivitygithubmatrix

Activity Heatmap Grid

Тепловая карта активности в стиле GitHub с градацией цветов и подсказками дат.

Живое превью

Contribution Activity
1,428 events in the last 4 months
JulAugSepOct

Использование

Скопируйте и вставьте этот код в ваш React-компонент:

tsx
import { ActivityHeatmapGrid } from 'react-component-kit-ui/data';

<ActivityHeatmapGrid title="Contribution Activity" weeks={16} />

Ручная установка

Если вы не используете пакет npm, создайте файл и вставьте следующий код: src/components/ActivityHeatmapGrid.tsx + ActivityHeatmapGrid.css:

ActivityHeatmapGrid.tsx
'use client';

import './ActivityHeatmapGrid.css';

/** class:list → className */
function cx(...args: unknown[]): string {
  const out: string[] = [];
  const walk = (v: unknown) => {
    if (!v) return;
    if (typeof v === 'string' || typeof v === 'number') out.push(String(v));
    else if (Array.isArray(v)) v.forEach(walk);
    else if (typeof v === 'object') for (const [k, on] of Object.entries(v as Record<string, unknown>)) if (on) out.push(k);
  };
  args.forEach(walk);
  return out.join(' ');
}

/**
 * ActivityHeatmapGrid — GitHub-style activity contribution matrix with intensity color levels and month labels.
 * 
 * @param {string} title - Section header label. Default is 'Commit Activity'.
 * @param {number} totalCount - Total activity events recorded. Default is 1428.
 */
export interface ActivityHeatmapGridProps {
  title?: string;
  totalCount?: number;
}

export function ActivityHeatmapGrid({
  title = 'Contribution Activity',
  totalCount = 1428,
}: ActivityHeatmapGridProps) {
  // Mock 16 weeks of 7 days
  const weeks = Array.from({ length: 16 }, (_, w) =>
    Array.from({ length: 7 }, (_, d) => {
      // Generate pseudo-random intensity 0 to 4
      const seed = (w * 7 + d * 13 + 5) % 17;
      if (seed < 4) return 0;
      if (seed < 8) return 1;
      if (seed < 12) return 2;
      if (seed < 15) return 3;
      return 4;
    })
  );
  
  const months = ['Jul', 'Aug', 'Sep', 'Oct'];
  return (
    <>
      <div className="heatmap-card" data-rk-f489b5="">
        <div className="heatmap-card__head" data-rk-f489b5="">
          <div className="heatmap-card__title-wrap" data-rk-f489b5="">
            <h5 className="heatmap-card__title" data-rk-f489b5="">{title}</h5>
            <span className="heatmap-card__total" data-rk-f489b5="">{totalCount.toLocaleString()} events in the last 4 months</span>
          </div>
      
          <div className="heatmap-card__legend" aria-hidden="true" data-rk-f489b5="">
            <span className="legend-text" data-rk-f489b5="">Less</span>
            <span className="cell cell--0" data-rk-f489b5=""></span>
            <span className="cell cell--1" data-rk-f489b5=""></span>
            <span className="cell cell--2" data-rk-f489b5=""></span>
            <span className="cell cell--3" data-rk-f489b5=""></span>
            <span className="cell cell--4" data-rk-f489b5=""></span>
            <span className="legend-text" data-rk-f489b5="">More</span>
          </div>
        </div>
      
        <div className="heatmap-card__matrix" data-rk-f489b5="">
          <div className="heatmap-card__months" data-rk-f489b5="">
            {months.map((m, __i: number) => (
              <span key={__i} className="month-label" data-rk-f489b5="">{m}</span>
            ))}
          </div>
      
          <div className="heatmap-card__grid" data-rk-f489b5="">
            {weeks.map((week, __i: number) => (
              <div key={__i} className="heatmap-col" data-rk-f489b5="">
                {week.map((level, __i: number) => (
                  <span key={__i} className={cx(['cell', `cell--${level}`])} data-rk-f489b5=""></span>
                ))}
              </div>
            ))}
          </div>
        </div>
      </div>
    </>
  );
}

export default ActivityHeatmapGrid;
ActivityHeatmapGrid.css
/* ActivityHeatmapGrid — ported from astro-component-kit (data/ActivityHeatmapGrid.astro) */

.heatmap-card:where([data-rk-f489b5]) {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: var(--sp-6, 1.5rem);
  background: rgba(255, 255, 255, 0.02);
  backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-xl, 20px);
  width: 100%;
  max-width: 480px;
  font-family: var(--font-sans, system-ui, sans-serif);
}

.heatmap-card__head:where([data-rk-f489b5]) {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.heatmap-card__title:where([data-rk-f489b5]) {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--c-text-1, #ffffff);
  margin: 0 0 2px 0;
}

.heatmap-card__total:where([data-rk-f489b5]) {
  font-size: 0.75rem;
  color: var(--c-text-3, #737373);
}

.heatmap-card__legend:where([data-rk-f489b5]) {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.7rem;
  color: var(--c-text-3, #737373);
}

.heatmap-card__matrix:where([data-rk-f489b5]) {
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.heatmap-card__months:where([data-rk-f489b5]) {
  display: flex;
  justify-content: space-between;
  padding: 0 4px;
  font-size: 0.68rem;
  color: var(--c-text-3, #737373);
  font-weight: 600;
}

.heatmap-card__grid:where([data-rk-f489b5]) {
  display: flex;
  gap: 4px;
}

.heatmap-col:where([data-rk-f489b5]) {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.cell:where([data-rk-f489b5]) {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  transition: transform 0.15s ease;
}

.heatmap-card__grid:where([data-rk-f489b5]) .cell:hover:where([data-rk-f489b5]) {
  transform: scale(1.3);
}

.cell--0:where([data-rk-f489b5]) { background: rgba(255, 255, 255, 0.05); }
.cell--1:where([data-rk-f489b5]) { background: rgba(184, 134, 11, 0.25); }
.cell--2:where([data-rk-f489b5]) { background: rgba(184, 134, 11, 0.55); }
.cell--3:where([data-rk-f489b5]) { background: rgba(212, 160, 23, 0.85); }
.cell--4:where([data-rk-f489b5]) { background: #fef3c7; box-shadow: 0 0 6px rgba(254, 243, 199, 0.6); }

Краткая информация

Категория
Отображение данных
Имя файла
ActivityHeatmapGrid.tsx
Зависимости
Нет — чистый React + CSS
Теги
dataheatmapactivitygithubmatrix