@thilakbhat/heatmap-ui 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ![heatmap-ui playground preview](docs/cover.png)
4
4
 
5
- [![CI](https://github.com/tb962/heatmap-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/tb962/heatmap-ui/actions/workflows/ci.yml)
5
+ [![CI](https://github.com/thilakbhat/heatmap-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/thilakbhat/heatmap-ui/actions/workflows/ci.yml)
6
6
  [![npm](https://img.shields.io/npm/v/@thilakbhat/heatmap-ui.svg)](https://www.npmjs.com/package/@thilakbhat/heatmap-ui)
7
7
  [![license](https://img.shields.io/npm/l/@thilakbhat/heatmap-ui.svg)](LICENSE)
8
8
 
@@ -10,7 +10,7 @@ A headless heatmap toolkit for React. Eight cell shapes, an interactive 3D mode
10
10
  that runs on plain SVG, and control over every colour, size and label on the
11
11
  grid.
12
12
 
13
- **[Try it in the playground →](https://tb962.github.io/heatmap-ui/)**
13
+ **[Try it in the playground →](https://thilakbhat.github.io/heatmap-ui/)**
14
14
 
15
15
  ```bash
16
16
  npm install @thilakbhat/heatmap-ui
@@ -20,7 +20,7 @@ npm install @thilakbhat/heatmap-ui
20
20
  import { CalendarHeatmap } from "@thilakbhat/heatmap-ui";
21
21
  import "@thilakbhat/heatmap-ui/styles.css";
22
22
 
23
- <CalendarHeatmap values={days} weeks={20} showLegend />;
23
+ <CalendarHeatmap values={days} weeks="auto" showLegend />;
24
24
  ```
25
25
 
26
26
  ## What you get
@@ -44,6 +44,8 @@ override.
44
44
  | Colour | any ramp, palest first, with separate colours for zero and for no data |
45
45
  | Labels | row and column labels, tooltips, and arbitrary content inside cells |
46
46
  | Layout | cell size, gap, corner radius, and a predicate for hiding slots |
47
+ | Sizing | calendars that fit their container (`weeks="auto"` or `{ min, max }`), and grids that scroll inside it with labels and legend held still (`overflow`) |
48
+ | Dates | rolling windows, exact ranges (`from`/`to`), and `calendarPeriods` for a year picker |
47
49
 
48
50
  ### The 3D mode
49
51
 
@@ -121,6 +123,7 @@ values={[{ row: 0, column: 0, value: 3, known: true, meta: anything }]}
121
123
  | `cellLabel` | none | `(cell) => string`; the accessible name for a cell. |
122
124
  | `onCellClick` | none | Makes cells buttons. |
123
125
  | `showLegend` | `false` | less/more key, plus "no data" when relevant. |
126
+ | `overflow` | `"scroll"` | A grid wider than its container scrolls inside it, with row labels and legend held still. `"visible"` lets it spill out. |
124
127
 
125
128
  ### Shading
126
129
 
@@ -304,7 +307,74 @@ labels and tooltips, so it stays an SVG renderer without an HTML overlay.
304
307
  />
305
308
  ```
306
309
 
307
- `weeks` defaults to 53 when omitted.
310
+ ### Fitting the container
311
+
312
+ `weeks` takes a number, `"auto"`, or a `{ min, max }` range:
313
+
314
+ | `weeks` | Container wide enough | Container too narrow |
315
+ | --- | --- | --- |
316
+ | `53` (default) | 53 weeks | 53 weeks, scrolling |
317
+ | `"auto"` | as many weeks as fit, up to 53 | as many weeks as fit, never scrolls |
318
+ | `{ min: 13, max: 53 }` | as many weeks as fit, 13 to 53 | 13 weeks, scrolling |
319
+
320
+ ```tsx
321
+ <CalendarHeatmap values={days} weeks="auto" />
322
+ <CalendarHeatmap values={days} weeks={{ min: 13 }} showWeekdayLabels />
323
+ ```
324
+
325
+ A fitted calendar spans its container and drops the oldest weeks first, so the
326
+ cell size never changes. When a calendar scrolls, it opens on the newest week
327
+ and stays anchored there as the container resizes. The weekday labels and
328
+ legend sit outside the scrolling area, so they stay put. Set `overflow="visible"` to
329
+ handle overflow yourself.
330
+
331
+ On the server, a fitted calendar renders its maximum, already scrolled to the
332
+ newest week, and trims to fit before the first client paint.
333
+
334
+ `CalendarHeatmap3D` scales its scene to the container rather than scrolling, so
335
+ `"auto"` and ranges show their maximum there.
336
+
337
+ `weeks` has no upper limit: `weeks={104}` shows two years. Once a range runs
338
+ past a year, each January is labelled with its year so repeated months stay
339
+ unambiguous. How much history to allow is a product decision, so cap it where
340
+ you query the data.
341
+
342
+ ### Choosing a period
343
+
344
+ `from` and `to` set an exact range. Days outside it are not drawn, `weeks` is
345
+ ignored, and a range wider than its container scrolls rather than dropping any
346
+ of it:
347
+
348
+ ```tsx
349
+ <CalendarHeatmap values={days} from="2025-01-01" to="2025-12-31" />
350
+ ```
351
+
352
+ `calendarPeriods` builds the usual list: a rolling window ending today, then
353
+ each year back to the first with data. The current year runs to today. The picker
354
+ itself is yours, so it matches the rest of your UI:
355
+
356
+ ```tsx
357
+ import { CalendarHeatmap, calendarPeriods } from "@thilakbhat/heatmap-ui";
358
+
359
+ const periods = calendarPeriods(days);
360
+ // [{ key: "rolling", label: "Last 12 months", range: { to } },
361
+ // { key: "2026", label: "2026", kind: "year", year: 2026, range: { from, to } }, …]
362
+
363
+ const [key, setKey] = useState("rolling");
364
+ const period = periods.find((p) => p.key === key) ?? periods[0];
365
+
366
+ <select value={key} onChange={(e) => setKey(e.target.value)}>
367
+ {periods.map((p) => <option key={p.key} value={p.key}>{p.label}</option>)}
368
+ </select>
369
+ <CalendarHeatmap values={days} weeks="auto" {...period.range} />
370
+ ```
371
+
372
+ It is a plain function rather than a hook, so the selection can live wherever
373
+ yours does: component state, the URL, or the server. Labels are English
374
+ defaults. Use `kind` and `year` to write your own, or `rollingLabel` for the
375
+ window. To fetch one year at a time, pass the years that have activity
376
+ (`calendarPeriods([2026, 2025, 2023])`) and load that year's days when it is
377
+ picked. Otherwise pass every day, and the calendar reads only the ones in range.
308
378
 
309
379
  The calendar adapter handles date mapping, month labels, weekday labels, and a
310
380
  default accessible name for each day. It hides days after `to` instead of
@@ -427,6 +497,10 @@ the previous label.
427
497
  `tooltip`, or `onCellClick`.
428
498
  - Tooltips open on focus as well as hover, after a 300ms delay, and are wired
429
499
  with `aria-describedby`.
500
+ - A grid that scrolls can be scrolled from the keyboard. Focusable cells scroll
501
+ it into view themselves, and a grid of plain cells makes its scroll area focusable.
502
+ - Tooltips render in the browser's top layer, so a scrolling grid or an
503
+ ancestor's `overflow` never clips them.
430
504
  - `encode` lets you carry intensity without relying on colour alone.
431
505
  - Hover and focus scaling is dropped under `prefers-reduced-motion`.
432
506
 
@@ -445,11 +519,15 @@ defines four variables you can override:
445
519
  ```
446
520
 
447
521
  Tooltip colours follow `prefers-color-scheme`. Set
448
- `data-heatmap-theme="light" | "dark"` to pin them.
522
+ `data-heatmap-theme="light" | "dark"` to pin them. Tooltips stay inside the
523
+ chart's DOM, so these variables still reach them from the top layer.
524
+
525
+ Inside `.heatmap`, the cells and column labels sit in `.heatmap__canvas`, which
526
+ scrolls within `.heatmap__viewport`. Row labels and the legend sit outside it.
449
527
 
450
528
  ## Playground
451
529
 
452
- **<https://tb962.github.io/heatmap-ui/>**. No install required.
530
+ **<https://thilakbhat.github.io/heatmap-ui/>**. No install required.
453
531
 
454
532
  To run it from your working copy:
455
533
 
@@ -460,7 +538,9 @@ npx serve .
460
538
 
461
539
  Open `examples/playground.html`. You can switch between 2D and 3D, choose Solid,
462
540
  LEGO, or Skyline cells, and orbit the scene. The graph choices include calendar,
463
- punchcard, cohort retention, co-occurrence, and uptime. Adjust a prop and the
541
+ punchcard, cohort retention, co-occurrence, and uptime. Drag the handle on the
542
+ preview's right edge to narrow it and watch a calendar fit or scroll. The
543
+ calendar also has a period picker built on `calendarPeriods`. Adjust a prop and the
464
544
  panel below the chart shows the exact code for the current view, including its
465
545
  imports.
466
546
 
@@ -8,12 +8,28 @@ export type CalendarDay = {
8
8
  known?: boolean;
9
9
  meta?: unknown;
10
10
  };
11
+ /**
12
+ * How many weeks to show. A number is exact. "auto" shows as many as the
13
+ * container fits, up to 53, dropping the oldest first. A range fits the same
14
+ * way within its bounds, and scrolls once even `min` does not fit.
15
+ * 3D charts scale rather than scroll, so they always show the maximum.
16
+ */
17
+ export type CalendarWeeks = number | "auto" | {
18
+ min?: number;
19
+ max?: number;
20
+ };
11
21
  type CalendarOptions = {
12
22
  values?: ReadonlyArray<CalendarDay>;
23
+ /**
24
+ * First day shown. With `from`, the range is exact: days outside it are not
25
+ * drawn, `weeks` is ignored, and a range too wide for its container scrolls
26
+ * rather than dropping any of it. A `from` after `to` shows `to` alone.
27
+ */
28
+ from?: string | Date;
13
29
  /** Last day shown. Defaults to today. */
14
30
  to?: string | Date;
15
- /** Columns to render. Defaults to 53. */
16
- weeks?: number;
31
+ /** Defaults to 53. Ignored when `from` is set. */
32
+ weeks?: CalendarWeeks;
17
33
  /** 0 = Sunday (default), 1 = Monday. */
18
34
  weekStart?: 0 | 1;
19
35
  showMonthLabels?: boolean;
@@ -32,7 +48,16 @@ export type CalendarHeatmap3DProps = Omit<Heatmap3DProps, CalendarManagedProps>
32
48
  export type CalendarCell = ResolvedCell & {
33
49
  date: string;
34
50
  };
35
- /** Lays days onto a flat grid, with one column per week. */
51
+ /** Reads `weeks` as a range. A fixed count is a range of one. */
52
+ export declare function resolveWeeks(weeks: CalendarWeeks | undefined): {
53
+ min: number;
54
+ max: number;
55
+ fit: boolean;
56
+ };
57
+ /**
58
+ * Lays days onto a flat grid, with one column per week. The newest week is
59
+ * the one in view when the grid has to scroll.
60
+ */
36
61
  export declare function CalendarHeatmap(props: CalendarHeatmapProps): import("react").JSX.Element;
37
62
  /** Lays the same calendar onto a rotatable 3D grid, with height encoding value. */
38
63
  export declare function CalendarHeatmap3D(props: CalendarHeatmap3DProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIhD,OAAO,KAAK,EAAE,cAAc,EAAe,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAS1F,MAAM,MAAM,WAAW,GAAG;IACxB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,yCAAyC;IACzC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,SAAS,CAAC;IAC3C,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC;CAC3C,CAAC;AAEF,KAAK,oBAAoB,GACrB,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAE3F,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,GAAG,eAAe,CAAC;AAE9F,yEAAyE;AACzE,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,EAAE,oBAAoB,CAAC,GAAG,eAAe,CAAC;AAElG,uDAAuD;AACvD,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AA+I3D,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAG1D;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAG9D;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../src/calendar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI1D,OAAO,KAAK,EAAE,cAAc,EAAe,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAW1F,MAAM,MAAM,WAAW,GAAG;IACxB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,KAAK,eAAe,GAAG;IACrB,MAAM,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,yCAAyC;IACzC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wCAAwC;IACxC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,SAAS,CAAC;IAC3C,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC;CAC3C,CAAC;AAEF,KAAK,oBAAoB,GACrB,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAE3F,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,GAAG,eAAe,CAAC;AAE9F,yEAAyE;AACzE,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,EAAE,oBAAoB,CAAC,GAAG,eAAe,CAAC;AAElG,uDAAuD;AACvD,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAmC3D,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,GAAG;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,OAAO,CAAC;CACd,CASA;AAsKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAiB1D;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAG9D;AAED,eAAe,eAAe,CAAC"}
package/dist/calendar.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useMemo } from "react";
4
- import { Heatmap } from "./heatmap.js";
3
+ import { useMemo, useState } from "react";
4
+ import { HeatmapView } from "./heatmap.js";
5
5
  import { Heatmap3D } from "./heatmap3d.js";
6
6
  const DAY_MS = 24 * 60 * 60 * 1000;
7
+ const WEEK_MS = 7 * DAY_MS;
8
+ const DEFAULT_WEEKS = 53;
7
9
  const MONTHS = [
8
10
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
9
11
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
@@ -20,38 +22,88 @@ function parseIsoDate(value) {
20
22
  function isoKey(date) {
21
23
  return date.toISOString().slice(0, 10);
22
24
  }
25
+ /** The ISO day of a date or date string, or null when it is missing or invalid. */
26
+ function dayKey(value) {
27
+ if (value === undefined)
28
+ return null;
29
+ const day = toUtcMidnight(value);
30
+ return Number.isNaN(day.getTime()) ? null : isoKey(day);
31
+ }
32
+ function startOfWeek(date, weekStart) {
33
+ const weekday = (date.getUTCDay() - weekStart + 7) % 7;
34
+ return new Date(date.getTime() - weekday * DAY_MS);
35
+ }
36
+ /** A week count as a whole number of at least one, or the fallback. */
37
+ function wholeWeeks(value, fallback) {
38
+ return typeof value === "number" && Number.isFinite(value)
39
+ ? Math.max(1, Math.floor(value))
40
+ : fallback;
41
+ }
42
+ /** Reads `weeks` as a range. A fixed count is a range of one. */
43
+ export function resolveWeeks(weeks) {
44
+ if (weeks === "auto" || (typeof weeks === "object" && weeks !== null)) {
45
+ const range = weeks === "auto" ? {} : weeks;
46
+ const min = wholeWeeks(range.min, 1);
47
+ // A minimum above the maximum wins: it is the floor the caller asked for.
48
+ return { min, max: Math.max(min, wholeWeeks(range.max, DEFAULT_WEEKS)), fit: true };
49
+ }
50
+ const count = wholeWeeks(weeks, DEFAULT_WEEKS);
51
+ return { min: count, max: count, fit: false };
52
+ }
23
53
  /**
24
54
  * Lays days onto the grid: one column per week, one row per weekday. This is
25
55
  * the only place in the package that knows what a date is.
26
56
  */
27
- function useCalendarProps({ values = [], to, weeks = 53, weekStart = 0, showMonthLabels = true, showWeekdayLabels = false, weekdayLabelRows = [1, 3, 5], unitLabel = "", tooltip, cellLabel, ...heatmapProps }) {
28
- const end = useMemo(() => toUtcMidnight(to ?? new Date()), [to]);
29
- const { cells, columnLabels, dates, hidden } = useMemo(() => {
57
+ function useCalendarProps({ values = [], from, to,
58
+ // Resolved by the caller, which knows whether the chart can fit its container.
59
+ weeks: _weeks, weekStart = 0, showMonthLabels = true, showWeekdayLabels = false, weekdayLabelRows = [1, 3, 5], unitLabel = "", tooltip, cellLabel, ...heatmapProps }, weeks) {
60
+ // Keyed by day, so a fresh Date each render (or "today") does not re-lay the grid.
61
+ // An unreadable `to` means today and an unreadable `from` means none,
62
+ // rather than a render that throws.
63
+ const endKey = dayKey(to) ?? dayKey(new Date());
64
+ const startKey = dayKey(from);
65
+ const { cells, columns, columnLabels, dates, hidden } = useMemo(() => {
30
66
  const byDate = new Map(values.map((day) => [day.date, day]));
67
+ const end = parseIsoDate(endKey);
68
+ const start = startKey === null ? null : new Date(Math.min(parseIsoDate(startKey).getTime(), end.getTime()));
31
69
  // The grid ends on the week containing `end`, so the last column is
32
- // partial whenever today is not the last day of the week.
33
- const endWeekday = (end.getUTCDay() - weekStart + 7) % 7;
34
- const lastColumnStart = new Date(end.getTime() - endWeekday * DAY_MS);
35
- const firstColumnStart = new Date(lastColumnStart.getTime() - (weeks - 1) * 7 * DAY_MS);
70
+ // partial whenever today is not the last day of the week. With a start,
71
+ // the first column is likewise the week containing it.
72
+ const lastColumnStart = startOfWeek(end, weekStart);
73
+ const firstColumnStart = start
74
+ ? startOfWeek(start, weekStart)
75
+ : new Date(lastColumnStart.getTime() - (weeks - 1) * WEEK_MS);
76
+ const columnCount = start
77
+ ? Math.round((lastColumnStart.getTime() - firstColumnStart.getTime()) / WEEK_MS) + 1
78
+ : weeks;
79
+ // More than a year repeats month names, so January says which year it is.
80
+ const namesYears = columnCount > DEFAULT_WEEKS;
36
81
  const resolved = [];
37
82
  const dateByKey = new Map();
38
83
  const hiddenSlots = new Set();
39
84
  const labels = [];
40
85
  let previousMonth = -1;
41
- for (let column = 0; column < weeks; column += 1) {
86
+ for (let column = 0; column < columnCount; column += 1) {
42
87
  // Which month a column belongs to is a property of the calendar, not of
43
88
  // the data, so the label is derived from the date before any value is
44
89
  // looked up. Deriving it inside the cell loop lost the label whenever
45
- // the caller had supplied nothing for that column's first day.
46
- const columnMonth = new Date(firstColumnStart.getTime() + column * 7 * DAY_MS).getUTCMonth();
90
+ // the caller had supplied nothing for that column's first day. A column
91
+ // is named for its first drawn day: the week holding 1 January starts
92
+ // in December, but a range from 1 January should not open on "Dec".
93
+ const columnStart = firstColumnStart.getTime() + column * WEEK_MS;
94
+ const columnDate = new Date(start ? Math.max(columnStart, start.getTime()) : columnStart);
95
+ const columnMonth = columnDate.getUTCMonth();
47
96
  if (columnMonth !== previousMonth) {
48
- labels.push({ column, text: MONTHS[columnMonth] });
97
+ const text = namesYears && columnMonth === 0
98
+ ? String(columnDate.getUTCFullYear())
99
+ : MONTHS[columnMonth];
100
+ labels.push({ column, text });
49
101
  previousMonth = columnMonth;
50
102
  }
51
103
  for (let row = 0; row < 7; row += 1) {
52
- const date = new Date(firstColumnStart.getTime() + (column * 7 + row) * DAY_MS);
53
- // Days after `end` are not "no data", they simply do not exist yet.
54
- if (date.getTime() > end.getTime()) {
104
+ const date = new Date(columnStart + row * DAY_MS);
105
+ // Days outside the range are not "no data", they are not in it at all.
106
+ if (date.getTime() > end.getTime() || (start && date.getTime() < start.getTime())) {
55
107
  hiddenSlots.add(row + ":" + column);
56
108
  continue;
57
109
  }
@@ -69,8 +121,14 @@ function useCalendarProps({ values = [], to, weeks = 53, weekStart = 0, showMont
69
121
  });
70
122
  }
71
123
  }
72
- return { cells: resolved, columnLabels: labels, dates: dateByKey, hidden: hiddenSlots };
73
- }, [values, end, weeks, weekStart]);
124
+ return {
125
+ cells: resolved,
126
+ columns: columnCount,
127
+ columnLabels: labels,
128
+ dates: dateByKey,
129
+ hidden: hiddenSlots,
130
+ };
131
+ }, [values, endKey, startKey, weeks, weekStart]);
74
132
  // A three-letter month is about 24px at the label's 10px font. When a month
75
133
  // starts too few columns after the previous label there is no room for both,
76
134
  // so the later one is dropped rather than drawn on top of its neighbour.
@@ -80,8 +138,15 @@ function useCalendarProps({ values = [], to, weeks = 53, weekStart = 0, showMont
80
138
  const kept = [];
81
139
  let lastColumn = Number.NEGATIVE_INFINITY;
82
140
  for (const label of columnLabels) {
83
- if (label.column - lastColumn < minColumns)
141
+ if (label.column - lastColumn < minColumns) {
142
+ // The range usually starts partway through a month. When that stub
143
+ // crowds the first whole month, the whole month keeps the label.
144
+ if (kept.length === 1 && kept[0].column === 0) {
145
+ kept[0] = label;
146
+ lastColumn = label.column;
147
+ }
84
148
  continue;
149
+ }
85
150
  kept.push(label);
86
151
  lastColumn = label.column;
87
152
  }
@@ -96,7 +161,7 @@ function useCalendarProps({ values = [], to, weeks = 53, weekStart = 0, showMont
96
161
  : undefined;
97
162
  return {
98
163
  rows: 7,
99
- columns: weeks,
164
+ columns,
100
165
  values: cells,
101
166
  isSlotHidden: (row, column) => hidden.has(row + ":" + column),
102
167
  rowLabels,
@@ -122,14 +187,25 @@ function useCalendarProps({ values = [], to, weeks = 53, weekStart = 0, showMont
122
187
  ...heatmapProps,
123
188
  };
124
189
  }
125
- /** Lays days onto a flat grid, with one column per week. */
190
+ /**
191
+ * Lays days onto a flat grid, with one column per week. The newest week is
192
+ * the one in view when the grid has to scroll.
193
+ */
126
194
  export function CalendarHeatmap(props) {
127
- const heatmapProps = useCalendarProps(props);
128
- return _jsx(Heatmap, { ...heatmapProps });
195
+ const { min, max, fit: fitsWeeks } = resolveWeeks(props.weeks);
196
+ // An exact range is never trimmed to fit; it scrolls instead.
197
+ const fit = fitsWeeks && props.from === undefined;
198
+ // Until the container is measured (and always on the server) the calendar
199
+ // renders its maximum, scrolled to the newest week, so the first paint
200
+ // shows the same recent weeks the fitted grid will.
201
+ const [fitted, setFitted] = useState(null);
202
+ const weeks = fit && fitted !== null ? Math.min(max, Math.max(min, fitted)) : max;
203
+ const heatmapProps = useCalendarProps(props, weeks);
204
+ return (_jsx(HeatmapView, { ...heatmapProps, scrollAnchor: "end", onFitColumns: fit ? setFitted : undefined }));
129
205
  }
130
206
  /** Lays the same calendar onto a rotatable 3D grid, with height encoding value. */
131
207
  export function CalendarHeatmap3D(props) {
132
- const heatmapProps = useCalendarProps(props);
208
+ const heatmapProps = useCalendarProps(props, resolveWeeks(props.weeks).max);
133
209
  return _jsx(Heatmap3D, { ...heatmapProps });
134
210
  }
135
211
  export default CalendarHeatmap;
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../src/calendar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../src/calendar.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACnC,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC;AAC3B,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACxC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;CAChC,CAAC;AACX,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAqD5E,SAAS,aAAa,CAAC,KAAoB;IACzC,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACrE,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,MAAM,CAAC,IAAU;IACxB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,mFAAmF;AACnF,SAAS,MAAM,CAAC,KAAgC;IAC9C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,WAAW,CAAC,IAAU,EAAE,SAAgB;IAC/C,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACvD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,uEAAuE;AACvE,SAAS,UAAU,CAAC,KAAyB,EAAE,QAAgB;IAC7D,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,QAAQ,CAAC;AACf,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,YAAY,CAAC,KAAgC;IAK3D,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;QACtE,MAAM,KAAK,GAAG,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC5C,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrC,0EAA0E;QAC1E,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACtF,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAC/C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CACvB,EACE,MAAM,GAAG,EAAE,EACX,IAAI,EACJ,EAAE;AACF,+EAA+E;AAC/E,KAAK,EAAE,MAAM,EACb,SAAS,GAAG,CAAC,EACb,eAAe,GAAG,IAAI,EACtB,iBAAiB,GAAG,KAAK,EACzB,gBAAgB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC5B,SAAS,GAAG,EAAE,EACd,OAAO,EACP,SAAS,EACT,GAAG,YAAY,EACT,EACR,KAAa;IAEb,mFAAmF;IACnF,sEAAsE;IACtE,oCAAoC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAE9B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE7G,oEAAoE;QACpE,wEAAwE;QACxE,uDAAuD;QACvD,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACpD,MAAM,gBAAgB,GAAG,KAAK;YAC5B,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC;YAC/B,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,KAAK;YACvB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;YACpF,CAAC,CAAC,KAAK,CAAC;QACV,0EAA0E;QAC1E,MAAM,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;QAE/C,MAAM,QAAQ,GAAkB,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;QACtC,MAAM,MAAM,GAA4C,EAAE,CAAC;QAC3D,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;QAEvB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;YACvD,wEAAwE;YACxE,sEAAsE;YACtE,sEAAsE;YACtE,wEAAwE;YACxE,sEAAsE;YACtE,oEAAoE;YACpE,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC;YAClE,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YAC1F,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;YAC7C,IAAI,WAAW,KAAK,aAAa,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,UAAU,IAAI,WAAW,KAAK,CAAC;oBAC1C,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;oBACrC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9B,aAAa,GAAG,WAAW,CAAC;YAC9B,CAAC;YAED,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC;gBAClD,uEAAuE;gBACvE,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;oBAClF,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC;oBACpC,SAAS;gBACX,CAAC;gBAED,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzB,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC;gBACvC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,CAAC,GAAG;oBAAE,SAAS;gBAEnB,QAAQ,CAAC,IAAI,CAAC;oBACZ,GAAG;oBACH,MAAM;oBACN,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,KAAK;oBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO;YACL,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,WAAW;YACpB,YAAY,EAAE,MAAM;YACpB,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,WAAW;SACpB,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAEjD,4EAA4E;IAC5E,6EAA6E;IAC7E,yEAAyE;IACzE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,MAAM,MAAM,GACV,CAAC,YAAY,CAAC,SAAS,IAAI,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACpF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;QAC1C,MAAM,IAAI,GAA4C,EAAE,CAAC;QACzD,IAAI,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,GAAG,UAAU,GAAG,UAAU,EAAE,CAAC;gBAC3C,mEAAmE;gBACnE,iEAAiE;gBACjE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC9C,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;oBAChB,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC5B,CAAC;gBACD,SAAS;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjB,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IAEpF,MAAM,QAAQ,GAAG,CAAC,IAAkB,EAAgB,EAAE,CAAC,CAAC;QACtD,GAAG,IAAI;QACP,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;KACpD,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,iBAAiB;QACjC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CACnC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CACtE;QACH,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,IAAI,EAAE,CAAC;QACP,OAAO;QACP,MAAM,EAAE,KAAK;QACb,YAAY,EAAE,CAAC,GAAW,EAAE,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC;QAC7E,SAAS;QACT,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QACvD,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC9E,SAAS,EAAE,CAAC,IAAkB,EAAE,EAAE;YAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,SAAS;gBAAE,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;gBACvE,OAAO,EAAE,MAAM;gBACf,GAAG,EAAE,SAAS;gBACd,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,KAAK;gBAAE,OAAO,QAAQ,GAAG,YAAY,CAAC;YACpD,OAAO,QAAQ,GAAG,IAAI,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,GAAG,YAAY;KAChB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/D,8DAA8D;IAC9D,MAAM,GAAG,GAAG,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;IAClD,0EAA0E;IAC1E,uEAAuE;IACvE,oDAAoD;IACpD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,GAAG,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClF,MAAM,YAAY,GAAG,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO,CACL,KAAC,WAAW,OACN,YAAY,EAChB,YAAY,EAAC,KAAK,EAClB,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GACzC,CACH,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,YAAY,GAAG,gBAAgB,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5E,OAAO,KAAC,SAAS,OAAK,YAAY,GAAI,CAAC;AACzC,CAAC;AAED,eAAe,eAAe,CAAC"}
package/dist/heatmap.d.ts CHANGED
@@ -1,4 +1,15 @@
1
1
  import type { HeatmapProps } from "./types.js";
2
- export declare function Heatmap({ rows, columns, values, scale, levels: levelsProp, thresholds: thresholdsProp, shape, encode, cellSize, cellWidth: cellWidthProp, cellHeight: cellHeightProp, gap, radius, colors, emptyColor, cellColor, unknownOpacity, minScale, rowLabels, columnLabels, tooltip, cellContent, cellLabel, onCellClick, isSlotHidden, showLegend, legendLabels, ariaLabel, className, style, ...rest }: HeatmapProps): import("react").JSX.Element;
2
+ /** Columns of a given pitch that fit in `available` pixels. */
3
+ export declare function fittingColumns(available: number, columnWidth: number, gap: number, overhang?: number): number;
4
+ /** Props the calendar passes to the grid, not part of the public API. */
5
+ export type HeatmapViewProps = HeatmapProps & {
6
+ /** Which end of an overflowing grid is in view first. Defaults to "start". */
7
+ scrollAnchor?: "start" | "end";
8
+ /** Stretches the chart to its container and reports how many columns fit. */
9
+ onFitColumns?: (columns: number) => void;
10
+ };
11
+ export declare function Heatmap(props: HeatmapProps): import("react").JSX.Element;
12
+ /** @internal */
13
+ export declare function HeatmapView({ rows, columns, values, scale, levels: levelsProp, thresholds: thresholdsProp, shape, encode, cellSize, cellWidth: cellWidthProp, cellHeight: cellHeightProp, gap, radius, colors, emptyColor, cellColor, unknownOpacity, minScale, rowLabels, columnLabels, tooltip, cellContent, cellLabel, onCellClick, isSlotHidden, showLegend, legendLabels, overflow, scrollAnchor, onFitColumns, ariaLabel, className, style, ...rest }: HeatmapViewProps): import("react").JSX.Element;
3
14
  export default Heatmap;
4
15
  //# sourceMappingURL=heatmap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../src/heatmap.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAC;AAO7D,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,OAAO,EACP,MAAM,EACN,KAAgB,EAChB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,cAAc,EAC1B,KAAiB,EACjB,MAAgB,EAChB,QAAa,EACb,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,cAAc,EAC1B,GAAO,EACP,MAAM,EACN,MAAuB,EACvB,UAA0B,EAC1B,SAAS,EACT,cAAoB,EACpB,QAAe,EACf,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,YAAY,+BAyId;AA0OD,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../src/heatmap.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAC;AAY7D,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAI,UAI/F;AAED,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG;IAC5C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC/B,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,+BAE1C;AAED,gBAAgB;AAChB,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,MAAM,EACN,KAAgB,EAChB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,cAAc,EAC1B,KAAiB,EACjB,MAAgB,EAChB,QAAa,EACb,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,cAAc,EAC1B,GAAO,EACP,MAAM,EACN,MAAuB,EACvB,UAA0B,EAC1B,SAAS,EACT,cAAoB,EACpB,QAAe,EACf,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAkB,EAClB,YAAY,EACZ,QAAmB,EACnB,YAAsB,EACtB,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA8LlB;AAwRD,eAAe,OAAO,CAAC"}
package/dist/heatmap.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useEffect, useId, useMemo, useRef, useState } from "react";
3
+ import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState, } from "react";
4
4
  import { luminance, parseHex } from "./colors.js";
5
5
  import { buildCells } from "./grid.js";
6
6
  import { fillStyle, isRoundShape, rowOffset, rowSpacing, shapeStyle } from "./shapes.js";
@@ -8,7 +8,22 @@ import { fillStyle, isRoundShape, rowOffset, rowSpacing, shapeStyle } from "./sh
8
8
  const DEFAULT_COLORS = ["#9be9a8", "#40c463", "#30a14e", "#216e39"];
9
9
  const DEFAULT_EMPTY = "#ebedf0";
10
10
  const TOOLTIP_DELAY = 300;
11
- export function Heatmap({ rows, columns, values, scale = "linear", levels: levelsProp, thresholds: thresholdsProp, shape = "rounded", encode = "color", cellSize = 13, cellWidth: cellWidthProp, cellHeight: cellHeightProp, gap = 3, radius, colors = DEFAULT_COLORS, emptyColor = DEFAULT_EMPTY, cellColor, unknownOpacity = 0.5, minScale = 0.35, rowLabels, columnLabels, tooltip, cellContent, cellLabel, onCellClick, isSlotHidden, showLegend = false, legendLabels, ariaLabel, className, style, ...rest }) {
11
+ const TOOLTIP_OFFSET = 8;
12
+ const COLUMN_LABEL_HEIGHT = 16;
13
+ // Measuring has to happen before paint, but the server has no layout to read.
14
+ const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
15
+ /** Columns of a given pitch that fit in `available` pixels. */
16
+ export function fittingColumns(available, columnWidth, gap, overhang = 0) {
17
+ if (!(available > 0) || !(columnWidth > 0))
18
+ return 0;
19
+ // The epsilon absorbs float error, so a grid that fits exactly is not a column short.
20
+ return Math.max(0, Math.floor((available + gap - overhang) / columnWidth + 1e-6));
21
+ }
22
+ export function Heatmap(props) {
23
+ return _jsx(HeatmapView, { ...props });
24
+ }
25
+ /** @internal */
26
+ export function HeatmapView({ rows, columns, values, scale = "linear", levels: levelsProp, thresholds: thresholdsProp, shape = "rounded", encode = "color", cellSize = 13, cellWidth: cellWidthProp, cellHeight: cellHeightProp, gap = 3, radius, colors = DEFAULT_COLORS, emptyColor = DEFAULT_EMPTY, cellColor, unknownOpacity = 0.5, minScale = 0.35, rowLabels, columnLabels, tooltip, cellContent, cellLabel, onCellClick, isSlotHidden, showLegend = false, legendLabels, overflow = "scroll", scrollAnchor = "start", onFitColumns, ariaLabel, className, style, ...rest }) {
12
27
  const levels = levelsProp ?? colors.length ?? 4;
13
28
  const { cells, total, unknownCount } = useMemo(() => buildCells({
14
29
  rows,
@@ -27,15 +42,77 @@ export function Heatmap({ rows, columns, values, scale = "linear", levels: level
27
42
  const overhang = shape === "hexagon" && rows > 1 ? columnWidth / 2 : 0;
28
43
  const width = columns * columnWidth - gap + overhang;
29
44
  const height = (rows - 1) * rowHeight + cellHeight;
45
+ const viewportRef = useRef(null);
46
+ const canvasRef = useRef(null);
47
+ // Null until measured, which the server never is.
48
+ const [overflowing, setOverflowing] = useState(null);
49
+ useIsomorphicLayoutEffect(() => {
50
+ const viewport = viewportRef.current;
51
+ const canvas = canvasRef.current;
52
+ if (!viewport || !canvas)
53
+ return;
54
+ const measure = () => {
55
+ // A container that is not laid out (display: none, a closed tab) has
56
+ // no width to fit; keep the last answer rather than collapse the grid.
57
+ if (viewport.clientWidth === 0)
58
+ return;
59
+ // The start padding is room for focus rings, not for cells. The end
60
+ // padding only exists while scrolling, so it is not subtracted.
61
+ const available = viewport.clientWidth - parseFloat(getComputedStyle(viewport).paddingLeft);
62
+ onFitColumns?.(fittingColumns(available, columnWidth, gap, overhang));
63
+ setOverflowing(canvas.getBoundingClientRect().width > available + 0.5);
64
+ };
65
+ measure();
66
+ if (typeof ResizeObserver === "undefined")
67
+ return;
68
+ const observer = new ResizeObserver(measure);
69
+ observer.observe(viewport);
70
+ observer.observe(canvas);
71
+ return () => observer.disconnect();
72
+ }, [onFitColumns, columnWidth, gap, overhang, width]);
73
+ // Unmeasured, the grid is assumed to overflow: clipping and anchoring a grid
74
+ // that turns out to fit is harmless, spilling one past its container is not.
75
+ const clipped = overflow === "scroll" && overflowing !== false;
76
+ // A scrolled grid must be reachable by keyboard. Focusable cells scroll it
77
+ // into view themselves; a grid of plain cells needs the viewport focusable.
78
+ const keyboardScroll = overflow === "scroll" && overflowing === true && !(tooltip || cellLabel || onCellClick);
79
+ const visibleColumnLabels = columnLabels && columnLabels.length > 0 ? columnLabels : null;
30
80
  const label = ariaLabel ??
31
81
  "Heatmap, " + rows + " by " + columns +
32
82
  (unknownCount > 0 ? ", " + unknownCount + " slots with no data" : "");
33
- return (_jsxs("div", { className: ["heatmap", className].filter(Boolean).join(" "), role: "group", "aria-label": label, "data-total": total, style: style, ...rest, children: [_jsxs("div", { className: "heatmap__body", children: [columnLabels && columnLabels.length > 0 ? (_jsx("div", { className: "heatmap__column-labels", style: { height: 16, width }, children: columnLabels.map((entry, index) => (_jsx("span", { className: "heatmap__column-label", style: { left: entry.column * columnWidth + cellWidth / 2 }, children: entry.text }, index))) })) : null, rowLabels && rowLabels.length > 0 ? (_jsx("div", { className: "heatmap__row-labels", style: { height, gridAutoRows: rowHeight }, children: rowLabels.map((text, index) => (_jsx("span", { className: "heatmap__row-label", style: { top: index * rowHeight, height: cellHeight }, children: text }, index))) })) : null, _jsx("div", { className: "heatmap__grid", style: { width, height }, children: cells.map((cell) => (_jsx(HeatmapCellView, { cell: cell, left: cell.column * columnWidth + rowOffset(shape, cell.row, columnWidth), top: cell.row * rowHeight, width: cellWidth, height: cellHeight, shape: shape, encode: encode, levels: levels, radius: radius, colors: colors, emptyColor: emptyColor, cellColor: cellColor, unknownOpacity: unknownOpacity, minScale: minScale, tooltip: tooltip, cellContent: cellContent, cellLabel: cellLabel, onCellClick: onCellClick, nearLeftEdge: cell.column === 0, nearRightEdge: cell.column === columns - 1 }, cell.row + ":" + cell.column))) })] }), showLegend ? (_jsxs("div", { className: "heatmap__legend", children: [_jsx("span", { children: legendLabels?.less ?? "less" }), _jsx(LegendSwatch, { color: emptyColor, shape: shape, width: cellWidth, height: cellHeight, radius: radius }), colors.map((color, index) => (_jsx(LegendSwatch, { color: color, shape: shape, width: cellWidth, height: cellHeight, radius: radius }, color + index))), _jsx("span", { children: legendLabels?.more ?? "more" }), unknownCount > 0 ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "heatmap__legend-unknown", children: legendLabels?.unknown ?? "no data" }), _jsx(LegendSwatch, { color: emptyColor, shape: shape, width: cellWidth, height: cellHeight, radius: radius, opacity: unknownOpacity })] })) : null] })) : null] }));
83
+ return (_jsxs("div", { className: ["heatmap", className].filter(Boolean).join(" "), role: "group", "aria-label": label, "data-total": total, "data-overflow": overflow, "data-fit": onFitColumns ? "true" : undefined, style: style, ...rest, children: [_jsxs("div", { className: "heatmap__body", children: [rowLabels && rowLabels.length > 0 ? (_jsx("div", { className: "heatmap__row-labels", style: {
84
+ height,
85
+ gridAutoRows: rowHeight,
86
+ marginTop: visibleColumnLabels ? COLUMN_LABEL_HEIGHT : 0,
87
+ }, children: rowLabels.map((text, index) => (_jsx("span", { className: "heatmap__row-label", style: { height: cellHeight }, children: text }, index))) })) : null, _jsx("div", { ref: viewportRef, className: "heatmap__viewport", "data-anchor": scrollAnchor, "data-scrolling": clipped ? "true" : undefined, tabIndex: keyboardScroll ? 0 : undefined, children: _jsxs("div", { ref: canvasRef, className: "heatmap__canvas", children: [visibleColumnLabels ? (_jsx("div", { className: "heatmap__column-labels", style: { height: COLUMN_LABEL_HEIGHT, width }, children: visibleColumnLabels.map((entry, index) => (_jsx("span", { className: "heatmap__column-label", style: { left: entry.column * columnWidth + cellWidth / 2 }, children: entry.text }, index))) })) : null, _jsx("div", { className: "heatmap__grid", style: { width, height }, children: cells.map((cell) => (_jsx(HeatmapCellView, { cell: cell, left: cell.column * columnWidth + rowOffset(shape, cell.row, columnWidth), top: cell.row * rowHeight, width: cellWidth, height: cellHeight, shape: shape, encode: encode, levels: levels, radius: radius, colors: colors, emptyColor: emptyColor, cellColor: cellColor, unknownOpacity: unknownOpacity, minScale: minScale, tooltip: tooltip, cellContent: cellContent, cellLabel: cellLabel, onCellClick: onCellClick, nearLeftEdge: cell.column === 0, nearRightEdge: cell.column === columns - 1 }, cell.row + ":" + cell.column))) })] }) })] }), showLegend ? (_jsxs("div", { className: "heatmap__legend", children: [_jsx("span", { children: legendLabels?.less ?? "less" }), _jsx(LegendSwatch, { color: emptyColor, shape: shape, width: cellWidth, height: cellHeight, radius: radius }), colors.map((color, index) => (_jsx(LegendSwatch, { color: color, shape: shape, width: cellWidth, height: cellHeight, radius: radius }, color + index))), _jsx("span", { children: legendLabels?.more ?? "more" }), unknownCount > 0 ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "heatmap__legend-unknown", children: legendLabels?.unknown ?? "no data" }), _jsx(LegendSwatch, { color: emptyColor, shape: shape, width: cellWidth, height: cellHeight, radius: radius, opacity: unknownOpacity })] })) : null] })) : null] }));
34
88
  }
35
89
  function HeatmapCellView({ cell, left, top, width, height, shape, encode, levels, radius, colors, emptyColor, cellColor, unknownOpacity, minScale, tooltip, cellContent, cellLabel, onCellClick, nearLeftEdge, nearRightEdge, }) {
36
90
  const tooltipId = useId();
37
91
  const timer = useRef(null);
92
+ const slotRef = useRef(null);
93
+ const tooltipRef = useRef(null);
38
94
  const [open, setOpen] = useState(false);
95
+ // Only rendered once open, which only happens in the browser.
96
+ const topLayer = open && supportsPopover();
97
+ // A scrolling grid clips its overflow, so a tooltip drawn inside it would be
98
+ // cut off at the top row. The top layer escapes every ancestor's clipping
99
+ // and transform while staying in the DOM, so theme variables still apply.
100
+ useIsomorphicLayoutEffect(() => {
101
+ const slot = slotRef.current;
102
+ const tip = tooltipRef.current;
103
+ if (!topLayer || !slot || !tip)
104
+ return;
105
+ tip.showPopover();
106
+ placeTooltip(tip, slot);
107
+ // A scroll or resize would leave it pointing at nothing.
108
+ const close = () => setOpen(false);
109
+ window.addEventListener("scroll", close, true);
110
+ window.addEventListener("resize", close);
111
+ return () => {
112
+ window.removeEventListener("scroll", close, true);
113
+ window.removeEventListener("resize", close);
114
+ };
115
+ }, [topLayer]);
39
116
  useEffect(() => () => {
40
117
  if (timer.current !== null)
41
118
  window.clearTimeout(timer.current);
@@ -111,7 +188,7 @@ function HeatmapCellView({ cell, left, top, width, height, shape, encode, levels
111
188
  }
112
189
  : {}),
113
190
  };
114
- return (_jsxs("div", { className: "heatmap__cell-slot", style: { left, top, width, height }, "data-known": cell.known ? "true" : "false", "data-level": cell.level, tabIndex: interactive ? 0 : undefined,
191
+ return (_jsxs("div", { ref: slotRef, className: "heatmap__cell-slot", style: { left, top, width, height }, "data-known": cell.known ? "true" : "false", "data-level": cell.level, tabIndex: interactive ? 0 : undefined,
115
192
  // A generic div may not carry aria-label, so a labelled cell is an image
116
193
  // of its value, as in Heatmap3D. Unlabelled cells stay generic.
117
194
  role: onCellClick ? "button" : name ? "img" : undefined, "aria-label": name, "aria-describedby": open ? tooltipId : undefined, onPointerEnter: show, onPointerLeave: hide, onFocus: show, onBlur: hide, onClick: onCellClick ? () => onCellClick(cell) : undefined, onKeyDown: onCellClick
@@ -121,7 +198,20 @@ function HeatmapCellView({ cell, left, top, width, height, shape, encode, levels
121
198
  onCellClick(cell);
122
199
  }
123
200
  }
124
- : undefined, children: [_jsx("div", { className: "heatmap__cell", style: { ...fill, opacity: cell.known ? 1 : unknownOpacity }, children: hasVisualContent ? (_jsx("span", { className: "heatmap__cell-content", "aria-hidden": "true", style: contentStyle, children: visualContent })) : null }), open && content ? (_jsx("div", { id: tooltipId, className: "heatmap__tooltip", role: "tooltip", "data-align": nearLeftEdge ? "start" : nearRightEdge ? "end" : "center", children: content })) : null] }));
201
+ : undefined, children: [_jsx("div", { className: "heatmap__cell", style: { ...fill, opacity: cell.known ? 1 : unknownOpacity }, children: hasVisualContent ? (_jsx("span", { className: "heatmap__cell-content", "aria-hidden": "true", style: contentStyle, children: visualContent })) : null }), open && content ? (_jsx("div", { ref: tooltipRef, id: tooltipId, className: "heatmap__tooltip", role: "tooltip", popover: topLayer ? "manual" : undefined, "data-align": topLayer ? undefined : nearLeftEdge ? "start" : nearRightEdge ? "end" : "center", children: content })) : null] }));
202
+ }
203
+ function supportsPopover() {
204
+ return typeof HTMLElement !== "undefined" && "showPopover" in HTMLElement.prototype;
205
+ }
206
+ /** Centres the tooltip above its cell, flipping below and clamping to the viewport. */
207
+ function placeTooltip(tip, anchor) {
208
+ const cell = anchor.getBoundingClientRect();
209
+ const { width, height } = tip.getBoundingClientRect();
210
+ const viewportWidth = document.documentElement.clientWidth;
211
+ const left = Math.min(Math.max(TOOLTIP_OFFSET, cell.left + cell.width / 2 - width / 2), Math.max(TOOLTIP_OFFSET, viewportWidth - width - TOOLTIP_OFFSET));
212
+ const above = cell.top - height - TOOLTIP_OFFSET;
213
+ tip.style.left = left + "px";
214
+ tip.style.top = (above >= 0 ? above : cell.bottom + TOOLTIP_OFFSET) + "px";
125
215
  }
126
216
  /*
127
217
  * The legend is a key, not data, so its swatches read a step below the cells
@@ -1 +1 @@
1
- {"version":3,"file":"heatmap.js","sourceRoot":"","sources":["../src/heatmap.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"heatmap.js","sourceRoot":"","sources":["../src/heatmap.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  export { Heatmap } from "./heatmap.js";
2
2
  export { Heatmap3D } from "./heatmap3d.js";
3
3
  export { renderHeatmap3DSvg, type Heatmap3DSvgLabel, type Heatmap3DSvgOptions } from "./static-svg.js";
4
- export { CalendarHeatmap, CalendarHeatmap3D, type CalendarCell, type CalendarDay, type CalendarHeatmapProps, type CalendarHeatmap3DProps } from "./calendar.js";
4
+ export { CalendarHeatmap, CalendarHeatmap3D, type CalendarCell, type CalendarDay, type CalendarHeatmapProps, type CalendarHeatmap3DProps, type CalendarWeeks } from "./calendar.js";
5
+ export { calendarPeriods, type CalendarPeriod, type CalendarPeriodsOptions, type CalendarRange } from "./periods.js";
5
6
  export { normalizeCamera, resolveHeightDomain, valueToHeight, projectPoint, projectionBounds, type Point3D, type ProjectedPoint } from "./projection3d.js";
6
7
  export { buildCells, normalizeValues, resolveThresholds } from "./grid.js";
7
8
  export { levelForValue, linearThresholds, logThresholds, quantileThresholds, } from "./scale.js";
8
9
  export { fillStyle, rowOffset, rowSpacing, shapeStyle } from "./shapes.js";
9
10
  export { deriveRamp, HEATMAP_3D_THEMES, luminance, mixHex, parseHex, resolve3DColors, resolve3DFaceColor, resolve3DTheme, type Heatmap3DThemePreset, type RampOptions, } from "./colors.js";
10
- export type { HeatmapCell, Heatmap3DProps, Heatmap3DShape, Heatmap3DBlockStyle, Heatmap3DCamera, Heatmap3DFace, Heatmap3DFaceColor, Heatmap3DFaceColorArgs, Heatmap3DThemeName, Heatmap3DMaterial, Heatmap3DPattern, Heatmap3DAnimation, HeatmapEncoding, HeatmapLegendLabels, HeatmapMatrix, HeatmapProps, HeatmapScale, HeatmapShape, HeatmapValues, ResolvedCell, } from "./types.js";
11
+ export type { HeatmapCell, Heatmap3DProps, Heatmap3DShape, Heatmap3DBlockStyle, Heatmap3DCamera, Heatmap3DFace, Heatmap3DFaceColor, Heatmap3DFaceColorArgs, Heatmap3DThemeName, Heatmap3DMaterial, Heatmap3DPattern, Heatmap3DAnimation, HeatmapEncoding, HeatmapLegendLabels, HeatmapMatrix, HeatmapOverflow, HeatmapProps, HeatmapScale, HeatmapShape, HeatmapValues, ResolvedCell, } from "./types.js";
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAChK,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC3J,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACpL,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACrH,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC3J,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,WAAW,EACX,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export { Heatmap } from "./heatmap.js";
3
3
  export { Heatmap3D } from "./heatmap3d.js";
4
4
  export { renderHeatmap3DSvg } from "./static-svg.js";
5
5
  export { CalendarHeatmap, CalendarHeatmap3D } from "./calendar.js";
6
+ export { calendarPeriods } from "./periods.js";
6
7
  export { normalizeCamera, resolveHeightDomain, valueToHeight, projectPoint, projectionBounds } from "./projection3d.js";
7
8
  export { buildCells, normalizeValues, resolveThresholds } from "./grid.js";
8
9
  export { levelForValue, linearThresholds, logThresholds, quantileThresholds, } from "./scale.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAoD,MAAM,iBAAiB,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAA+F,MAAM,eAAe,CAAC;AAChK,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAqC,MAAM,mBAAmB,CAAC;AAC3J,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,cAAc,GAGf,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAoD,MAAM,iBAAiB,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAmH,MAAM,eAAe,CAAC;AACpL,OAAO,EAAE,eAAe,EAAwE,MAAM,cAAc,CAAC;AACrH,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAqC,MAAM,mBAAmB,CAAC;AAC3J,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,cAAc,GAGf,MAAM,aAAa,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The periods a calendar can be switched between: a rolling window ending
3
+ * today, then each calendar year with data, newest first. This is only the
4
+ * date arithmetic; the picker belongs to the app, in its own components.
5
+ */
6
+ /** Spread into a calendar: `<CalendarHeatmap {...period.range} />`. */
7
+ export type CalendarRange = {
8
+ /** Absent for the rolling window, whose length is the calendar's `weeks`. */
9
+ from?: string;
10
+ to: string;
11
+ };
12
+ export type CalendarPeriod = {
13
+ /** Stable and unique: "rolling", or the year as a string. */
14
+ key: string;
15
+ /** A default, English label. Relabel from `kind` and `year` as needed. */
16
+ label: string;
17
+ kind: "rolling" | "year";
18
+ /** Set for a year period. */
19
+ year?: number;
20
+ range: CalendarRange;
21
+ };
22
+ export type CalendarPeriodsOptions = {
23
+ /** The day the periods are measured from. Defaults to today. */
24
+ today?: string | Date;
25
+ /** Leads with a window ending today. Defaults to true. */
26
+ rolling?: boolean;
27
+ /** Defaults to "Last 12 months". */
28
+ rollingLabel?: string;
29
+ };
30
+ /**
31
+ * Years come from the source: explicit years are used as given, while days
32
+ * are read for the first year with data, which runs up to the current year so
33
+ * a quiet year in between still has a period. Years after today are left out
34
+ * of the derived list, since their days are not in any range yet.
35
+ */
36
+ export declare function calendarPeriods(source?: ReadonlyArray<{
37
+ date: string;
38
+ }> | ReadonlyArray<number>, { today, rolling, rollingLabel }?: CalendarPeriodsOptions): CalendarPeriod[];
39
+ //# sourceMappingURL=periods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"periods.d.ts","sourceRoot":"","sources":["../src/periods.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG;IAC1B,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,GAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,aAAa,CAAC,MAAM,CAAM,EACpE,EAAE,KAAK,EAAE,OAAc,EAAE,YAA+B,EAAE,GAAE,sBAA2B,GACtF,cAAc,EAAE,CAsBlB"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The periods a calendar can be switched between: a rolling window ending
3
+ * today, then each calendar year with data, newest first. This is only the
4
+ * date arithmetic; the picker belongs to the app, in its own components.
5
+ */
6
+ /**
7
+ * Years come from the source: explicit years are used as given, while days
8
+ * are read for the first year with data, which runs up to the current year so
9
+ * a quiet year in between still has a period. Years after today are left out
10
+ * of the derived list, since their days are not in any range yet.
11
+ */
12
+ export function calendarPeriods(source = [], { today, rolling = true, rollingLabel = "Last 12 months" } = {}) {
13
+ const todayKey = isoDay(today ?? new Date()) ?? isoDay(new Date());
14
+ const currentYear = Number(todayKey.slice(0, 4));
15
+ const periods = rolling
16
+ ? [{ key: "rolling", label: rollingLabel, kind: "rolling", range: { to: todayKey } }]
17
+ : [];
18
+ for (const year of yearsOf(source, currentYear)) {
19
+ periods.push({
20
+ key: String(year),
21
+ label: String(year),
22
+ kind: "year",
23
+ year,
24
+ range: {
25
+ from: pad(year) + "-01-01",
26
+ // The current year runs to today: the rest of it has not happened.
27
+ to: year === currentYear ? todayKey : pad(year) + "-12-31",
28
+ },
29
+ });
30
+ }
31
+ return periods;
32
+ }
33
+ function yearsOf(source, currentYear) {
34
+ if (source.length > 0 && typeof source[0] === "number") {
35
+ const years = source.filter((year) => Number.isInteger(year) && year > 0);
36
+ return [...new Set(years)].sort((a, b) => b - a);
37
+ }
38
+ let first = currentYear;
39
+ for (const day of source) {
40
+ const year = Number(String(day?.date).slice(0, 4));
41
+ if (Number.isInteger(year) && year > 0 && year < first)
42
+ first = year;
43
+ }
44
+ return Array.from({ length: currentYear - first + 1 }, (_, index) => currentYear - index);
45
+ }
46
+ function isoDay(value) {
47
+ const date = typeof value === "string" ? new Date(value.slice(0, 10) + "T00:00:00Z") : value;
48
+ if (Number.isNaN(date.getTime()))
49
+ return null;
50
+ // A Date is read in UTC, as the calendar reads it.
51
+ return date.toISOString().slice(0, 10);
52
+ }
53
+ function pad(year) {
54
+ return String(year).padStart(4, "0");
55
+ }
56
+ //# sourceMappingURL=periods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"periods.js","sourceRoot":"","sources":["../src/periods.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -32,6 +32,12 @@ export type HeatmapShape = "rounded" | "square" | "circle" | "diamond" | "hexago
32
32
  */
33
33
  export type HeatmapEncoding = "color" | "size" | "both";
34
34
  export type HeatmapScale = "quantile" | "linear" | "log" | ((value: number, values: readonly number[]) => number);
35
+ /**
36
+ * What a grid wider than its container does. "scroll" keeps the chart inside
37
+ * the container and scrolls the cells, with the row labels and legend held
38
+ * still. "visible" lets it spill out, for callers who manage overflow themselves.
39
+ */
40
+ export type HeatmapOverflow = "scroll" | "visible";
35
41
  export type HeatmapLegendLabels = {
36
42
  less?: ReactNode;
37
43
  more?: ReactNode;
@@ -93,6 +99,8 @@ export type HeatmapProps = Omit<HTMLAttributes<HTMLDivElement>, "values"> & {
93
99
  onCellClick?: (cell: ResolvedCell) => void;
94
100
  showLegend?: boolean;
95
101
  legendLabels?: HeatmapLegendLabels;
102
+ /** Defaults to "scroll". */
103
+ overflow?: HeatmapOverflow;
96
104
  ariaLabel?: string;
97
105
  style?: CSSProperties;
98
106
  };
@@ -129,7 +137,7 @@ export type Heatmap3DFaceColorArgs = {
129
137
  /** Override the default top/side material treatment for a cell. */
130
138
  export type Heatmap3DFaceColor = (args: Heatmap3DFaceColorArgs) => string;
131
139
  /** Heights encode actual values linearly, independently of the colour bands. */
132
- export type Heatmap3DProps = Omit<HeatmapProps, "shape" | "encode" | "radius" | "minScale" | "cellContent" | "cellWidth" | "cellHeight" | "cellColor"> & {
140
+ export type Heatmap3DProps = Omit<HeatmapProps, "shape" | "encode" | "radius" | "minScale" | "cellContent" | "cellWidth" | "cellHeight" | "cellColor" | "overflow"> & {
133
141
  shape?: Heatmap3DShape;
134
142
  blockStyle?: Heatmap3DBlockStyle;
135
143
  /** Surface treatment. `color` defers to `colors`; the rest set their own. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thilakbhat/heatmap-ui",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "A headless heatmap toolkit for React. Any grid, eight cell shapes, a 3D SVG mode, and full control of colour, size and layout.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -47,10 +47,10 @@
47
47
  "@types/react-dom": "^19.0.0",
48
48
  "typescript": "^5.0.0"
49
49
  },
50
- "repository": { "type": "git", "url": "git+https://github.com/tb962/heatmap-ui.git" },
51
- "homepage": "https://tb962.github.io/heatmap-ui/",
52
- "bugs": { "url": "https://github.com/tb962/heatmap-ui/issues" },
53
- "author": "tb962",
50
+ "repository": { "type": "git", "url": "git+https://github.com/thilakbhat/heatmap-ui.git" },
51
+ "homepage": "https://thilakbhat.github.io/heatmap-ui/",
52
+ "bugs": { "url": "https://github.com/thilakbhat/heatmap-ui/issues" },
53
+ "author": "thilakbhat",
54
54
  "keywords": [
55
55
  "heatmap", "react", "calendar-heatmap", "contribution-graph", "punchcard",
56
56
  "hexbin", "data-visualization", "grid", "accessible", "headless",
package/src/styles.css CHANGED
@@ -22,18 +22,74 @@
22
22
  box-sizing: border-box;
23
23
  }
24
24
 
25
+ /* Scrolling keeps the chart inside its container instead of spilling out. */
26
+ .heatmap[data-overflow="scroll"] {
27
+ max-width: 100%;
28
+ }
29
+
30
+ /* A fitted chart spans its container, so the space it measures is the
31
+ * container's and never its own content's. */
32
+ .heatmap[data-fit] {
33
+ display: flex;
34
+ width: 100%;
35
+ }
36
+
25
37
  /*
26
- * A 2x2 grid ties the label tracks to the cell grid: the column labels share a
27
- * column with the cells, so they cannot drift out of alignment when the row
28
- * label gutter changes width.
38
+ * Row labels sit beside the viewport rather than inside it, so they stay put
39
+ * while the cells scroll. Being outside, they need no background to hide the
40
+ * cells passing beneath, which a sticky label would.
29
41
  */
30
42
  .heatmap__body {
31
- display: grid;
32
- grid-template-columns: auto auto;
43
+ display: flex;
44
+ align-items: flex-start;
45
+ min-width: 0;
46
+ }
47
+
48
+ /*
49
+ * The viewport scrolls; the canvas inside it holds the column labels and the
50
+ * cells together, so they cannot drift out of alignment. Padding cancelled by
51
+ * negative margins gives focus rings and hovered cells room inside the clip
52
+ * without moving the grid. The end side gets padding only while scrolling,
53
+ * since a negative margin there would hang past the container.
54
+ */
55
+ .heatmap__viewport {
56
+ flex: 0 1 auto;
57
+ min-width: 0;
58
+ margin: -4px 0 -4px -4px;
59
+ padding: 4px 0 4px 4px;
60
+ }
61
+
62
+ .heatmap[data-fit] .heatmap__viewport {
63
+ flex: 1 1 0;
64
+ }
65
+
66
+ .heatmap__viewport[data-scrolling] {
67
+ overflow-x: auto;
68
+ overflow-y: hidden;
69
+ overscroll-behavior-x: contain;
70
+ padding-right: 4px;
71
+ }
72
+
73
+ /* Scroll origin follows direction, so an end-anchored viewport opens on its
74
+ * newest column and stays there as it resizes, with or without script. */
75
+ .heatmap__viewport[data-anchor="end"] {
76
+ direction: rtl;
77
+ }
78
+
79
+ .heatmap__viewport:focus-visible {
80
+ outline: 2px solid currentColor;
81
+ outline-offset: -2px;
82
+ border-radius: 4px;
83
+ }
84
+
85
+ .heatmap__canvas {
86
+ direction: ltr;
87
+ width: max-content;
88
+ /* Keeps a narrower grid at the start edge inside a right-to-left viewport. */
89
+ margin-right: auto;
33
90
  }
34
91
 
35
92
  .heatmap__grid {
36
- grid-area: 2 / 2;
37
93
  position: relative;
38
94
  }
39
95
 
@@ -91,7 +147,6 @@
91
147
 
92
148
  /* Column labels sit above the cells, each centred on the column it names. */
93
149
  .heatmap__column-labels {
94
- grid-area: 1 / 2;
95
150
  position: relative;
96
151
  }
97
152
 
@@ -106,8 +161,8 @@
106
161
  }
107
162
 
108
163
  .heatmap__row-labels {
109
- grid-area: 2 / 1;
110
- /* Size the track to its widest label; the gutter is a margin, not a grid gap. */
164
+ flex: none;
165
+ /* Size the track to its widest label; the gutter is a margin, not a gap. */
111
166
  margin-inline-end: 6px;
112
167
  position: relative;
113
168
  display: grid;
@@ -127,6 +182,7 @@
127
182
 
128
183
  .heatmap__legend {
129
184
  display: flex;
185
+ flex-wrap: wrap;
130
186
  align-items: center;
131
187
  gap: 3px;
132
188
  color: var(--heatmap-label);
@@ -176,6 +232,15 @@
176
232
  right: 0;
177
233
  }
178
234
 
235
+ /* In the top layer the tooltip is placed by script in viewport coordinates.
236
+ * These undo the absolute placement above and the UA popover defaults. */
237
+ .heatmap__tooltip[popover] {
238
+ position: fixed;
239
+ inset: auto;
240
+ margin: 0;
241
+ overflow: visible;
242
+ }
243
+
179
244
  @media (prefers-color-scheme: dark) {
180
245
  .heatmap:not([data-heatmap-theme="light"]) {
181
246
  --heatmap-tooltip-bg: rgba(240, 238, 235, 0.97);