Отображение данныхdataheatmapactivitygithubmatrix
Activity Heatmap Grid
Тепловая карта активности в стиле GitHub с градацией цветов и подсказками дат.
Живое превью
Contribution Activity
1,428 events in the last 4 monthsLessMore
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