CalendarStrip
Recent weeks day by day, week-aligned to the real calendar, with empty days drawn differently from zero days.
- encodes
- discrete color step per real calendar day
- precision
- low per day, high for rhythm — ActivityGrid for longer histories
- nodes
- ≤ 56 (1 per day, weeks ≤ 8 documented cap)
Each cell is one dated day, sitting in its real week column: four weeks by default, starting Monday, so one glance covers a month of weekday rhythm without scrolling history. Weekday rhythm is the read.
Install
import { CalendarStrip } from "@microcharts/react/calendar-strip";// days — real values under “Sample data” below<CalendarStrip data={days} end="2026-07-01" title="Deploy cadence" />Sample data
const days = Array.from({ length: 18 }, (_, i) => ({ date: `2026-06-${String(4 + i).padStart(2, "0")}`, value: i % 4 === 3 ? 0 : (i % 7) + 1,}));Try it
When to use it
Use it for habit or deploy cadence in KPI cards and week-aligned recent activity. For long ordinal histories use ActivityGrid; for exact per-day values use MiniBar.
Sizing
Variants
All date math is UTC, so the same input renders identically in any host timezone and SSR output never depends on where
the server runs. end defaults to today; pin it wherever determinism matters.
cell/gap bump the edge length and spacing directly — grid-sibling parity with ActivityGrid and GardenGrid.
Edge cases
Empty is not zero here. A day with no record renders as a faint outline; a day with value 0 renders as a filled track cell, so a gap in the feed never reads as a quiet day. Future days are blank, never extrapolated.
Four homes
Accessibility
The accessible name counts real days — "Active 11 of 24 days over 4 weeks." The interactive entry walks the grid in 2-D and announces real calendar days ("Thursday, June 11: 0.", "Tuesday, June 23: no data.").
The interactive entry follows the shared interaction contract:
arrow keys rove between units on both axes, Home and End jump to the ends, and a click, tap, Enter or
Space selects a unit — pinning its readout so it survives blur, until you select it again or press Escape.
On touch, a tap pins and a drag scrubs.
Props
| Prop | Type | Notes |
|---|---|---|
| data* | { date; value }[] | Date-keyed values; duplicates sum with a dev warning. |
| weeks | number | Window length in whole weeks ending at `end` (default 4). |
| end | string | Date | Last day of the window (defaults to today UTC — pin it for SSR determinism). |
| weekStart | 0 | 1 | Locale start-of-week (default Monday). |
| steps | number | Intensity steps including the zero track (default 5). |
| shape | "square" | "round" | "dot" | Shared cell vocabulary. |
| cell | number | Cell edge length in viewBox units (default 7). |
| gap | number | Gap between cells (default 1). |
| dateFormat | Intl.DateTimeFormatOptions | (d: Date) => string | interactiveAnnounced day label (defaults to weekday + month + day, UTC). |
| animate | boolean | interactiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion. |
Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.