@aceshooting/lyra-ui 1.0.1 → 1.1.0

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.
Files changed (148) hide show
  1. package/README.md +8 -9
  2. package/custom-elements.json +12479 -6535
  3. package/dist/components/chart/chart.d.ts +46 -1
  4. package/dist/components/chart/chart.js +148 -10
  5. package/dist/components/chart/chart.stories.d.ts +32 -0
  6. package/dist/components/chart/chart.stories.js +141 -0
  7. package/dist/components/chart/chart.styles.js +16 -0
  8. package/dist/components/chart/histogram.d.ts +2 -0
  9. package/dist/components/chart/histogram.js +18 -2
  10. package/dist/components/chart/line-chart.stories.d.ts +17 -0
  11. package/dist/components/chart/line-chart.stories.js +75 -0
  12. package/dist/components/chart/lite-chart.d.ts +74 -0
  13. package/dist/components/chart/lite-chart.js +384 -0
  14. package/dist/components/chart/lite-chart.stories.d.ts +12 -0
  15. package/dist/components/chart/lite-chart.stories.js +98 -0
  16. package/dist/components/chart/lite-chart.styles.d.ts +1 -0
  17. package/dist/components/chart/lite-chart.styles.js +83 -0
  18. package/dist/components/combobox/combobox.d.ts +9 -0
  19. package/dist/components/combobox/combobox.js +75 -12
  20. package/dist/components/combobox/combobox.stories.d.ts +18 -0
  21. package/dist/components/combobox/combobox.stories.js +75 -0
  22. package/dist/components/date-picker/calendar-core.js +13 -2
  23. package/dist/components/date-picker/date-input.d.ts +9 -1
  24. package/dist/components/date-picker/date-input.js +55 -7
  25. package/dist/components/date-picker/date-input.stories.d.ts +5 -0
  26. package/dist/components/date-picker/date-input.stories.js +36 -0
  27. package/dist/components/date-picker/date-picker.d.ts +11 -3
  28. package/dist/components/date-picker/date-picker.js +87 -37
  29. package/dist/components/date-picker/date-picker.stories.d.ts +4 -0
  30. package/dist/components/date-picker/date-picker.stories.js +12 -0
  31. package/dist/components/date-picker/date-picker.styles.js +1 -1
  32. package/dist/components/empty/empty.d.ts +12 -1
  33. package/dist/components/empty/empty.js +20 -3
  34. package/dist/components/empty/empty.stories.d.ts +2 -0
  35. package/dist/components/empty/empty.stories.js +20 -0
  36. package/dist/components/empty/empty.styles.js +11 -0
  37. package/dist/components/export-button/csv.js +6 -2
  38. package/dist/components/export-button/export-button.d.ts +15 -1
  39. package/dist/components/export-button/export-button.js +89 -12
  40. package/dist/components/export-button/export-button.stories.d.ts +1 -0
  41. package/dist/components/export-button/export-button.stories.js +5 -0
  42. package/dist/components/export-button/export-button.styles.js +11 -3
  43. package/dist/components/file-input/accept.d.ts +8 -2
  44. package/dist/components/file-input/accept.js +9 -3
  45. package/dist/components/file-input/file-input.d.ts +5 -2
  46. package/dist/components/file-input/file-input.js +23 -8
  47. package/dist/components/file-input/file-input.stories.d.ts +2 -0
  48. package/dist/components/file-input/file-input.stories.js +9 -0
  49. package/dist/components/flag/flag.d.ts +48 -3
  50. package/dist/components/flag/flag.js +65 -29
  51. package/dist/components/flag/flag.styles.js +1 -1
  52. package/dist/components/flag/language-map.d.ts +11 -0
  53. package/dist/components/flag/language-map.js +12 -1
  54. package/dist/components/gauge/gauge.d.ts +2 -0
  55. package/dist/components/gauge/gauge.js +19 -5
  56. package/dist/components/gauge/gauge.stories.d.ts +2 -0
  57. package/dist/components/gauge/gauge.stories.js +6 -0
  58. package/dist/components/graph/graph-loader.d.ts +28 -0
  59. package/dist/components/graph/graph-loader.js +44 -0
  60. package/dist/components/graph/graph.d.ts +41 -15
  61. package/dist/components/graph/graph.js +146 -71
  62. package/dist/components/graph/graph.stories.d.ts +3 -0
  63. package/dist/components/graph/graph.stories.js +38 -0
  64. package/dist/components/graph/graph.styles.js +6 -1
  65. package/dist/components/heatmap/calendar-grid.d.ts +7 -0
  66. package/dist/components/heatmap/calendar-grid.js +27 -10
  67. package/dist/components/heatmap/heatmap.d.ts +137 -12
  68. package/dist/components/heatmap/heatmap.js +427 -27
  69. package/dist/components/heatmap/heatmap.stories.d.ts +17 -0
  70. package/dist/components/heatmap/heatmap.stories.js +130 -0
  71. package/dist/components/heatmap/heatmap.styles.js +60 -2
  72. package/dist/components/map/map.d.ts +17 -1
  73. package/dist/components/map/map.js +68 -21
  74. package/dist/components/map/map.stories.d.ts +10 -0
  75. package/dist/components/map/map.stories.js +107 -12
  76. package/dist/components/map/map.styles.js +2 -2
  77. package/dist/components/playback/playback.d.ts +6 -2
  78. package/dist/components/playback/playback.js +36 -12
  79. package/dist/components/playback/playback.stories.d.ts +2 -0
  80. package/dist/components/playback/playback.stories.js +6 -0
  81. package/dist/components/playback/playback.styles.js +10 -2
  82. package/dist/components/select/select.d.ts +122 -0
  83. package/dist/components/select/select.js +516 -0
  84. package/dist/components/select/select.stories.d.ts +19 -0
  85. package/dist/components/select/select.stories.js +75 -0
  86. package/dist/components/select/select.styles.d.ts +1 -0
  87. package/dist/components/select/select.styles.js +188 -0
  88. package/dist/components/skeleton/skeleton.js +4 -7
  89. package/dist/components/sparkline/sparkline.d.ts +1 -1
  90. package/dist/components/sparkline/sparkline.js +40 -13
  91. package/dist/components/sparkline/sparkline.stories.d.ts +4 -0
  92. package/dist/components/sparkline/sparkline.stories.js +22 -0
  93. package/dist/components/split/split.d.ts +24 -3
  94. package/dist/components/split/split.js +155 -31
  95. package/dist/components/split/split.stories.d.ts +2 -0
  96. package/dist/components/split/split.stories.js +20 -0
  97. package/dist/components/stat/stat.d.ts +27 -1
  98. package/dist/components/stat/stat.js +56 -3
  99. package/dist/components/stat/stat.stories.d.ts +3 -0
  100. package/dist/components/stat/stat.stories.js +49 -1
  101. package/dist/components/stat/stat.styles.js +44 -0
  102. package/dist/components/table/table.d.ts +64 -2
  103. package/dist/components/table/table.js +213 -17
  104. package/dist/components/table/table.stories.d.ts +6 -0
  105. package/dist/components/table/table.stories.js +45 -0
  106. package/dist/components/table/table.styles.js +51 -4
  107. package/dist/components/time-range/time-range.d.ts +34 -5
  108. package/dist/components/time-range/time-range.js +217 -36
  109. package/dist/components/time-range/time-range.stories.d.ts +2 -0
  110. package/dist/components/time-range/time-range.stories.js +13 -0
  111. package/dist/components/time-range/time-range.styles.js +44 -2
  112. package/dist/components/toast/toast-item.d.ts +14 -2
  113. package/dist/components/toast/toast-item.js +134 -17
  114. package/dist/components/toast/toast-item.styles.js +28 -2
  115. package/dist/components/toast/toast.stories.d.ts +3 -0
  116. package/dist/components/toast/toast.stories.js +41 -1
  117. package/dist/components/toast/toast.styles.js +11 -11
  118. package/dist/components/toast/toaster.d.ts +1 -1
  119. package/dist/components/toast/toaster.js +13 -6
  120. package/dist/components/tree/tree-node.d.ts +13 -7
  121. package/dist/components/tree/tree-node.js +24 -10
  122. package/dist/components/tree/tree.d.ts +64 -15
  123. package/dist/components/tree/tree.js +113 -22
  124. package/dist/components/tree/tree.stories.d.ts +4 -0
  125. package/dist/components/tree/tree.stories.js +31 -1
  126. package/dist/components/tree/update-cascade.d.ts +13 -0
  127. package/dist/components/tree/update-cascade.js +13 -0
  128. package/dist/components/widget/widget.d.ts +15 -1
  129. package/dist/components/widget/widget.js +140 -5
  130. package/dist/components/widget/widget.stories.d.ts +1 -0
  131. package/dist/components/widget/widget.stories.js +10 -0
  132. package/dist/components/widget/widget.styles.js +11 -1
  133. package/dist/components/word-cloud/word-cloud-layout.d.ts +63 -0
  134. package/dist/components/word-cloud/word-cloud-layout.js +145 -0
  135. package/dist/components/word-cloud/word-cloud.d.ts +65 -0
  136. package/dist/components/word-cloud/word-cloud.js +255 -0
  137. package/dist/components/word-cloud/word-cloud.stories.d.ts +10 -0
  138. package/dist/components/word-cloud/word-cloud.stories.js +55 -0
  139. package/dist/components/word-cloud/word-cloud.styles.d.ts +1 -0
  140. package/dist/components/word-cloud/word-cloud.styles.js +54 -0
  141. package/dist/internal/a11y.js +2 -1
  142. package/dist/internal/rtl.d.ts +7 -0
  143. package/dist/internal/rtl.js +9 -0
  144. package/dist/lyra.d.ts +9 -1
  145. package/dist/lyra.js +6 -0
  146. package/llms-full.txt +892 -276
  147. package/llms.txt +12 -9
  148. package/package.json +6 -4
