Detent web components
By Shane Logsdon

Charts & metrics

Activity Heatmap

Implemented

Responsive contribution calendar and weekday-by-hour activity grid

detent-activity-heatmap

Port status
Catalog status
implemented
Origin
upstream
Phase
3
Wave
phase-3-data
Group
Charts & metrics

8.9 KB gzip for the class module · inlines the shared spring

Variants

hours, weekday × hour
narrow container (columns drop, labels collapse)
no activity (all zero)

Local sample data only. Tab into a grid and use the arrow keys to inspect cells.

Recorded states

  • closed recorded state; no setter
  • collapsed recorded state; no setter
  • reduced motion recorded state; no setter
  • active recorded state; no setter

Usage

Import

import '/components/activity-heatmap/define.js';

// or register it yourself
import { DetentActivityHeatmap } from '/components/activity-heatmap/activity-heatmap.js';

Attributes

  • animated
  • aria-label
  • color
  • end-date
  • min-cell
  • mode
  • unit
  • week-start
  • weeks

Properties

  • data
  • matrix
  • rowLabels

Slots

No slots are recorded for this component.

Events

No events are recorded for this component.

Example

Runnable example: site/examples/activity-heatmap.ts. The snippet below is generated from the catalogued attributes.

<detent-activity-heatmap
  animated
  aria-label="auto-generated"
  color="#34d399"
  end-date
  min-cell="11"
  mode="calendar"
  unit="contributions"
  week-start="0"
  weeks="53"
></detent-activity-heatmap>

Property-only values

const element = document.querySelector('detent-activity-heatmap');
if (element !== null) {
  // data: HeatDay[]
  element.data = [];
  // matrix: number[][]
  element.matrix = [];
  // rowLabels: string[]
  element.rowLabels = [];
}

Source

The pinned upstream source for this row:

  • src/components/ui/ActivityHeatmap.tsx sha256 d56d1e12de14…

Native files

The native module and its artifacts:

  • src/components/activity-heatmap/activity-heatmap.ts
  • src/components/activity-heatmap/styles.css
  • src/components/activity-heatmap/define.ts
  • docs/components/activity-heatmap.md
  • site/examples/activity-heatmap.ts
  • tests/browser/activity-heatmap.spec.ts
  • evidence/components/activity-heatmap.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
animatedanimatedbooleantruePresence semantics: present means true, absent means false.
aria-labelariaLabelstringauto-generatedKebab-case attribute; camelCase property.
colorcolorstring"#34d399"Kebab-case attribute; camelCase property.
end-dateendDatestring | Date—Kebab-case attribute; camelCase property.
min-cellminCellnumber11Kebab-case attribute; camelCase property.
modemode"calendar" | "hours""calendar"Kebab-case attribute; camelCase property.
unitunitstring"contributions"Kebab-case attribute; camelCase property.
week-startweekStart0 | 10Kebab-case attribute; camelCase property.
weeksweeksnumber53Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
dataHeatDay[]—Property-only: assign from script; not accepted as an attribute.
matrixnumber[][]—Property-only: assign from script; not accepted as an attribute.
rowLabelsstring[]["Mon", … , "Sun"]Property-only: assign from script; not accepted as an attribute.

Events

No custom events are recorded for this component.

Slots

No slots are recorded for this component.

CSS customisation

  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • className is replaced by the documented CSS parts and custom properties; consumers need no Tailwind.
  • Framer Motion springs and the injected dangerouslySetInnerHTML keyframe block become the shared createSpring helper (pinned 520/42/0.6) and a scoped shadow stylesheet (PC-10.1, PC-11.3).
  • Levels paint the base colour with fill-opacity instead of color-mix(), so the computed fill stays measurable; the visible result is the same 28/52/76/100 % ramp.
  • The default colour resolves through --detent-chart-heat: its light value is darkened so a top-level cell keeps ≥ 3:1 against the surface, while the dark value is upstream's own #34d399 (PC-12.6). An explicit color attribute is honoured verbatim.
  • Resolved defaults (mode, weeks, week-start, min-cell, unit, end-date) are reflected into their attributes; upstream has no attribute layer.
  • The crosshair bands are always in the tree (hidden in calendar mode) so the documented part list is identical in both modes.

What it does

A responsive contribution calendar (one cell per day, GitHub style) and a weekday-by-hour activity grid. Cells are shaded by quartiles of the actual data, month and weekday labels collapse as the container narrows, columns are dropped until cells stay at or above min-cell, and a summary line reports the total and the peak cell.

Upstream behaviour
  • Calendar mode renders one cell per day in a GitHub-style contribution grid
  • Hours mode renders a 7 × 24 weekday-by-hour matrix with crosshair bands
  • Automatically drops columns on narrow screens so cells never fall below the minimum size
  • Quartile-based color levels adapt to the actual data distribution
  • Month and weekday labels collapse intelligently as the container narrows
  • Summary line reports total activity and the peak day or cell
  • Tooltip follows the active cell with a spring-tracked position and live region updates
  • Honors prefers-reduced-motion by removing the staggered cell entrance animation
Differences from upstream
  • `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • className is replaced by the documented CSS parts and custom properties; consumers need no Tailwind.
  • Framer Motion springs and the injected dangerouslySetInnerHTML keyframe block become the shared createSpring helper (pinned 520/42/0.6) and a scoped shadow stylesheet (PC-10.1, PC-11.3).
  • Levels paint the base colour with fill-opacity instead of color-mix(), so the computed fill stays measurable; the visible result is the same 28/52/76/100 % ramp.
  • The default colour resolves through --detent-chart-heat: its light value is darkened so a top-level cell keeps ≥ 3:1 against the surface, while the dark value is upstream's own #34d399 (PC-12.6). An explicit color attribute is honoured verbatim.
  • Resolved defaults (mode, weeks, week-start, min-cell, unit, end-date) are reflected into their attributes; upstream has no attribute layer.
  • The crosshair bands are always in the tree (hidden in calendar mode) so the documented part list is identical in both modes.
Previous: Activity Feed Next: Data Table

Docs

Components

Project