@@ -28,3 +28,41 @@ export const Default = {
28
28
  ></lyra-graph>
29
29
  `,
30
30
  };
31
+ export const TunedForces = {
32
+ render: () => html `
33
+ <lyra-graph
34
+ width="480"
35
+ height="320"
36
+ style="height: 20rem"
37
+ charge-strength="-900"
38
+ link-distance="200"
39
+ .nodes=${nodes}
40
+ .links=${links}
41
+ ></lyra-graph>
42
+ `,
43
+ };
44
+ export const BoundedZoom = {
45
+ render: () => html `
46
+ <lyra-graph
47
+ width="480"
48
+ height="320"
49
+ style="height: 20rem"
50
+ min-zoom="1"
51
+ max-zoom="2"
52
+ .nodes=${nodes}
53
+ .links=${links}
54
+ ></lyra-graph>
55
+ `,
56
+ };
57
+ export const SeededLayout = {
58
+ render: () => html `
59
+ <p>
60
+ Both graphs below share <code>seed="42"</code> — reload the page or diff a screenshot across builds and their
61
+ node positions are bit-identical, unlike the non-seeded <code>Default</code> story above.
62
+ </p>
63
+ <div style="display: flex; gap: 1rem; flex-wrap: wrap">
64
+ <lyra-graph width="320" height="240" style="height: 15rem" seed="42" .nodes=${nodes} .links=${links}></lyra-graph>
65
+ <lyra-graph width="320" height="240" style="height: 15rem" seed="42" .nodes=${nodes} .links=${links}></lyra-graph>
66
+ </div>
67
+ `,
68
+ };
@@ -11,6 +11,11 @@ export const styles = css `
11
11
  [part='link'] {
12
12
  stroke: var(--lyra-color-border);
13
13
  fill: none;
14
+ cursor: pointer;
15
+ }
16
+ [part='link']:focus-visible {
17
+ outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
18
+ outline-offset: var(--lyra-focus-ring-offset);
14
19
  }
15
20
  [part='node'] {
16
21
  /* --lyra-node-fill is set inline per-node (see graph.ts) from GraphNode.color;
@@ -26,7 +31,7 @@ export const styles = css `
26
31
  outline-offset: var(--lyra-focus-ring-offset);
27
32
  }
28
33
  [part='label'] {
29
- font-size: 10px;
34
+ font-size: 0.625rem;
30
35
  fill: var(--lyra-color-text);
31
36
  font-family: var(--lyra-font);
32
37
  pointer-events: none;
@@ -17,6 +17,13 @@ export declare function parseIsoDate(iso: string): Date;
17
17
  * Lays `days` out onto a GitHub-style Sunday-Saturday x week grid. `days`
18
18
  * need not be sorted or contiguous; the grid spans from the earliest to the
19
19
  * latest date present, anchored at the Sunday on/before the earliest date.
20
+ *
21
+ * An entry whose `date` doesn't parse to a valid calendar date (e.g. `''` or
22
+ * `'2026-03'`) is dropped rather than included: `parseIsoDate` on a malformed
23
+ * string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
24
+ * single `NaN` reach the min/max below would poison `firstWeekStart` (and
25
+ * therefore every cell's `week`) for the whole grid instead of just the bad
26
+ * entry.
20
27
  */
21
28
  export declare function buildCalendarGrid(days: CalendarDay[]): {
22
29
  cells: CalendarCell[];
@@ -1,3 +1,4 @@
1
+ import { minMax } from './heatmap-scale.js';
1
2
  const MS_PER_DAY = 86_400_000;
2
3
  /** Parses a `yyyy-mm-dd` string as UTC midnight, avoiding local-timezone day-boundary drift. */
3
4
  export function parseIsoDate(iso) {
@@ -8,14 +9,23 @@ export function parseIsoDate(iso) {
8
9
  * Lays `days` out onto a GitHub-style Sunday-Saturday x week grid. `days`
9
10
  * need not be sorted or contiguous; the grid spans from the earliest to the
10
11
  * latest date present, anchored at the Sunday on/before the earliest date.
12
+ *
13
+ * An entry whose `date` doesn't parse to a valid calendar date (e.g. `''` or
14
+ * `'2026-03'`) is dropped rather than included: `parseIsoDate` on a malformed
15
+ * string yields an `Invalid Date` (`getTime()` is `NaN`), and letting that
16
+ * single `NaN` reach the min/max below would poison `firstWeekStart` (and
17
+ * therefore every cell's `week`) for the whole grid instead of just the bad
18
+ * entry.
11
19
  */
12
20
  export function buildCalendarGrid(days) {
13
- if (days.length === 0) {
21
+ const parsed = days
22
+ .map((d) => ({ ...d, dateObj: parseIsoDate(d.date) }))
23
+ .filter((d) => !Number.isNaN(d.dateObj.getTime()));
24
+ if (parsed.length === 0) {
14
25
  return { cells: [], weekCount: 0, firstWeekStart: new Date(0), monthLabels: [] };
15
26
  }
16
- const parsed = days.map((d) => ({ ...d, dateObj: parseIsoDate(d.date) }));
17
- const minTime = Math.min(...parsed.map((d) => d.dateObj.getTime()));
18
- const min = new Date(minTime);
27
+ const timeBounds = minMax(parsed.map((d) => d.dateObj.getTime()));
28
+ const min = new Date(timeBounds[0]);
19
29
  const firstWeekStart = new Date(Date.UTC(min.getUTCFullYear(), min.getUTCMonth(), min.getUTCDate() - min.getUTCDay()));
20
30
  const cells = parsed.map((d) => {
21
31
  const weekday = d.dateObj.getUTCDay();
@@ -23,7 +33,7 @@ export function buildCalendarGrid(days) {
23
33
  const week = Math.floor(daysSinceStart / 7);
24
34
  return { date: d.date, value: d.value, week, weekday };
25
35
  });
26
- const weekCount = Math.max(...cells.map((c) => c.week)) + 1;
36
+ const weekCount = minMax(cells.map((c) => c.week))[1] + 1;
27
37
  const monthLabels = [];
28
38
  let lastMonth = -1;
29
39
  for (const cell of cells.slice().sort((a, b) => a.week - b.week)) {
@@ -43,10 +53,17 @@ export function buildCalendarGrid(days) {
43
53
  export function quartileBucket(value, sorted, bucketCount) {
44
54
  if (sorted.length === 0)
45
55
  return 0;
46
- let count = 0;
47
- for (const v of sorted)
48
- if (v <= value)
49
- count++;
50
- const rank = count / sorted.length;
56
+ // `sorted` is ascending, so the count of elements <= value is found via an
57
+ // upper-bound binary search (O(log n)) instead of scanning the whole array.
58
+ let lo = 0;
59
+ let hi = sorted.length;
60
+ while (lo < hi) {
61
+ const mid = (lo + hi) >>> 1;
62
+ if (sorted[mid] <= value)
63
+ lo = mid + 1;
64
+ else
65
+ hi = mid;
66
+ }
67
+ const rank = lo / sorted.length;
51
68
  return Math.min(bucketCount - 1, Math.floor(rank * bucketCount));
52
69
  }
@@ -1,6 +1,29 @@
1
- import { type TemplateResult } from 'lit';
1
+ import { type PropertyValues, type TemplateResult } from 'lit';
2
2
  import { LyraElement } from '../../internal/lyra-element.js';
3
3
  import { type CalendarDay } from './calendar-grid.js';
4
+ /** A cell cursor in matrix mode. */
5
+ export interface MatrixCellPos {
6
+ row: number;
7
+ col: number;
8
+ }
9
+ /** A cell cursor in calendar mode — a grid position, not necessarily one with
10
+ * a matching entry in `days` (see `calendarCellAt()`). */
11
+ export interface CalendarCellPos {
12
+ week: number;
13
+ weekday: number;
14
+ }
15
+ /**
16
+ * A marker drawn as a stroked ring over a matching cell (matrix mode:
17
+ * `row`/`col`; calendar mode: `date` — whichever pair matches the active
18
+ * `mode`; the other fields are simply ignored). An optional `label`
19
+ * additionally surfaces the annotation in the legend.
20
+ */
21
+ export interface HeatmapAnnotation {
22
+ row?: number;
23
+ col?: number;
24
+ date?: string;
25
+ label?: string;
26
+ }
4
27
  /**
5
28
  * Parses a strict `#rgb` or `#rrggbb` hex string into an `[r, g, b]` triple,
6
29
  * or `null` if `hex` isn't one (rather than silently coercing an unparsable
@@ -25,16 +48,42 @@ export declare function resolveRgb(color: string, fallbackHex: string): [number,
25
48
  /** Linearly interpolates between two CSS colors (any valid syntax) at `t` in `[0, 1]`. */
26
49
  export declare function mixColor(fromColor: string, toColor: string, t: number): string;
27
50
  /**
28
- * `<lyra-heatmap>` — a Canvas matrix heatmap with a DPR-aware, resize-aware
29
- * redraw loop. `-1` cells are treated as "no data". The sequential color
30
- * ramp's endpoints are read from the `--lyra-heatmap-scale-lo`/`-hi` custom
31
- * properties (declared in `heatmap.styles.ts`) so hosts can retheme it
32
- * canvas can't consume `var()` directly, so they're resolved once per draw
33
- * via `getComputedStyle`, then normalized to RGB by `resolveRgb()` (any
34
- * valid CSS color syntax, not just hex see its doc comment).
51
+ * `<lyra-heatmap>` — a Canvas heatmap with a DPR-aware, resize-aware redraw
52
+ * loop, in one of two `mode`s:
53
+ *
54
+ * - `"matrix"` (default): a `rowLabels` x `colLabels` grid of `values`. `-1`
55
+ * (or any non-finite value) is treated as "no data". `scale="sqrt"`
56
+ * compresses the ramp via `sqrtStep()` so one heavy cell doesn't wash out
57
+ * the rest; the default `"linear"` scale maps linearly instead. `scale`
58
+ * only affects matrix mode — calendar mode always buckets by quartile.
59
+ * - `"calendar"`: a GitHub-style Sunday-Saturday x week grid built from
60
+ * `days`, colored by `quartileBucket()` into `bucketCount` buckets. As in
61
+ * matrix mode, a cell whose `value` is negative or non-finite is treated
62
+ * as "no data" rather than being bucketed.
63
+ *
64
+ * The sequential color ramp's endpoints are read from the
65
+ * `--lyra-heatmap-scale-lo`/`-hi` custom properties (declared in
66
+ * `heatmap.styles.ts`) so hosts can retheme it — canvas can't consume
67
+ * `var()` directly, so they're resolved once per draw via
68
+ * `getComputedStyle`, then normalized to RGB by `resolveRgb()` (any valid
69
+ * CSS color syntax, not just hex — see its doc comment).
70
+ *
71
+ * Every cell is independently addressable: a `pointermove` hit test over the
72
+ * canvas shows `[part="tooltip"]` with that cell's label + value (hidden on
73
+ * `pointerleave`); the canvas is `tabindex="0"` with arrow-key roving focus
74
+ * (a stroked ring redrawn over the focused cell on every draw, plus a
75
+ * visually-hidden `aria-live="polite"` status announcement — avoids a
76
+ * DOM-node-per-cell overlay, which would be hundreds of nodes for a year
77
+ * calendar); and a click, or Enter/Space on the focused cell, fires
78
+ * `lyra-cell-click`. `annotations` additionally strokes a ring around
79
+ * specific cells (e.g. to call out an anomaly), each one optionally
80
+ * surfaced in the legend too via `[part="legend-annotation"]`.
35
81
  *
36
82
  * @customElement lyra-heatmap
37
- * @csspart base, canvas, legend
83
+ * @event lyra-cell-click - Fired on click, or Enter/Space on the
84
+ * focused/hovered cell. `detail: { row, col, value }` in matrix mode,
85
+ * `detail: { date, value }` in calendar mode.
86
+ * @csspart base, canvas, tooltip, live-region, legend, legend-lo, legend-hi, legend-annotation
38
87
  */
39
88
  export declare class LyraHeatmap extends LyraElement {
40
89
  static styles: import("lit").CSSResultGroup[];
@@ -56,26 +105,102 @@ export declare class LyraHeatmap extends LyraElement {
56
105
  mode: 'matrix' | 'calendar';
57
106
  days: CalendarDay[];
58
107
  bucketCount: number;
108
+ /** Cells to ring-highlight — `row`/`col` in matrix mode, `date` in calendar mode. See `HeatmapAnnotation`. */
109
+ annotations: HeatmapAnnotation[];
59
110
  private canvas?;
60
111
  private resizeObserver?;
61
112
  private dprQuery?;
113
+ /** The current value range, refreshed once per update cycle by `willUpdate()`. See `computeValueRange()`. */
114
+ private cachedValueRange;
115
+ /** The cell currently under the pointer (`null` when not hovering one) — drives `[part="tooltip"]`. */
116
+ private hoverCell;
117
+ /** The roving keyboard-focus cell cursor, moved by arrow keys — drives the
118
+ * canvas-drawn focus ring and the `[part="live-region"]` announcement. */
119
+ private focusedCell;
120
+ /** Text of the visually-hidden `aria-live="polite"` status announcement, refreshed on every focus move. */
121
+ private liveText;
62
122
  connectedCallback(): void;
63
123
  disconnectedCallback(): void;
64
124
  private watchDpr;
65
125
  private onDprChange;
66
- protected willUpdate(): void;
67
- /** The real (non-no-data) value range across `values` (or `days` in calendar mode), or `null` if there is none. Shared by `willUpdate()`, `draw()`, and the legend. */
68
- private valueRange;
126
+ protected willUpdate(changed: PropertyValues): void;
127
+ /**
128
+ * The real (non-no-data) value range across `values` (or `days` in
129
+ * calendar mode), or `null` if there is none. Only called from
130
+ * `willUpdate()`, which caches the result in `cachedValueRange` for
131
+ * `render()` and `drawMatrix()` to reuse — `willUpdate()`, `render()`, and
132
+ * `updated()` (which triggers `draw()`) all run within the same Lit update
133
+ * cycle against the same `values`/`days`, so a single scan per cycle
134
+ * suffices instead of one per consumer.
135
+ */
136
+ private computeValueRange;
69
137
  protected updated(): void;
70
138
  /** Reads the customizable ramp endpoints off the host's computed style. */
71
139
  private scaleEndpoints;
72
140
  /** Resolves the `--lyra-color-text-quiet` chrome token for axis labels. */
73
141
  private labelColor;
142
+ /** Reads the customizable canvas axis/label font off the host's computed style. */
143
+ private labelFont;
74
144
  /** Reads the customizable no-data cell fill off the host's computed style. */
75
145
  private noDataFill;
146
+ /** Reads the customizable canvas-drawn keyboard-focus-ring stroke color off the host's computed style. */
147
+ private focusRingColor;
148
+ /** Reads the customizable canvas-drawn annotation-ring stroke color off the host's computed style. */
149
+ private annotationColor;
76
150
  private draw;
77
151
  private drawCalendar;
152
+ /**
153
+ * Effective per-cell size in matrix mode — `fitToWidth` derives it from
154
+ * the host's measured width, otherwise it's the fixed `cellSize`
155
+ * property. Shared by `drawMatrix()` and the pointer/keyboard hit-testing
156
+ * below (`hitTestMatrix()`, `cellRect()`) so they always agree on exactly
157
+ * the same geometry as what's actually painted.
158
+ */
159
+ private matrixCellSize;
78
160
  private drawMatrix;
161
+ /**
162
+ * Maps a pointer position, in canvas-local CSS px (e.g.
163
+ * `PointerEvent.offsetX/offsetY`), to the cell underneath it — or `null`
164
+ * if the pointer is outside the grid. Dispatches on `mode` so callers
165
+ * don't have to.
166
+ */
167
+ private hitTest;
168
+ private hitTestMatrix;
169
+ private hitTestCalendar;
170
+ /**
171
+ * Resolves a (week, weekday) grid position to its real calendar date and
172
+ * value. Computed from grid geometry (`firstWeekStart` + offset), not
173
+ * just looked up in `cells` — so a position with no matching entry in
174
+ * `days` (a gap in a sparse calendar) still resolves to a real ISO date,
175
+ * with a `-1` "no data" sentinel value (the same convention `values`' `-1`
176
+ * sentinel uses in matrix mode), instead of being unresolvable.
177
+ */
178
+ private calendarCellAt;
179
+ /**
180
+ * Pixel rect (canvas-local CSS px) of a cell — shared by `tooltipStyle()`
181
+ * so the tooltip's position always agrees with the same geometry
182
+ * `drawMatrix()`/`drawCalendar()`/`hitTest*()` use.
183
+ */
184
+ private cellRect;
185
+ /**
186
+ * Human-readable "<label>: <value>" text for a cell — shared by the hover
187
+ * tooltip and the keyboard-focus live-region announcement, so both always
188
+ * describe a cell the same way.
189
+ */
190
+ private cellText;
191
+ private matrixCellText;
192
+ private calendarCellText;
193
+ /** Refreshes the visually-hidden live-region text for a newly-focused cell. */
194
+ private announce;
195
+ private emitCellClick;
196
+ /** Inline `style` for `[part="tooltip"]`, centered above the given cell. */
197
+ private tooltipStyle;
198
+ private onPointerMove;
199
+ private onPointerLeave;
200
+ private onCanvasClick;
201
+ private onKeyDown;
202
+ private onMatrixKeyDown;
203
+ private onCalendarKeyDown;
79
204
  render(): TemplateResult;
80
205
  }
81
206
  declare global {