@automattic/charts 4.7.0 → 4.9.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 (92) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/TOKENS.md +6 -3
  3. package/dist/index.cjs +834 -321
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +68 -17
  6. package/dist/index.d.cts +102 -28
  7. package/dist/index.d.ts +102 -28
  8. package/dist/index.js +838 -327
  9. package/dist/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/charts/area-chart/area-chart.tsx +7 -4
  12. package/src/charts/area-chart/test/area-chart.test.tsx +24 -15
  13. package/src/charts/area-chart/test/tooltip-resolution-branches.test.tsx +1 -1
  14. package/src/charts/area-chart/test/tooltip-resolution.test.tsx +2 -2
  15. package/src/charts/area-chart/types.ts +2 -0
  16. package/src/charts/bar-chart/bar-chart.module.scss +7 -0
  17. package/src/charts/bar-chart/bar-chart.tsx +25 -16
  18. package/src/charts/bar-chart/private/comparison-bars.tsx +1 -0
  19. package/src/charts/bar-chart/test/bar-chart.test.tsx +106 -62
  20. package/src/charts/bar-chart/types.ts +2 -0
  21. package/src/charts/bar-list-chart/test/bar-list-chart.test.tsx +3 -1
  22. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +1 -1
  23. package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +9 -0
  24. package/src/charts/heatmap-chart/heatmap-chart.module.scss +16 -8
  25. package/src/charts/heatmap-chart/heatmap-chart.tsx +183 -66
  26. package/src/charts/heatmap-chart/private/column-groups.ts +79 -8
  27. package/src/charts/heatmap-chart/private/fit-compact-cells.ts +72 -0
  28. package/src/charts/heatmap-chart/private/heatmap-context.ts +2 -2
  29. package/src/charts/heatmap-chart/private/heatmap-legend.tsx +15 -3
  30. package/src/charts/heatmap-chart/private/heatmap-scale.ts +74 -0
  31. package/src/charts/heatmap-chart/private/index.ts +6 -3
  32. package/src/charts/heatmap-chart/private/use-heatmap-colors.ts +24 -6
  33. package/src/charts/heatmap-chart/test/column-groups.test.ts +41 -4
  34. package/src/charts/heatmap-chart/test/fit-compact-cells.test.ts +59 -0
  35. package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +231 -8
  36. package/src/charts/heatmap-chart/test/heatmap-scale.test.ts +78 -0
  37. package/src/charts/heatmap-chart/test/use-heatmap-colors.test.ts +18 -6
  38. package/src/charts/heatmap-chart/types.ts +6 -3
  39. package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +46 -4
  40. package/src/charts/leaderboard-chart/leaderboard-chart.tsx +37 -1
  41. package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +53 -0
  42. package/src/charts/leaderboard-chart/types.ts +6 -1
  43. package/src/charts/line-chart/line-chart.tsx +7 -4
  44. package/src/charts/line-chart/private/line-chart-annotation-label-popover.tsx +19 -9
  45. package/src/charts/line-chart/test/default-tooltip-formatting.test.tsx +1 -1
  46. package/src/charts/line-chart/test/line-chart.test.tsx +45 -35
  47. package/src/charts/line-chart/test/tooltip-resolution.test.tsx +2 -2
  48. package/src/charts/line-chart/types.ts +5 -3
  49. package/src/charts/pie-chart/pie-chart.tsx +153 -143
  50. package/src/charts/pie-chart/test/pie-chart.test.tsx +171 -0
  51. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +126 -124
  52. package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +55 -1
  53. package/src/charts/private/chart-composition/use-chart-children.ts +11 -6
  54. package/src/charts/private/pie-keyboard-navigation/index.ts +4 -0
  55. package/src/charts/private/pie-keyboard-navigation/order-arcs-for-navigation.ts +10 -0
  56. package/src/charts/private/pie-keyboard-navigation/pie-keyboard-navigation.module.scss +16 -0
  57. package/src/charts/private/pie-keyboard-navigation/pie-selection-announcement.tsx +14 -0
  58. package/src/charts/private/pie-keyboard-navigation/pie-selection-output.tsx +82 -0
  59. package/src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx +44 -0
  60. package/src/charts/private/pie-keyboard-navigation/selected-segment-ring.tsx +47 -0
  61. package/src/charts/private/pie-keyboard-navigation/test/order-arcs-for-navigation.test.ts +34 -0
  62. package/src/charts/private/pie-keyboard-navigation/test/selected-segment-ring.test.ts +14 -0
  63. package/src/charts/private/pie-keyboard-navigation/use-pie-keyboard-navigation.ts +139 -0
  64. package/src/charts/private/test/label-text-color.test.ts +6 -8
  65. package/src/charts/private/x-zoom/test/x-zoom.test.tsx +3 -2
  66. package/src/components/tooltip/base-tooltip.tsx +31 -32
  67. package/src/components/tooltip/index.ts +3 -1
  68. package/src/components/tooltip/private/bounded-tooltip.tsx +15 -15
  69. package/src/components/tooltip/private/label-value-content.tsx +8 -0
  70. package/src/components/tooltip/private/xy-chart-tooltip-overlay.tsx +336 -0
  71. package/src/components/tooltip/test/tool-tip.test.tsx +8 -6
  72. package/src/components/tooltip/test/tooltip-box.test.tsx +53 -0
  73. package/src/components/tooltip/test/xy-chart-tooltip-overlay.test.tsx +445 -0
  74. package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +283 -365
  75. package/src/components/tooltip/{base-tooltip.module.scss → tooltip-box.module.scss} +5 -8
  76. package/src/components/tooltip/tooltip-box.tsx +43 -0
  77. package/src/components/tooltip/types.ts +7 -1
  78. package/src/components/tooltip/xy-chart-tooltip.tsx +410 -300
  79. package/src/hooks/test/use-chart-margin.test.tsx +8 -4
  80. package/src/hooks/use-chart-margin.tsx +21 -18
  81. package/src/index.ts +8 -3
  82. package/src/providers/chart-context/global-charts-provider.tsx +5 -14
  83. package/src/providers/chart-context/hooks/use-default-hidden-series.ts +1 -1
  84. package/src/providers/chart-context/private/catalog-pointers.ts +1 -0
  85. package/src/providers/chart-context/private/resolve-opaque-hex.ts +16 -0
  86. package/src/providers/chart-context/test/use-default-hidden-series.test.tsx +1 -1
  87. package/src/styles/chart-scope.scss +1 -0
  88. package/src/test-utils/zoned-parsing-suite.ts +0 -10
  89. package/src/types.ts +18 -2
  90. package/src/utils/test/date-formatting.test.ts +0 -10
  91. package/src/components/tooltip/accessible-tooltip.tsx +0 -433
  92. package/src/components/tooltip/test/accessible-tooltip.test.tsx +0 -331
package/dist/index.js CHANGED
@@ -4,20 +4,20 @@ import { AnimatedAreaSeries, AnimatedAreaStack, AreaSeries, Axis, BarGroup, BarS
4
4
  import { __, _x, sprintf } from "@wordpress/i18n";
5
5
  import clsx from "clsx";
6
6
  import * as React from "react";
7
- import { Children, Fragment, createContext, createContext as createContext$1, createElement, forwardRef, forwardRef as forwardRef$1, isValidElement, memo, useCallback, useCallback as useCallback$1, useContext, useContext as useContext$1, useEffect, useEffect as useEffect$1, useId, useImperativeHandle, useLayoutEffect, useMemo, useMemo as useMemo$1, useRef, useRef as useRef$1, useState, useState as useState$1 } from "react";
8
- import { color, hsl } from "@visx/vendor/d3-color";
7
+ import { Children, Fragment, createContext, createContext as createContext$1, createElement, forwardRef, forwardRef as forwardRef$1, isValidElement, memo, useCallback, useCallback as useCallback$1, useContext, useContext as useContext$1, useEffect, useEffect as useEffect$1, useId, useImperativeHandle, useLayoutEffect, useMemo, useMemo as useMemo$1, useRef, useRef as useRef$1, useState, useState as useState$1, version } from "react";
9
8
  import { differenceInHours, differenceInYears, isValid, parse, parseISO } from "date-fns";
10
9
  import { tzOffset } from "@date-fns/tz";
11
10
  import { Text, getStringWidth } from "@visx/text";
12
11
  import deepmerge from "deepmerge";
12
+ import { color, hsl } from "@visx/vendor/d3-color";
13
13
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
- import { Tooltip, useTooltip } from "@visx/tooltip";
14
+ import { useTooltip } from "@visx/tooltip";
15
15
  import { createScale, getTicks, scaleBand, scaleCanBeZeroed, scaleOrdinal, scaleTime } from "@visx/scale";
16
16
  import { Group } from "@visx/group";
17
17
  import { LegendItem, LegendLabel, LegendOrdinal, LegendShape } from "@visx/legend";
18
- import { IconButton, Stack, Text as Text$1 } from "@wordpress/ui";
18
+ import { IconButton, Stack, Text as Text$1, VisuallyHidden } from "@wordpress/ui";
19
19
  import { ThemeProvider } from "@wordpress/theme";
20
- import { createPortal } from "react-dom";
20
+ import { createPortal, flushSync } from "react-dom";
21
21
  import { LinearGradient } from "@visx/gradient";
22
22
  import { curveCatmullRom, curveLinear, curveMonotoneX } from "@visx/curve";
23
23
  import { useParentSize } from "@visx/responsive";
@@ -30,7 +30,7 @@ import { __assign } from "tslib";
30
30
  import "@babel/runtime/helpers/esm/extends";
31
31
  import "@babel/runtime/helpers/extends";
32
32
  import { Icon, chevronRight } from "@wordpress/icons";
33
- import { Pie } from "@visx/shape";
33
+ import { arc, pie } from "@visx/shape";
34
34
  //#region \0rolldown/runtime.js
35
35
  var __create = Object.create;
36
36
  var __defProp = Object.defineProperty;
@@ -834,6 +834,7 @@ const CATALOG_POINTERS = {
834
834
  annotation: "var(--a8c-charts-color-annotation, #1e1e1e)",
835
835
  surface: "var(--a8c-charts-color-surface, #fff)",
836
836
  surfaceSecondary: "var(--a8c-charts-color-surface-secondary, #f4f4f4)",
837
+ track: "var(--a8c-charts-color-track, #f0f0f0)",
837
838
  trendUp: "var(--a8c-charts-color-trend-up, #008030)",
838
839
  trendDown: "var(--a8c-charts-color-trend-down, #cc1818)",
839
840
  series: SERIES_PALETTE_POINTERS
@@ -1063,6 +1064,15 @@ const rgbLuminance = (rgb) => {
1063
1064
  * @return Ratio from 1 to 21.
1064
1065
  */
1065
1066
  const luminanceContrastRatio = (first, second) => (Math.max(first, second) + .05) / (Math.min(first, second) + .05);
1067
+ /**
1068
+ * WCAG contrast ratio between two hex colors.
1069
+ *
1070
+ * @param first - First hex color.
1071
+ * @param second - Second hex color.
1072
+ * @return Ratio from 1 to 21.
1073
+ * @throws {Error} if either hex string is malformed
1074
+ */
1075
+ const contrastRatio = (first, second) => luminanceContrastRatio(relativeLuminance(first), relativeLuminance(second));
1066
1076
  /** WCAG 1.4.3 text contrast, which a label drawn on a fill needs from at least one label color. */
1067
1077
  const MIN_LABEL_CONTRAST = 4.5;
1068
1078
  /** Degrees of hue one unit of OKLCH chroma is worth when ranking candidates by hue. */
@@ -1253,6 +1263,14 @@ const buildPaletteGenerator = (normalizedSeeds, background, labelColors) => {
1253
1263
  };
1254
1264
  };
1255
1265
  //#endregion
1266
+ //#region src/providers/chart-context/private/resolve-opaque-hex.ts
1267
+ const resolveOpaqueHex = (pointer, resolve) => {
1268
+ const raw = resolve(pointer);
1269
+ if (!raw || color(raw)?.opacity !== 1) return null;
1270
+ const hex = normalizeColorToHex(raw);
1271
+ return isValidHexColor(hex) ? hex : null;
1272
+ };
1273
+ //#endregion
1256
1274
  //#region src/providers/chart-context/themes.ts
1257
1275
  /**
1258
1276
  * Default theme configuration: the shape and spacing a consumer can override.
@@ -1301,12 +1319,6 @@ const defaultTheme = {
1301
1319
  };
1302
1320
  //#endregion
1303
1321
  //#region src/providers/chart-context/global-charts-provider.tsx
1304
- const resolveOpaqueHex = (pointer, element) => {
1305
- const raw = resolveCssVariable(pointer, element);
1306
- if (!raw || color(raw)?.opacity !== 1) return null;
1307
- const hex = normalizeColorToHex(pointer, element, resolveCssVariable);
1308
- return isValidHexColor(hex) ? hex : null;
1309
- };
1310
1322
  const PLACEHOLDER_LABEL_COLORS = [LABEL_FALLBACK, LABEL_INVERSE_FALLBACK];
1311
1323
  const GlobalChartsContext = createContext(null);
1312
1324
  const GlobalChartsProvider = ({ children, theme, locale, timeZone }) => {
@@ -1334,8 +1346,9 @@ const GlobalChartsProvider = ({ children, theme, locale, timeZone }) => {
1334
1346
  const normalizedColor = normalizeColorToHex(color, wrapperRef.current, resolveCssVariable);
1335
1347
  if (isValidHexColor(normalizedColor)) resolvedColors.push(normalizedColor);
1336
1348
  }
1337
- const backgroundHex = resolveOpaqueHex(CATALOG_POINTERS.background, wrapperRef.current) ?? "#ffffff";
1338
- const labelColors = [CATALOG_POINTERS.label, CATALOG_POINTERS.labelInverse].map((pointer) => resolveOpaqueHex(pointer, wrapperRef.current)).filter((hex) => hex !== null);
1349
+ const resolveAtWrapper = createCssVariableResolver(wrapperRef.current);
1350
+ const backgroundHex = resolveOpaqueHex(CATALOG_POINTERS.background, resolveAtWrapper) ?? "#ffffff";
1351
+ const labelColors = [CATALOG_POINTERS.label, CATALOG_POINTERS.labelInverse].map((pointer) => resolveOpaqueHex(pointer, resolveAtWrapper)).filter((hex) => hex !== null);
1339
1352
  setColorCache({
1340
1353
  colors: resolvedColors,
1341
1354
  background: backgroundHex,
@@ -1671,10 +1684,10 @@ const DEFAULT_MARGIN_BOTTOM = 20;
1671
1684
  */
1672
1685
  const DEFAULT_MARGIN_LEFT = 20;
1673
1686
  /**
1674
- * Bottom margin to use when the X-axis is rendered at the top.
1687
+ * Bottom margin when no X-axis sits below the chart, because it is on top or hidden.
1675
1688
  * We only need a small buffer below the chart in that case.
1676
1689
  */
1677
- const DEFAULT_BOTTOM_FOR_TOP_AXIS = 10;
1690
+ const DEFAULT_BOTTOM_WITHOUT_X_AXIS = 10;
1678
1691
  /**
1679
1692
  * Fallback font size used when we cannot derive a font size
1680
1693
  * from the theme or axis styles for X-axis tick labels.
@@ -1754,18 +1767,18 @@ const useChartMargin = (height, options, data, theme, horizontal = false) => {
1754
1767
  if (yAxisOrientation === "right") defaultMargin.right = yMarginValue;
1755
1768
  else defaultMargin.left = yMarginValue;
1756
1769
  }
1757
- const xOrientation = options.axis?.x?.orientation === "top" ? "top" : "bottom";
1758
- const { fontSize, tickLength, tickLabelStyle } = getXAxisLabelMetrics(theme, xOrientation);
1759
- const computedXMargin = fontSize + tickLength;
1760
- if (xOrientation === "top") {
1761
- defaultMargin.top = Math.max(defaultMargin.top, computedXMargin);
1762
- defaultMargin.bottom = DEFAULT_BOTTOM_FOR_TOP_AXIS;
1763
- } else defaultMargin.bottom = Math.max(defaultMargin.bottom, computedXMargin);
1764
1770
  if (options.axis?.x?.display !== false) {
1771
+ const xOrientation = options.axis?.x?.orientation === "top" ? "top" : "bottom";
1772
+ const { fontSize, tickLength, tickLabelStyle } = getXAxisLabelMetrics(theme, xOrientation);
1773
+ const computedXMargin = fontSize + tickLength;
1774
+ if (xOrientation === "top") {
1775
+ defaultMargin.top = Math.max(defaultMargin.top, computedXMargin);
1776
+ defaultMargin.bottom = DEFAULT_BOTTOM_WITHOUT_X_AXIS;
1777
+ } else defaultMargin.bottom = Math.max(defaultMargin.bottom, computedXMargin);
1765
1778
  const { first, last } = getEdgeTickWidths(options.axis?.x?.tickValues ?? [], options.axis?.x?.tickFormat, tickLabelStyle);
1766
1779
  defaultMargin.left = Math.max(defaultMargin.left, Math.ceil(first / 2));
1767
1780
  defaultMargin.right = Math.max(defaultMargin.right, Math.ceil(last / 2));
1768
- }
1781
+ } else defaultMargin.bottom = DEFAULT_BOTTOM_WITHOUT_X_AXIS;
1769
1782
  return defaultMargin;
1770
1783
  }, [
1771
1784
  options,
@@ -2477,11 +2490,12 @@ function useChartLegendItems(data, options = {}, legendShape) {
2477
2490
  ]);
2478
2491
  }
2479
2492
  //#endregion
2480
- //#region src/components/tooltip/base-tooltip.module.scss
2481
- var base_tooltip_module_default = {
2482
- "surface": "a8ccharts--zY0xG-surface",
2483
- "tooltip": "a8ccharts--zY0xG-tooltip"
2484
- };
2493
+ //#region src/components/tooltip/private/label-value-content.tsx
2494
+ const LabelValueContent = ({ data }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
2495
+ data.label,
2496
+ ": ",
2497
+ data.valueDisplay || formatNumber(data.value)
2498
+ ] });
2485
2499
  //#endregion
2486
2500
  //#region src/components/tooltip/private/tooltip-theme.tsx
2487
2501
  const DEFAULT_SURFACE = "#1e1e1e";
@@ -2507,28 +2521,63 @@ const TooltipTheme = ({ children }) => {
2507
2521
  });
2508
2522
  };
2509
2523
  //#endregion
2524
+ //#region src/components/tooltip/tooltip-box.module.scss
2525
+ var tooltip_box_module_default = { "surface": "a8ccharts-ddpU1W-surface" };
2526
+ //#endregion
2527
+ //#region src/components/tooltip/tooltip-box.tsx
2528
+ /**
2529
+ * The chart tooltip box: the dark surface every chart tooltip draws. It does not position itself; place it with `style` or a wrapper.
2530
+ *
2531
+ * @param props - Div attributes, plus `unstyled`.
2532
+ * @param props.unstyled - Drop the surface, scope class and theme.
2533
+ * @param ref - Forwarded to the box element.
2534
+ * @return The tooltip box.
2535
+ */
2536
+ const TooltipBox = forwardRef(({ unstyled = false, role = "tooltip", className, children, ...rest }, ref) => {
2537
+ const box = /* @__PURE__ */ jsx("div", {
2538
+ ref,
2539
+ role,
2540
+ className: clsx("visx-tooltip", !unstyled && ["a8c-charts-tooltip-scope", tooltip_box_module_default.surface], className),
2541
+ ...rest,
2542
+ children
2543
+ });
2544
+ return unstyled ? box : /* @__PURE__ */ jsx(TooltipTheme, { children: box });
2545
+ });
2546
+ TooltipBox.displayName = "TooltipBox";
2547
+ //#endregion
2510
2548
  //#region src/components/tooltip/base-tooltip.tsx
2511
- const DefaultTooltipContent = ({ data }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
2512
- data?.label,
2513
- ": ",
2514
- data?.valueDisplay || formatNumber(data?.value)
2515
- ] });
2516
- const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipContent, children, className, style, renderContainer = true }) => {
2549
+ /**
2550
+ * A tooltip box with children or `label: value` content. Prefer `TooltipBox`.
2551
+ *
2552
+ * @param props - Tooltip props.
2553
+ * @param props.data - Data for the default content.
2554
+ * @param props.top - Deprecated vertical position.
2555
+ * @param props.left - Deprecated horizontal position.
2556
+ * @param props.component - Deprecated content component.
2557
+ * @param props.children - Tooltip content.
2558
+ * @param props.className - Class name passed to the content component.
2559
+ * @param props.style - Styles for the box.
2560
+ * @param props.renderContainer - Deprecated; render the content alone when false.
2561
+ * @return The tooltip.
2562
+ */
2563
+ const BaseTooltip = ({ data, top, left, component: Component = LabelValueContent, children, className, style, renderContainer = true }) => {
2517
2564
  const content = children || data && /* @__PURE__ */ jsx(Component, {
2518
2565
  data,
2519
2566
  className
2520
2567
  });
2521
2568
  if (!renderContainer) return content;
2522
- return /* @__PURE__ */ jsx(TooltipTheme, { children: /* @__PURE__ */ jsx("div", {
2523
- className: clsx(CHART_SCOPE_CLASS, base_tooltip_module_default.tooltip),
2569
+ return /* @__PURE__ */ jsx(TooltipBox, {
2524
2570
  style: {
2525
- top,
2526
- left,
2571
+ ...top === void 0 && left === void 0 ? void 0 : {
2572
+ position: "absolute",
2573
+ top,
2574
+ left,
2575
+ transform: "translate(-50%, -100%)"
2576
+ },
2527
2577
  ...style
2528
2578
  },
2529
- role: "tooltip",
2530
2579
  children: content
2531
- }) });
2580
+ });
2532
2581
  };
2533
2582
  //#endregion
2534
2583
  //#region src/components/tooltip/private/bounded-tooltip.tsx
@@ -2608,7 +2657,7 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
2608
2657
  };
2609
2658
  };
2610
2659
  /**
2611
- * visx's `Tooltip`, positioned like its `TooltipWithBounds` but kept inside the
2660
+ * A `TooltipBox`, positioned like visx's `TooltipWithBounds` but kept inside the
2612
2661
  * nearest clipping ancestor — or the viewport when there is none — rather than
2613
2662
  * inside its own parent. Rendered in-tree, a tooltip's parent is the chart
2614
2663
  * wrapper, which is often narrower than the box; measuring against the parent
@@ -2617,7 +2666,7 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
2617
2666
  * Re-measures on every render, so a box whose content changes width between
2618
2667
  * two hovers is placed for its current size.
2619
2668
  *
2620
- * @param props - visx `Tooltip` props.
2669
+ * @param props - `TooltipBox` props plus placement.
2621
2670
  * @param props.left - Anchor x, in wrapper coordinates.
2622
2671
  * @param props.top - Anchor y, in wrapper coordinates.
2623
2672
  * @param props.offsetLeft - Gap between the anchor and the box, horizontally.
@@ -2683,9 +2732,11 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offset
2683
2732
  ]);
2684
2733
  const x = position?.x ?? left + offsetLeft;
2685
2734
  const y = position?.y ?? top + (placement === "below-axis" ? POINTER_HEIGHT : offsetTop);
2686
- const box = /* @__PURE__ */ jsxs(Tooltip, {
2735
+ return /* @__PURE__ */ jsxs(TooltipBox, {
2687
2736
  ref: nodeRef,
2688
- className: clsx(!unstyled && ["a8c-charts-tooltip-scope", base_tooltip_module_default.surface], className),
2737
+ role: "presentation",
2738
+ unstyled,
2739
+ className,
2689
2740
  style: {
2690
2741
  position: "absolute",
2691
2742
  left: 0,
@@ -2708,10 +2759,9 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offset
2708
2759
  }
2709
2760
  }), children]
2710
2761
  });
2711
- return unstyled ? box : /* @__PURE__ */ jsx(TooltipTheme, { children: box });
2712
2762
  };
2713
2763
  //#endregion
2714
- //#region src/components/tooltip/xy-chart-tooltip.tsx
2764
+ //#region src/components/tooltip/private/xy-chart-tooltip-overlay.tsx
2715
2765
  const CROSSHAIR_STROKE_WIDTH = 1.5;
2716
2766
  const CROSSHAIR_PAINT_PROPERTIES = /* @__PURE__ */ new Set([
2717
2767
  "stroke",
@@ -2813,21 +2863,35 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
2813
2863
  const crosshairStroke = theme?.gridStyles?.stroke ?? theme?.htmlLabel?.color ?? FALLBACK_COLOR;
2814
2864
  const marginTop = margin?.top ?? 0;
2815
2865
  const marginLeft = margin?.left ?? 0;
2816
- const TooltipComponent = detectBounds || tooltipPlacement !== "auto" ? BoundedTooltip : Tooltip;
2817
2866
  const boxStyle = {
2818
2867
  zIndex,
2819
2868
  ...style
2820
2869
  };
2821
- const themesOwnBox = TooltipComponent === Tooltip && !tooltipProps.unstyled;
2822
- const box = /* @__PURE__ */ jsx(TooltipComponent, {
2870
+ const { offsetLeft = 10, offsetTop = 10, unstyled, className, ...boxProps } = tooltipProps;
2871
+ const anchorTop = tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop;
2872
+ const box = detectBounds || tooltipPlacement !== "auto" ? /* @__PURE__ */ jsx(BoundedTooltip, {
2823
2873
  left: tooltipLeft,
2824
- top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop,
2874
+ top: anchorTop,
2875
+ offsetLeft,
2876
+ offsetTop,
2877
+ unstyled,
2878
+ className,
2825
2879
  style: boxStyle,
2826
- applyPositionStyle: true,
2827
- ...tooltipProps,
2828
- className: clsx(themesOwnBox && ["a8c-charts-scope", base_tooltip_module_default.surface], tooltipProps.className),
2880
+ ...boxProps,
2829
2881
  ...tooltipPlacement !== "auto" && { placement: tooltipPlacement },
2830
2882
  children: tooltipContent
2883
+ }) : /* @__PURE__ */ jsx(TooltipBox, {
2884
+ role: "presentation",
2885
+ unstyled,
2886
+ className,
2887
+ style: {
2888
+ position: "absolute",
2889
+ left: (tooltipLeft ?? 0) + offsetLeft,
2890
+ top: (anchorTop ?? 0) + offsetTop,
2891
+ ...!unstyled && boxStyle
2892
+ },
2893
+ ...boxProps,
2894
+ children: tooltipContent
2831
2895
  });
2832
2896
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("g", {
2833
2897
  className: "visx-tooltip-overlay",
@@ -2855,7 +2919,7 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
2855
2919
  }),
2856
2920
  glyphs
2857
2921
  ]
2858
- }), container && createPortal(themesOwnBox ? /* @__PURE__ */ jsx(TooltipTheme, { children: box }) : box, container)] });
2922
+ }), container && createPortal(box, container)] });
2859
2923
  };
2860
2924
  /**
2861
2925
  * In-tree replacement for `@visx/xychart`'s `Tooltip`.
@@ -2880,7 +2944,7 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
2880
2944
  * @param props - visx's `Tooltip` options. `scroll`, `debounce` and `resizeObserverPolyfill` are accepted and ignored.
2881
2945
  * @return An anchor in the SVG, plus the overlay and the tooltip box while the tooltip is open.
2882
2946
  */
2883
- const XyChartTooltip = (props) => {
2947
+ const XyChartTooltipOverlay = (props) => {
2884
2948
  const tooltipContext = useContext(TooltipContext);
2885
2949
  const [container, setContainer] = useState(null);
2886
2950
  const anchorRef = useCallback((node) => {
@@ -2893,8 +2957,8 @@ const XyChartTooltip = (props) => {
2893
2957
  })] });
2894
2958
  };
2895
2959
  //#endregion
2896
- //#region src/components/tooltip/accessible-tooltip.tsx
2897
- const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", verticalCrosshairStyle, horizontalCrosshairStyle, ...props }) => {
2960
+ //#region src/components/tooltip/xy-chart-tooltip.tsx
2961
+ const XYChartTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", verticalCrosshairStyle, horizontalCrosshairStyle, ...props }) => {
2898
2962
  const tooltipContext = useContext(TooltipContext);
2899
2963
  const scopeElement = useChartScopeElement();
2900
2964
  const crosshairStroke = useMemo(() => {
@@ -3000,7 +3064,7 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
3000
3064
  keyboardFocusedClassName,
3001
3065
  standaloneScopeClass
3002
3066
  ]);
3003
- return /* @__PURE__ */ jsx(XyChartTooltip, {
3067
+ return /* @__PURE__ */ jsx(XyChartTooltipOverlay, {
3004
3068
  ...props,
3005
3069
  verticalCrosshairStyle: {
3006
3070
  ...crosshairStroke,
@@ -3013,8 +3077,10 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
3013
3077
  renderTooltip: focusableRenderTooltip
3014
3078
  });
3015
3079
  };
3080
+ /** @deprecated Use `XYChartTooltip`. */
3081
+ const AccessibleTooltip = XYChartTooltip;
3016
3082
  const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints, onActivate, preventTooltipScroll = false, visibleSeriesKey }) => {
3017
- const getChartRoot = useCallback(() => chartRef.current?.closest("[role=\"grid\"]") ?? chartRef.current, [chartRef]);
3083
+ const getChartRoot = useCallback(() => chartRef.current?.closest("[role=\"application\"]") ?? chartRef.current, [chartRef]);
3018
3084
  const focusWithoutScrollIfNeeded = useCallback((element) => {
3019
3085
  if (preventTooltipScroll) element?.focus({ preventScroll: true });
3020
3086
  else element?.focus();
@@ -3229,11 +3295,13 @@ function useChartChildren(children, chartType) {
3229
3295
  }
3230
3296
  const displayName = child.type?.displayName;
3231
3297
  if (displayName === `${chartType}.SVG` || displayName === "Chart.SVG") {
3232
- if (child.props?.children) Children.forEach(child.props.children, (svgChild) => {
3298
+ const { children: svgChildren } = child.props ?? {};
3299
+ if (svgChildren) Children.forEach(svgChildren, (svgChild) => {
3233
3300
  svg.push(svgChild);
3234
3301
  });
3235
3302
  } else if (displayName === `${chartType}.HTML` || displayName === "Chart.HTML") {
3236
- if (child.props?.children) Children.forEach(child.props.children, (htmlChild) => {
3303
+ const { children: htmlChildren } = child.props ?? {};
3304
+ if (htmlChildren) Children.forEach(htmlChildren, (htmlChild) => {
3237
3305
  html.push(htmlChild);
3238
3306
  });
3239
3307
  } else if (child.type === Group) svg.push(child);
@@ -4055,6 +4123,7 @@ var line_chart_module_default = {
4055
4123
  "line-chart--animated": "a8ccharts-inuQka-line-chart--animated",
4056
4124
  "rise": "a8ccharts-inuQka-rise"
4057
4125
  };
4126
+ const isReact18 = version.startsWith("18.");
4058
4127
  const CloseIcon = () => /* @__PURE__ */ jsx("svg", {
4059
4128
  width: "16",
4060
4129
  height: "16",
@@ -4097,7 +4166,7 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
4097
4166
  className: line_chart_module_default["line-chart__annotation-label"],
4098
4167
  children: [/* @__PURE__ */ jsx("button", {
4099
4168
  ref: buttonRef,
4100
- popovertarget: popoverId,
4169
+ ...isReact18 ? { popovertarget: popoverId } : { popoverTarget: popoverId },
4101
4170
  className: line_chart_module_default["line-chart__annotation-label-trigger-button"],
4102
4171
  style: {
4103
4172
  width: `44px`,
@@ -4125,8 +4194,13 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
4125
4194
  subtitle
4126
4195
  })
4127
4196
  }), /* @__PURE__ */ jsx("button", {
4128
- popovertarget: popoverId,
4129
- popovertargetaction: "hide",
4197
+ ...isReact18 ? {
4198
+ popovertarget: popoverId,
4199
+ popovertargetaction: "hide"
4200
+ } : {
4201
+ popoverTarget: popoverId,
4202
+ popoverTargetAction: "hide"
4203
+ },
4130
4204
  className: line_chart_module_default["line-chart__annotation-label-popover-close-button"],
4131
4205
  "aria-label": __("Close", "jetpack-charts"),
4132
4206
  children: /* @__PURE__ */ jsx(CloseIcon, {})
@@ -4648,7 +4722,7 @@ const LineChartScalesRef = ({ chartRef, width, height, margin }) => {
4648
4722
  ]);
4649
4723
  return null;
4650
4724
  };
4651
- const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, tooltipPlacement, tooltipStyle, withStartGlyphs = false, withEndGlyphs = false, animation, options = {}, onPointerDown = void 0, onPointerUp = void 0, onPointerMove = void 0, onPointerOut = void 0, onDatumActivate = void 0, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
4725
+ const LineChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, tooltipPlacement, tooltipStyle, withStartGlyphs = false, withEndGlyphs = false, animation, options = {}, onPointerDown = void 0, onPointerUp = void 0, onPointerMove = void 0, onPointerOut = void 0, onDatumActivate = void 0, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
4652
4726
  const legendInteractive = legend.interactive ?? false;
4653
4727
  const legendCollapseGroups = legend.collapseGroups ?? false;
4654
4728
  const legendComparisonItem = legend.comparisonItem ?? false;
@@ -4916,8 +4990,8 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4916
4990
  const chartHeight = contentHeight > 0 ? contentHeight : height;
4917
4991
  return /* @__PURE__ */ jsx("div", {
4918
4992
  ref: chartRef,
4919
- role: "grid",
4920
- "aria-label": __("Line chart", "jetpack-charts"),
4993
+ role: "application",
4994
+ "aria-label": ariaLabel ?? __("Line chart", "jetpack-charts"),
4921
4995
  tabIndex: 0,
4922
4996
  onKeyDown: onChartKeyDown,
4923
4997
  onFocus: onChartFocus,
@@ -4925,6 +4999,7 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4925
4999
  children: chartHeight > 0 && /* @__PURE__ */ jsxs("div", {
4926
5000
  className: xy_plot_module_default["xy-plot"],
4927
5001
  children: [zoomable && zoom.domain && /* @__PURE__ */ jsx(ZoomResetButton, { onClick: zoom.reset }), /* @__PURE__ */ jsxs(XYChart, {
5002
+ accessibilityLabel: "",
4928
5003
  theme,
4929
5004
  width,
4930
5005
  height: chartHeight,
@@ -5018,7 +5093,7 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
5018
5093
  ] }, seriesData?.label || index);
5019
5094
  })
5020
5095
  }),
5021
- withTooltips && /* @__PURE__ */ jsx(AccessibleTooltip, {
5096
+ withTooltips && /* @__PURE__ */ jsx(XYChartTooltip, {
5022
5097
  detectBounds: true,
5023
5098
  snapTooltipToDatumX: true,
5024
5099
  tooltipPlacement,
@@ -5165,7 +5240,7 @@ const HoverGlyphs = ({ visibleSeries, stacked, stackOffset, getElementStyles, st
5165
5240
  };
5166
5241
  //#endregion
5167
5242
  //#region src/charts/area-chart/area-chart.tsx
5168
- const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, stacked = true, stackOffset = "none", smoothing = true, curveType, fillOpacity, withStroke, renderTooltip = renderDefaultTooltip, animation, options = {}, onPointerDown, onPointerUp, onPointerMove, onPointerOut, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
5243
+ const AreaChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, stacked = true, stackOffset = "none", smoothing = true, curveType, fillOpacity, withStroke, renderTooltip = renderDefaultTooltip, animation, options = {}, onPointerDown, onPointerUp, onPointerMove, onPointerOut, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
5169
5244
  const legendInteractive = legend.interactive ?? false;
5170
5245
  const legendShape = legend.shape ?? "rect";
5171
5246
  const legendPosition = legend.position ?? "bottom";
@@ -5436,8 +5511,8 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
5436
5511
  const chartHeight = contentHeight > 0 ? contentHeight : height;
5437
5512
  return /* @__PURE__ */ jsx("div", {
5438
5513
  ref: chartRef,
5439
- role: "grid",
5440
- "aria-label": __("Area chart", "jetpack-charts"),
5514
+ role: "application",
5515
+ "aria-label": ariaLabel ?? __("Area chart", "jetpack-charts"),
5441
5516
  tabIndex: 0,
5442
5517
  onKeyDown: onChartKeyDown,
5443
5518
  onFocus: onChartFocus,
@@ -5445,6 +5520,7 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
5445
5520
  children: chartHeight > 0 && /* @__PURE__ */ jsxs("div", {
5446
5521
  className: xy_plot_module_default["xy-plot"],
5447
5522
  children: [zoomable && zoom.domain && /* @__PURE__ */ jsx(ZoomResetButton, { onClick: zoom.reset }), /* @__PURE__ */ jsxs(XYChart, {
5523
+ accessibilityLabel: "",
5448
5524
  theme,
5449
5525
  width,
5450
5526
  height: chartHeight,
@@ -5494,7 +5570,7 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
5494
5570
  children: seriesWithVisibility.map(renderSeries)
5495
5571
  }), !allSeriesHidden && !stacked && seriesWithVisibility.map(renderSeries)]
5496
5572
  }),
5497
- withTooltips && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AccessibleTooltip, {
5573
+ withTooltips && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(XYChartTooltip, {
5498
5574
  detectBounds: true,
5499
5575
  snapTooltipToDatumX: true,
5500
5576
  snapTooltipToDatumY: !stacked,
@@ -6105,6 +6181,7 @@ const ComparisonBars = ({ comparisonEntries, primaryKeys, groupPadding, horizont
6105
6181
  widthFactor
6106
6182
  });
6107
6183
  rects.push(/* @__PURE__ */ jsx("rect", {
6184
+ className: "bar-chart__comparison-bar",
6108
6185
  x: rect.x,
6109
6186
  y: rect.y,
6110
6187
  width: rect.width,
@@ -6296,7 +6373,7 @@ const renderTooltipRow = (label, value) => /* @__PURE__ */ jsx("div", {
6296
6373
  className: bar_chart_module_default["bar-chart__tooltip-row"],
6297
6374
  children: sprintf(__("%1$s: %2$s", "jetpack-charts"), label, value)
6298
6375
  });
6299
- const BarChartInternal = ({ data, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, tooltipPlacement, tooltipAnchorTop, tooltipStyle, barClassName, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, withBandHighlight = false, onBandHighlightChange, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
6376
+ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, tooltipPlacement, tooltipAnchorTop, tooltipStyle, barClassName, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, withBandHighlight = false, onBandHighlightChange, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
6300
6377
  if (!withTooltips && (withBandHighlight || onBandHighlightChange)) warnOnce("bar-chart-band-highlight-without-tooltips", "BarChart: withBandHighlight and onBandHighlightChange require withTooltips.");
6301
6378
  const legendInteractive = legend.interactive ?? false;
6302
6379
  const legendCollapseGroups = legend.collapseGroups ?? false;
@@ -6520,7 +6597,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
6520
6597
  const patternId = getPatternId(chartId, index);
6521
6598
  return `
6522
6599
  .visx-bar[fill="url(#${patternId})"],
6523
- .bar-chart__comparison-bars rect[fill="url(#${patternId})"] {
6600
+ .bar-chart__comparison-bar[fill="url(#${patternId})"] {
6524
6601
  stroke: ${color};
6525
6602
  stroke-width: 1;
6526
6603
  }
@@ -6604,9 +6681,9 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
6604
6681
  children: ({ contentHeight }) => {
6605
6682
  const chartHeight = contentHeight > 0 ? contentHeight : height;
6606
6683
  return /* @__PURE__ */ jsx("div", {
6607
- role: "grid",
6684
+ role: "application",
6608
6685
  ref: chartRef,
6609
- "aria-label": __("Bar chart", "jetpack-charts"),
6686
+ "aria-label": ariaLabel ?? __("Bar chart", "jetpack-charts"),
6610
6687
  tabIndex: 0,
6611
6688
  onKeyDown: onChartKeyDown,
6612
6689
  onFocus: onChartFocus,
@@ -6614,6 +6691,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
6614
6691
  children: chartHeight > 0 && /* @__PURE__ */ jsx("div", {
6615
6692
  className: xy_plot_module_default["xy-plot"],
6616
6693
  children: /* @__PURE__ */ jsxs(XYChart, {
6694
+ accessibilityLabel: "",
6617
6695
  theme,
6618
6696
  width,
6619
6697
  height: chartHeight,
@@ -6702,15 +6780,15 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
6702
6780
  }),
6703
6781
  !allSeriesHidden && /* @__PURE__ */ jsx(WholeNumberTicks, {
6704
6782
  ...wholeNumberTicksProps,
6705
- children: (valueTicks) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Axis, {
6783
+ children: (valueTicks) => /* @__PURE__ */ jsxs(Fragment$1, { children: [chartOptions.axis.x.display !== false && /* @__PURE__ */ jsx(Axis, {
6706
6784
  ...chartOptions.axis.x,
6707
6785
  ...horizontal && valueTicks ? { tickValues: valueTicks } : {}
6708
- }), /* @__PURE__ */ jsx(Axis, {
6786
+ }), chartOptions.axis.y.display !== false && /* @__PURE__ */ jsx(Axis, {
6709
6787
  ...chartOptions.axis.y,
6710
6788
  ...!horizontal && valueTicks ? { tickValues: valueTicks } : {}
6711
6789
  })] })
6712
6790
  }),
6713
- withTooltips && /* @__PURE__ */ jsx(AccessibleTooltip, {
6791
+ withTooltips && /* @__PURE__ */ jsx(XYChartTooltip, {
6714
6792
  tooltipPlacement,
6715
6793
  tooltipAnchorTop,
6716
6794
  style: tooltipStyle,
@@ -7237,7 +7315,10 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
7237
7315
  left: tooltipLeft,
7238
7316
  className: standaloneScopeClass,
7239
7317
  style: tooltipStyle,
7240
- children: tooltipContent
7318
+ children: /* @__PURE__ */ jsx("div", {
7319
+ role: "tooltip",
7320
+ children: tooltipContent
7321
+ })
7241
7322
  });
7242
7323
  })()]
7243
7324
  });
@@ -7616,6 +7697,7 @@ var heatmap_chart_module_default = {
7616
7697
  "heatmap-chart__legend-label": "a8ccharts-O3YMOW-heatmap-chart__legend-label",
7617
7698
  "heatmap-chart__legend-scale--bar": "a8ccharts-O3YMOW-heatmap-chart__legend-scale--bar",
7618
7699
  "heatmap-chart__legend-swatch": "a8ccharts-O3YMOW-heatmap-chart__legend-swatch",
7700
+ "heatmap-chart__legend-swatch--empty": "a8ccharts-O3YMOW-heatmap-chart__legend-swatch--empty",
7619
7701
  "heatmap-chart__row": "a8ccharts-O3YMOW-heatmap-chart__row",
7620
7702
  "heatmap-chart__row-label": "a8ccharts-O3YMOW-heatmap-chart__row-label",
7621
7703
  "heatmap-chart--height-capped": "a8ccharts-O3YMOW-heatmap-chart--height-capped"
@@ -7624,30 +7706,44 @@ var heatmap_chart_module_default = {
7624
7706
  //#region src/charts/heatmap-chart/private/use-heatmap-colors.ts
7625
7707
  const isPresent = (value) => value !== null && value !== void 0 && !isNaN(value);
7626
7708
  /**
7627
- * Get the min and max values from heatmap data, ignoring null/NaN. Summary
7628
- * columns stay out: a roll-up on the scale would flatten every real cell.
7709
+ * Get the min and max values from heatmap data, ignoring null/NaN and the zeros
7710
+ * `isEmptyValue` paints as empty. Summary columns stay out: a roll-up on the
7711
+ * scale would flatten every real cell.
7629
7712
  * @param data - The heatmap columns
7630
7713
  * @return Tuple of [min, max] values
7631
7714
  */
7632
7715
  const getValueExtent = (data) => {
7633
7716
  let min = Infinity;
7634
7717
  let max = -Infinity;
7718
+ let hasZero = false;
7635
7719
  for (const column of data) {
7636
7720
  if (column.summary) continue;
7637
7721
  for (const cell of column.data) {
7638
7722
  if (!isPresent(cell.value)) continue;
7723
+ if (cell.value === 0) {
7724
+ hasZero = true;
7725
+ continue;
7726
+ }
7639
7727
  if (cell.value < min) min = cell.value;
7640
7728
  if (cell.value > max) max = cell.value;
7641
7729
  }
7642
7730
  }
7731
+ if (hasZero && min < 0) max = Math.max(max, 0);
7643
7732
  if (min === Infinity) return [0, 0];
7644
7733
  return [min, max];
7645
7734
  };
7646
7735
  /**
7736
+ * Whether a value paints as an empty cell: a zero in data with no negatives
7737
+ * counts nothing, so it must not look like the lowest step of activity.
7738
+ *
7739
+ * @param value - The cell value
7740
+ * @param extent - The extent from `getValueExtent`
7741
+ * @return True when the cell takes the empty-cell color
7742
+ */
7743
+ const isEmptyValue = (value, extent) => value === 0 && extent[0] >= 0;
7744
+ /**
7647
7745
  * Normalize a value to 0–1 within the extent. A flat extent (min === max)
7648
- * maps to 1 — every cell is equally the "highest" — except an all-zero
7649
- * extent, which maps to 0 so a no-activity grid renders at the scale's
7650
- * bottom instead of full intensity.
7746
+ * maps to 1, since every cell is equally the "highest".
7651
7747
  *
7652
7748
  * @param value - The value to normalize
7653
7749
  * @param extent - Tuple of [min, max] values for the normalization range
@@ -7655,9 +7751,40 @@ const getValueExtent = (data) => {
7655
7751
  */
7656
7752
  const getNormalizedValue = (value, extent) => {
7657
7753
  const [min, max] = extent;
7658
- if (min === max) return max === 0 ? 0 : 1;
7754
+ if (min === max) return 1;
7659
7755
  return Math.min(1, Math.max(0, (value - min) / (max - min)));
7660
7756
  };
7757
+ const STEPS = 200;
7758
+ const firstMeeting = (from, to, meets) => {
7759
+ for (let step = 0; step <= STEPS; step++) {
7760
+ const color = mixHexColors(from, to, step / STEPS);
7761
+ if (meets(color)) return color;
7762
+ }
7763
+ return null;
7764
+ };
7765
+ /**
7766
+ * The two ends of the heatmap fill scale: 3:1 against the background and the empty cell at the
7767
+ * low end, toward 9:1 against the background at the high end.
7768
+ *
7769
+ * @param primary - The resolved primary color, as six-digit hex.
7770
+ * @param background - The resolved chart background, as six-digit hex.
7771
+ * @param emptyCell - The resolved empty-cell color, as six-digit hex, when it is opaque.
7772
+ * @return The scale ends, as six-digit hex.
7773
+ */
7774
+ const getHeatmapScale = (primary, background, emptyCell) => {
7775
+ const primaryStandsOut = contrastRatio(primary, background) >= 3;
7776
+ const extreme = (primaryStandsOut ? relativeLuminance(primary) > relativeLuminance(background) : contrastRatio("#ffffff", background) > contrastRatio("#000000", background)) ? "#ffffff" : "#000000";
7777
+ const lowAgainst = (references) => {
7778
+ const meets = (color) => references.every((reference) => contrastRatio(color, reference) >= 3);
7779
+ return (primaryStandsOut ? firstMeeting(background, primary, meets) : null) ?? firstMeeting(primary, extreme, meets);
7780
+ };
7781
+ const high = firstMeeting(primary, extreme, (color) => contrastRatio(color, background) >= 9) ?? extreme;
7782
+ const againstEmptyCell = emptyCell ? lowAgainst([background, emptyCell]) : null;
7783
+ return {
7784
+ low: (againstEmptyCell && contrastRatio(againstEmptyCell, background) <= contrastRatio(high, background) ? againstEmptyCell : lowAgainst([background])) ?? extreme,
7785
+ high
7786
+ };
7787
+ };
7661
7788
  //#endregion
7662
7789
  //#region src/charts/heatmap-chart/private/heatmap-context.ts
7663
7790
  /** Shared by the chart and legend without importing back from `heatmap-chart.tsx`. */
@@ -7668,8 +7795,9 @@ const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }
7668
7795
  const context = useContext(HeatmapContext);
7669
7796
  const { legend } = useGlobalChartsTheme();
7670
7797
  if (!context) return null;
7671
- const { primaryColorHex } = context;
7798
+ const { extent, fillVars } = context;
7672
7799
  const labelStyle = legend.labelStyles;
7800
+ const showsEmptyCell = isEmptyValue(0, extent);
7673
7801
  return /* @__PURE__ */ jsxs(Stack, {
7674
7802
  direction: "row",
7675
7803
  gap: "xs",
@@ -7681,21 +7809,21 @@ const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }
7681
7809
  style: labelStyle,
7682
7810
  children: lessLabel ?? __("Less", "jetpack-charts")
7683
7811
  }),
7684
- /* @__PURE__ */ jsx(Stack, {
7812
+ /* @__PURE__ */ jsxs(Stack, {
7685
7813
  direction: "row",
7686
7814
  gap: variant === "bar" ? void 0 : "xs",
7687
7815
  "aria-hidden": "true",
7688
7816
  className: variant === "bar" ? heatmap_chart_module_default["heatmap-chart__legend-scale--bar"] : void 0,
7689
- children: Array.from({ length: steps }, (_, index) => {
7817
+ children: [showsEmptyCell && /* @__PURE__ */ jsx("span", { className: clsx(heatmap_chart_module_default["heatmap-chart__legend-swatch"], heatmap_chart_module_default["heatmap-chart__legend-swatch--empty"]) }), Array.from({ length: steps }, (_, index) => {
7690
7818
  const intensity = steps <= 1 ? 1 : index / (steps - 1);
7691
7819
  return /* @__PURE__ */ jsx("span", {
7692
7820
  className: heatmap_chart_module_default["heatmap-chart__legend-swatch"],
7693
7821
  style: {
7694
- "--a8c-charts-color-heatmap-primary": primaryColorHex,
7822
+ ...fillVars,
7695
7823
  "--a8c-charts-heatmap-cell-intensity": intensity
7696
7824
  }
7697
7825
  }, index);
7698
- })
7826
+ })]
7699
7827
  }),
7700
7828
  /* @__PURE__ */ jsx(Text$1, {
7701
7829
  variant: "body-sm",
@@ -7721,9 +7849,11 @@ const resolveColumnGroups = (groups, columnCount, firstLine) => {
7721
7849
  const ungrouped = () => ({
7722
7850
  columns: Array.from({ length: columnCount }, (_, index) => ({
7723
7851
  line: firstLine + index,
7852
+ band: 0,
7724
7853
  gapBefore: false
7725
7854
  })),
7726
- groups: []
7855
+ groups: [],
7856
+ bands: 1
7727
7857
  });
7728
7858
  if (!groups || groups.length === 0 || columnCount === 0) return ungrouped();
7729
7859
  const spans = groups.map((group) => group.span);
@@ -7739,11 +7869,13 @@ const resolveColumnGroups = (groups, columnCount, firstLine) => {
7739
7869
  if (groupIndex > 0) line += 1;
7740
7870
  laidOut.push({
7741
7871
  ...group,
7742
- line
7872
+ line,
7873
+ band: 0
7743
7874
  });
7744
7875
  for (let offset = 0; offset < group.span; offset++) {
7745
7876
  columns.push({
7746
7877
  line,
7878
+ band: 0,
7747
7879
  gapBefore: groupIndex > 0 && offset === 0,
7748
7880
  group: groupIndex
7749
7881
  });
@@ -7753,13 +7885,99 @@ const resolveColumnGroups = (groups, columnCount, firstLine) => {
7753
7885
  while (columns.length < columnCount) {
7754
7886
  columns.push({
7755
7887
  line,
7888
+ band: 0,
7756
7889
  gapBefore: false
7757
7890
  });
7758
7891
  line += 1;
7759
7892
  }
7760
7893
  return {
7761
7894
  columns,
7762
- groups: laidOut
7895
+ groups: laidOut,
7896
+ bands: 1
7897
+ };
7898
+ };
7899
+ /**
7900
+ * Wraps the groups onto bands of equal group count, each band starting back at
7901
+ * the first data line so the groups line up in slots down the bands.
7902
+ *
7903
+ * @param layout - The unwrapped layout from `resolveColumnGroups`.
7904
+ * @param bands - Bands to aim for; the groups split as evenly as whole bands allow.
7905
+ * @return The wrapped layout, or null when there is nothing to wrap: one band, one group, or a column outside every group.
7906
+ */
7907
+ const wrapColumnGroups = (layout, bands) => {
7908
+ const { columns, groups } = layout;
7909
+ if (bands < 2 || groups.length < 2 || columns.some((column) => column.group === void 0)) return null;
7910
+ const perBand = Math.ceil(groups.length / bands);
7911
+ const slotSpans = Array(perBand).fill(0);
7912
+ groups.forEach((group, index) => {
7913
+ const slot = index % perBand;
7914
+ slotSpans[slot] = Math.max(slotSpans[slot], group.span);
7915
+ });
7916
+ const slotLines = [];
7917
+ let line = columns[0].line;
7918
+ slotSpans.forEach((span, slot) => {
7919
+ if (slot > 0) line += 1;
7920
+ slotLines.push(line);
7921
+ line += span;
7922
+ });
7923
+ const wrappedGroups = groups.map((group, index) => ({
7924
+ ...group,
7925
+ line: slotLines[index % perBand],
7926
+ band: Math.floor(index / perBand)
7927
+ }));
7928
+ return {
7929
+ columns: columns.map((column) => {
7930
+ const group = column.group;
7931
+ const offset = column.line - groups[group].line;
7932
+ return {
7933
+ ...column,
7934
+ line: wrappedGroups[group].line + offset,
7935
+ band: wrappedGroups[group].band,
7936
+ gapBefore: offset === 0 && group % perBand > 0
7937
+ };
7938
+ }),
7939
+ groups: wrappedGroups,
7940
+ bands: Math.ceil(groups.length / perBand),
7941
+ slotSpans
7942
+ };
7943
+ };
7944
+ //#endregion
7945
+ //#region src/charts/heatmap-chart/private/fit-compact-cells.ts
7946
+ /**
7947
+ * Largest whole-pixel square cell, and the band count giving it, for a compact grid in a box.
7948
+ *
7949
+ * @param input - The box, the grid's layout, and its fixed gaps and label sizes.
7950
+ * @return The fit; one band at `minCellSize` when no band count reaches it.
7951
+ */
7952
+ const fitCompactCells = (input) => {
7953
+ const { width, height, layout, rows, cellGap, groupGap, minCellSize } = input;
7954
+ const columns = layout.columns.length;
7955
+ if (columns === 0 || rows === 0) return {
7956
+ bands: 1,
7957
+ cellSize: minCellSize
7958
+ };
7959
+ const maxBands = Math.max(1, layout.groups.length);
7960
+ const labelHeights = (input.columnLabelHeight ?? 0) + (input.groupLabelHeight ?? 0);
7961
+ const bandTracks = (input.columnLabelHeight === null ? 0 : 1) + rows + (input.groupLabelHeight === null ? 0 : 1);
7962
+ let best = null;
7963
+ for (let target = 1; target <= maxBands; target++) {
7964
+ const wrapped = target > 1 ? wrapColumnGroups(layout, target) : null;
7965
+ const { bands } = wrapped ?? layout;
7966
+ const cellColumns = wrapped ? wrapped.slotSpans.reduce((sum, span) => sum + span, 0) : columns;
7967
+ const gapTracks = wrapped ? wrapped.slotSpans.length - 1 : layout.columns.filter((column) => column.gapBefore).length;
7968
+ const columnTracks = 1 + cellColumns + gapTracks;
7969
+ const byWidth = (width - input.rowLabelWidth - gapTracks * groupGap - (columnTracks - 1) * cellGap) / cellColumns;
7970
+ const rowTracks = bands * bandTracks + (bands - 1);
7971
+ const byHeight = (height - (bands * labelHeights + (bands - 1) * groupGap + (rowTracks - 1) * cellGap)) / (bands * rows);
7972
+ const cellSize = Math.floor(Math.min(byWidth, byHeight));
7973
+ if (cellSize >= minCellSize && (!best || cellSize > best.cellSize)) best = {
7974
+ bands,
7975
+ cellSize
7976
+ };
7977
+ }
7978
+ return best ?? {
7979
+ bands: 1,
7980
+ cellSize: minCellSize
7763
7981
  };
7764
7982
  };
7765
7983
  //#endregion
@@ -7895,7 +8113,6 @@ const stepCalendarCell = (grid, blocks, from, key) => {
7895
8113
  };
7896
8114
  //#endregion
7897
8115
  //#region src/charts/heatmap-chart/heatmap-chart.tsx
7898
- const CELL_MIX_FLOOR = .15;
7899
8116
  const CELL_VALUE_MODIFIER = {
7900
8117
  label: void 0,
7901
8118
  "label-inverse": heatmap_chart_module_default["heatmap-chart__cell-value--inverse"],
@@ -7904,12 +8121,26 @@ const CELL_VALUE_MODIFIER = {
7904
8121
  };
7905
8122
  const NO_ROW_LABELS = [];
7906
8123
  const TOOLTIP_BOX_STYLE = { zIndex: 3 };
8124
+ const largest = (root, selector, size) => Math.max(0, ...Array.from(root.querySelectorAll(selector), (el) => el[size]));
8125
+ const gridBox = (chart, grid) => {
8126
+ let height = chart.clientHeight;
8127
+ const rowGap = parseFloat(getComputedStyle(chart).rowGap) || 0;
8128
+ Array.from(chart.children).forEach((child) => {
8129
+ const { display, position } = getComputedStyle(child);
8130
+ if (child === grid || display === "none" || position === "absolute" || position === "fixed") return;
8131
+ height -= child.offsetHeight + rowGap;
8132
+ });
8133
+ return {
8134
+ width: chart.clientWidth,
8135
+ height
8136
+ };
8137
+ };
7907
8138
  const cellName = (info) => info.cellLabel || [
7908
8139
  info.groupLabel,
7909
8140
  info.columnLabel,
7910
8141
  info.rowLabel
7911
8142
  ].filter(Boolean).join(" ");
7912
- const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = NO_ROW_LABELS, columnGroups, keyboardNavigation = "grid", ariaLabel, primaryColor, gap = "md", withTooltips = false, renderTooltip, tooltipStyle, children }) => {
8143
+ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, fitCells = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = NO_ROW_LABELS, columnGroups, keyboardNavigation = "grid", ariaLabel, primaryColor, gap = "md", withTooltips = false, renderTooltip, tooltipStyle, children }) => {
7913
8144
  const chartId = useChartId(providedChartId);
7914
8145
  const tooltipBoxStyle = tooltipStyle ? {
7915
8146
  ...TOOLTIP_BOX_STYLE,
@@ -7923,19 +8154,30 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
7923
8154
  const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = useTooltip();
7924
8155
  const standaloneScopeClass = useStandaloneScopeClass();
7925
8156
  const containerRef = useRef(null);
8157
+ const chartRef = useRef(null);
7926
8158
  const [labelRoles, setLabelRoles] = useState(null);
7927
- const getTooltipOrigin = useCallback(() => containerRef.current?.closest(`[data-chart-id="heatmap-chart-${chartId}"]`)?.getBoundingClientRect() ?? null, [chartId]);
8159
+ const getTooltipOrigin = useCallback(() => chartRef.current?.getBoundingClientRect() ?? null, []);
7928
8160
  const { color: primaryColorHex } = getElementStyles({
7929
8161
  index: 0,
7930
8162
  overrideColor: primaryColor
7931
8163
  });
7932
- const chartBackgroundHex = normalizeColorToHex(CATALOG_POINTERS.background, scopeElement, resolveCssVariable);
8164
+ const resolveAtScope = createCssVariableResolver(scopeElement);
8165
+ const chartBackgroundHex = resolveOpaqueHex(CATALOG_POINTERS.background, resolveAtScope) ?? "#ffffff";
8166
+ const emptyCellHex = resolveOpaqueHex(CATALOG_POINTERS.track, resolveAtScope);
7933
8167
  const primaryHex = normalizeColorToHex(primaryColorHex);
7934
- const cellMix = isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) ? {
7935
- primary: hexToRgb(primaryHex),
7936
- background: hexToRgb(chartBackgroundHex)
7937
- } : null;
7938
- const cellTextColor = (intensity) => cellMix ? pickLabelTextColorForFill(blendRgb(cellMix.primary, cellMix.background, CELL_MIX_FLOOR + .85 * intensity), labelRoles, "label") : "label";
8168
+ const scale = useMemo(() => isValidHexColor(primaryHex) ? getHeatmapScale(primaryHex, chartBackgroundHex, emptyCellHex) : null, [
8169
+ primaryHex,
8170
+ chartBackgroundHex,
8171
+ emptyCellHex
8172
+ ]);
8173
+ const fillVars = useMemo(() => ({
8174
+ "--a8c-charts-color-heatmap-primary": primaryColorHex,
8175
+ ...scale && {
8176
+ "--a8c-charts-color-heatmap-low": scale.low,
8177
+ "--a8c-charts-color-heatmap-high": scale.high
8178
+ }
8179
+ }), [primaryColorHex, scale]);
8180
+ const cellTextColor = (intensity) => scale ? pickLabelTextColorForFill(blendRgb(hexToRgb(scale.high), hexToRgb(scale.low), intensity), labelRoles, "label") : "label";
7939
8181
  useIsomorphicLayoutEffect(() => {
7940
8182
  if (!containerRef.current) return;
7941
8183
  const next = resolveLabelRoles(createCssVariableResolver(containerRef.current));
@@ -7949,13 +8191,56 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
7949
8191
  const extent = useMemo(() => getValueExtent(data), [data]);
7950
8192
  const heatmapContext = useMemo(() => ({
7951
8193
  extent,
7952
- primaryColorHex
7953
- }), [extent, primaryColorHex]);
8194
+ fillVars
8195
+ }), [extent, fillVars]);
7954
8196
  const columns = data.length;
7955
8197
  const rows = Math.max(0, ...data.map((column) => column.data.length));
7956
8198
  const groupLayout = useMemo(() => resolveColumnGroups(columnGroups, columns, 2), [columnGroups, columns]);
7957
8199
  const { compactCellGap, compactCellSize, groupGap } = heatmapChartSettings;
7958
8200
  const drawValues = showValues ?? !compact;
8201
+ const hasColumnLabels = data.some((column) => Boolean(column.label));
8202
+ const hasGroups = groupLayout.groups.length > 0;
8203
+ const [fit, setFit] = useState(null);
8204
+ const hasSummary = data.some((column) => column.summary);
8205
+ const fitting = compact && fitCells && !hasSummary;
8206
+ if (fitCells && !fitting) warnOnce("heatmap:fitCells", "fitCells applies only in compact mode without summary columns, so the cells keep their size.");
8207
+ useIsomorphicLayoutEffect(() => {
8208
+ const chart = chartRef.current;
8209
+ const grid = containerRef.current;
8210
+ if (!fitting || !chart || !grid) {
8211
+ setFit(null);
8212
+ return;
8213
+ }
8214
+ const measure = () => {
8215
+ const next = fitCompactCells({
8216
+ ...gridBox(chart, grid),
8217
+ layout: groupLayout,
8218
+ rows,
8219
+ cellGap: compactCellGap,
8220
+ groupGap,
8221
+ rowLabelWidth: largest(grid, `.${heatmap_chart_module_default["heatmap-chart__row-label"]}`, "offsetWidth"),
8222
+ columnLabelHeight: hasColumnLabels ? largest(grid, `.${heatmap_chart_module_default["heatmap-chart__col-label"]}`, "offsetHeight") : null,
8223
+ groupLabelHeight: hasGroups ? largest(grid, `.${heatmap_chart_module_default["heatmap-chart__group-label"]}`, "offsetHeight") : null,
8224
+ minCellSize: compactCellSize
8225
+ });
8226
+ setFit((previous) => (0, import_fast_deep_equal.default)(previous, next) ? previous : next);
8227
+ };
8228
+ measure();
8229
+ if (typeof ResizeObserver === "undefined") return;
8230
+ const observer = new ResizeObserver(() => flushSync(measure));
8231
+ observer.observe(chart);
8232
+ return () => observer.disconnect();
8233
+ }, [
8234
+ fitting,
8235
+ groupLayout,
8236
+ rows,
8237
+ hasColumnLabels,
8238
+ hasGroups,
8239
+ compactCellGap,
8240
+ compactCellSize,
8241
+ groupGap
8242
+ ]);
8243
+ const wrapped = useMemo(() => fit ? wrapColumnGroups(groupLayout, fit.bands) : null, [fit, groupLayout]);
7959
8244
  const buildTooltipData = useCallback((columnIndex, rowIndex) => {
7960
8245
  const cell = data[columnIndex]?.data[rowIndex];
7961
8246
  const group = groupLayout.columns[columnIndex]?.group;
@@ -8095,20 +8380,25 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
8095
8380
  });
8096
8381
  const columnTrack = compact ? "var(--a8c-charts-dimension-heatmap-cell-size)" : `minmax(${minCellWidth ?? 0}px, ${maxCellWidth ? `${maxCellWidth}px` : "1fr"})`;
8097
8382
  const rowTrack = compact ? "var(--a8c-charts-dimension-heatmap-cell-size)" : `minmax(${minCellHeight ?? 0}px, ${maxCellHeight ? `${maxCellHeight}px` : "1fr"})`;
8098
- const hasColumnLabels = data.some((column) => Boolean(column.label));
8099
- const hasGroups = groupLayout.groups.length > 0;
8100
- const columnLine = (columnIndex) => groupLayout.columns[columnIndex].line;
8101
- const firstDataRow = hasColumnLabels ? 2 : 1;
8383
+ const placed = wrapped ?? groupLayout;
8384
+ const columnLine = (columnIndex) => placed.columns[columnIndex].line;
8385
+ const bandOf = (columnIndex) => placed.columns[columnIndex].band;
8386
+ const { bands } = placed;
8387
+ const bandRowCount = (hasColumnLabels ? 1 : 0) + rows + (hasGroups ? 1 : 0) + 1;
8388
+ const labelRowOf = (band) => 1 + band * bandRowCount;
8389
+ const dataRowOf = (band, rowIndex) => labelRowOf(band) + (hasColumnLabels ? 1 : 0) + rowIndex;
8102
8390
  const dataTrack = (column) => column.summary ? "minmax(auto, max-content)" : columnTrack;
8103
8391
  const gapTrack = compact ? `minmax(${groupGap}px, 1fr)` : `${groupGap}px`;
8392
+ const columnTracks = wrapped ? wrapped.slotSpans.map((span, slot) => [...slot > 0 ? [gapTrack] : [], ...Array(span).fill(columnTrack)].join(" ")).join(" ") : data.map((column, columnIndex) => groupLayout.columns[columnIndex].gapBefore ? `${gapTrack} ${dataTrack(column)}` : dataTrack(column)).join(" ");
8393
+ const bandTracks = `${hasColumnLabels ? "auto " : ""}repeat(${rows}, ${rowTrack})${hasGroups ? " auto" : ""}`;
8104
8394
  const gridStyle = {
8105
- "--a8c-charts-color-heatmap-primary": primaryColorHex,
8106
- gridTemplateColumns: `auto ${data.map((column, columnIndex) => groupLayout.columns[columnIndex].gapBefore ? `${gapTrack} ${dataTrack(column)}` : dataTrack(column)).join(" ")}`,
8107
- gridTemplateRows: `${hasColumnLabels ? "auto " : ""}repeat(${rows}, ${rowTrack})${hasGroups ? " auto" : ""}`
8395
+ ...fillVars,
8396
+ gridTemplateColumns: `auto ${columnTracks}`,
8397
+ gridTemplateRows: Array(bands).fill(bandTracks).join(` ${groupGap}px `)
8108
8398
  };
8109
8399
  if (compact) {
8110
8400
  gridStyle["--a8c-charts-dimension-heatmap-cell-gap"] = `${compactCellGap}px`;
8111
- gridStyle["--a8c-charts-dimension-heatmap-cell-size"] = `${compactCellSize}px`;
8401
+ gridStyle["--a8c-charts-dimension-heatmap-cell-size"] = `${fit?.cellSize ?? compactCellSize}px`;
8112
8402
  }
8113
8403
  const summaryGaps = (columnIndex) => {
8114
8404
  if (!data[columnIndex]?.summary) return {};
@@ -8128,6 +8418,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
8128
8418
  legendChildren: [],
8129
8419
  trailingContent: nonLegendChildren,
8130
8420
  gap,
8421
+ rootRef: chartRef,
8131
8422
  className: clsx("heatmap-chart", heatmap_chart_module_default["heatmap-chart"], className, { [heatmap_chart_module_default["heatmap-chart--height-capped"]]: heightCapped }),
8132
8423
  style: {
8133
8424
  width: width || void 0,
@@ -8157,11 +8448,11 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
8157
8448
  className: heatmap_chart_module_default["heatmap-chart__row"],
8158
8449
  children: [/* @__PURE__ */ jsx("span", { style: {
8159
8450
  gridColumn: 1,
8160
- gridRow: 1
8451
+ gridRow: labelRowOf(0)
8161
8452
  } }), data.map((column, columnIndex) => /* @__PURE__ */ jsx("span", {
8162
8453
  style: {
8163
8454
  gridColumn: columnLine(columnIndex),
8164
- gridRow: 1
8455
+ gridRow: labelRowOf(bandOf(columnIndex))
8165
8456
  },
8166
8457
  className: clsx(heatmap_chart_module_default["heatmap-chart__col-label"], {
8167
8458
  [heatmap_chart_module_default["heatmap-chart__col-label--summary"]]: column.summary,
@@ -8172,24 +8463,23 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
8172
8463
  }),
8173
8464
  Array.from({ length: rows }).map((_row, rowIndex) => {
8174
8465
  const labelVisible = !compact || rowIndex % 2 === 0;
8175
- const gridRow = firstDataRow + rowIndex;
8176
8466
  return /* @__PURE__ */ jsxs("div", {
8177
8467
  role: "row",
8178
8468
  "aria-rowindex": rowIndex + 1,
8179
8469
  className: heatmap_chart_module_default["heatmap-chart__row"],
8180
- children: [/* @__PURE__ */ jsx("span", {
8470
+ children: [Array.from({ length: bands }).map((_band, band) => /* @__PURE__ */ jsx("span", {
8181
8471
  "aria-hidden": "true",
8182
8472
  className: heatmap_chart_module_default["heatmap-chart__row-label"],
8183
8473
  style: {
8184
8474
  gridColumn: 1,
8185
- gridRow
8475
+ gridRow: dataRowOf(band, rowIndex)
8186
8476
  },
8187
8477
  children: labelVisible ? rowLabels[rowIndex] ?? "" : ""
8188
- }), data.map((column, columnIndex) => {
8478
+ }, `row-label-${band}`)), data.map((column, columnIndex) => {
8189
8479
  const cell = column.data[rowIndex];
8190
8480
  const placement = {
8191
8481
  gridColumn: columnLine(columnIndex),
8192
- gridRow
8482
+ gridRow: dataRowOf(bandOf(columnIndex), rowIndex)
8193
8483
  };
8194
8484
  if (cell?.hidden) return /* @__PURE__ */ jsx("div", {
8195
8485
  "aria-hidden": "true",
@@ -8203,7 +8493,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
8203
8493
  }, `cell-${columnIndex}-${rowIndex}`);
8204
8494
  const value = cell?.value ?? null;
8205
8495
  const present = isPresent(value);
8206
- const filled = present && !column.summary;
8496
+ const filled = present && !column.summary && !isEmptyValue(value, extent);
8207
8497
  const normalized = filled ? getNormalizedValue(value, extent) : 0;
8208
8498
  const info = buildTooltipData(columnIndex, rowIndex);
8209
8499
  const accessibleLabel = `${cellName(info)}: ${info.value === null ? __("No data", "jetpack-charts") : formatNumber(info.value)}`;
@@ -8239,11 +8529,11 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
8239
8529
  role: "row",
8240
8530
  "aria-hidden": "true",
8241
8531
  className: heatmap_chart_module_default["heatmap-chart__row"],
8242
- children: groupLayout.groups.map((group, groupIndex) => /* @__PURE__ */ jsx("span", {
8532
+ children: placed.groups.map((group, groupIndex) => /* @__PURE__ */ jsx("span", {
8243
8533
  className: heatmap_chart_module_default["heatmap-chart__group-label"],
8244
8534
  style: {
8245
8535
  gridColumn: `${group.line} / span ${group.span}`,
8246
- gridRow: firstDataRow + rows
8536
+ gridRow: dataRowOf(group.band, rows)
8247
8537
  },
8248
8538
  children: group.label
8249
8539
  }, `group-${groupIndex}`))
@@ -11113,6 +11403,7 @@ var leaderboard_chart_module_default = {
11113
11403
  "interactiveRow": "a8ccharts-GovfoW-interactiveRow",
11114
11404
  "is-overlay": "a8ccharts-GovfoW-is-overlay",
11115
11405
  "label": "a8ccharts-GovfoW-label",
11406
+ "layeredRow": "a8ccharts-GovfoW-layeredRow",
11116
11407
  "leaderboardChart": "a8ccharts-GovfoW-leaderboardChart",
11117
11408
  "leaderboardChart__content": "a8ccharts-GovfoW-leaderboardChart__content",
11118
11409
  "leaderboardChart__content--fit": "a8ccharts-GovfoW-leaderboardChart__content--fit",
@@ -11121,6 +11412,7 @@ var leaderboard_chart_module_default = {
11121
11412
  "overlap": "a8ccharts-GovfoW-overlap",
11122
11413
  "overlayLabel": "a8ccharts-GovfoW-overlayLabel",
11123
11414
  "row": "a8ccharts-GovfoW-row",
11415
+ "rowButton": "a8ccharts-GovfoW-rowButton",
11124
11416
  "stretch": "a8ccharts-GovfoW-stretch",
11125
11417
  "valueContainer": "a8ccharts-GovfoW-valueContainer"
11126
11418
  };
@@ -11171,6 +11463,16 @@ const defaultDeltaFormatter = (value) => {
11171
11463
  const getBarWidth = (share) => `calc(${share}% - var(--a8c-charts-dimension-leaderboard-bar-hover-inset, 0px) * ${share} / 100)`;
11172
11464
  const hasPreviousValue = (entry) => entry.previousValue != null && entry.previousShare != null;
11173
11465
  const hasDeltaValue = (entry) => hasPreviousValue(entry) && entry.delta != null;
11466
+ /**
11467
+ * A layered row's cell that takes pointer events of its own (a value tooltip)
11468
+ * sits above the row button; pass its clicks on so they still drill down.
11469
+ *
11470
+ * @param event - The click on the row.
11471
+ */
11472
+ function forwardCellClickToRowButton(event) {
11473
+ if (event.target.closest("a, button")) return;
11474
+ event.currentTarget.querySelector(":scope > button")?.click();
11475
+ }
11174
11476
  const BarLabel = ({ label }) => /* @__PURE__ */ jsx(Fragment$1, { children: typeof label === "string" ? /* @__PURE__ */ jsx(Text$1, {
11175
11477
  className: leaderboard_chart_module_default.label,
11176
11478
  children: label
@@ -11403,6 +11705,26 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
11403
11705
  })
11404
11706
  ]
11405
11707
  })] });
11708
+ if (entry.onClick && entry.hasInteractiveLabel) return /* @__PURE__ */ jsxs("div", {
11709
+ "data-row-index": rowIndex,
11710
+ style: rowStyle,
11711
+ className: clsx(leaderboard_chart_module_default.row, leaderboard_chart_module_default.interactiveRow, leaderboard_chart_module_default.layeredRow),
11712
+ onClick: forwardCellClickToRowButton,
11713
+ children: [
11714
+ rowCells,
11715
+ /* @__PURE__ */ jsx("button", {
11716
+ type: "button",
11717
+ className: leaderboard_chart_module_default.rowButton,
11718
+ onClick: entry.onClick,
11719
+ "aria-label": entry.ariaLabel
11720
+ }),
11721
+ /* @__PURE__ */ jsx(Icon, {
11722
+ className: leaderboard_chart_module_default.chevron,
11723
+ icon: chevronRight,
11724
+ size: 24
11725
+ })
11726
+ ]
11727
+ }, entry.id);
11406
11728
  if (entry.onClick) return /* @__PURE__ */ jsxs("button", {
11407
11729
  type: "button",
11408
11730
  "data-row-index": rowIndex,
@@ -11436,6 +11758,210 @@ LeaderboardChartWithProvider.displayName = "LeaderboardChart";
11436
11758
  const LeaderboardChart = attachSubComponents(LeaderboardChartWithProvider, { Legend });
11437
11759
  const LeaderboardChartResponsive = attachSubComponents(withResponsive(LeaderboardChartWithProvider), { Legend });
11438
11760
  //#endregion
11761
+ //#region src/charts/private/pie-keyboard-navigation/order-arcs-for-navigation.ts
11762
+ /**
11763
+ * Orders arcs the way they appear: clockwise from 12 o'clock, which for a semi-circle is left to right.
11764
+ *
11765
+ * @param arcs - Arcs from visx's `pie` factory, in data order.
11766
+ * @return A copy of `arcs` sorted by angular midpoint.
11767
+ */
11768
+ const orderArcsForNavigation = (arcs) => [...arcs].sort((a, b) => a.startAngle + a.endAngle - (b.startAngle + b.endAngle));
11769
+ //#endregion
11770
+ //#region src/charts/private/pie-keyboard-navigation/pie-selection-announcement.tsx
11771
+ const PieSelectionAnnouncement = ({ data }) => /* @__PURE__ */ jsx(VisuallyHidden, {
11772
+ role: "status",
11773
+ "aria-atomic": "true",
11774
+ children: data && /* @__PURE__ */ jsx(LabelValueContent, { data })
11775
+ });
11776
+ //#endregion
11777
+ //#region src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx
11778
+ const PieTooltip = ({ top, left, selectedIndex, tooltipRef, children }) => {
11779
+ const standaloneScopeClass = useStandaloneScopeClass();
11780
+ return /* @__PURE__ */ jsx(BoundedTooltip, {
11781
+ top,
11782
+ left,
11783
+ children: selectedIndex === void 0 ? /* @__PURE__ */ jsx("div", {
11784
+ className: standaloneScopeClass,
11785
+ role: "tooltip",
11786
+ children
11787
+ }) : /* @__PURE__ */ jsx("div", {
11788
+ ref: tooltipRef,
11789
+ tabIndex: -1,
11790
+ role: "tooltip",
11791
+ "aria-atomic": "true",
11792
+ className: standaloneScopeClass,
11793
+ children
11794
+ }, `chart-tooltip-${selectedIndex}`)
11795
+ });
11796
+ };
11797
+ //#endregion
11798
+ //#region src/charts/private/pie-keyboard-navigation/pie-selection-output.tsx
11799
+ /**
11800
+ * Reports the selected segment: a focused tooltip for a keyboard selection, a pointer tooltip on hover, or a screen reader announcement without tooltips.
11801
+ *
11802
+ * @param {PieSelectionOutputProps} props - Component props
11803
+ * @return {JSX.Element} The announcement region and the tooltip, if any
11804
+ */
11805
+ const PieSelectionOutput = ({ withTooltips, selectedIndex, selectedData, keyboardTooltipAnchor, pointerTooltip, chartRef, svgRef, tooltipRef, renderTooltip }) => {
11806
+ const [svgOffset, setSvgOffset] = useState({
11807
+ top: 0,
11808
+ left: 0
11809
+ });
11810
+ const showKeyboardTooltip = withTooltips && selectedData && keyboardTooltipAnchor;
11811
+ useLayoutEffect(() => {
11812
+ const chartBounds = chartRef.current?.getBoundingClientRect();
11813
+ const svgBounds = svgRef.current?.getBoundingClientRect();
11814
+ if (!showKeyboardTooltip || !chartBounds || !svgBounds) return;
11815
+ const top = svgBounds.top - chartBounds.top;
11816
+ const left = svgBounds.left - chartBounds.left;
11817
+ setSvgOffset((current) => current.top === top && current.left === left ? current : {
11818
+ top,
11819
+ left
11820
+ });
11821
+ });
11822
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
11823
+ /* @__PURE__ */ jsx(PieSelectionAnnouncement, { data: withTooltips ? void 0 : selectedData }),
11824
+ showKeyboardTooltip && /* @__PURE__ */ jsx(PieTooltip, {
11825
+ top: svgOffset.top + keyboardTooltipAnchor.top,
11826
+ left: svgOffset.left + keyboardTooltipAnchor.left,
11827
+ selectedIndex,
11828
+ tooltipRef,
11829
+ children: renderTooltip({ tooltipData: selectedData })
11830
+ }),
11831
+ withTooltips && !selectedData && pointerTooltip?.data && /* @__PURE__ */ jsx(PieTooltip, {
11832
+ top: pointerTooltip.top,
11833
+ left: pointerTooltip.left,
11834
+ children: renderTooltip({ tooltipData: pointerTooltip.data })
11835
+ })
11836
+ ] });
11837
+ };
11838
+ //#endregion
11839
+ //#region src/charts/private/pie-keyboard-navigation/pie-keyboard-navigation.module.scss
11840
+ var pie_keyboard_navigation_module_default = {
11841
+ "selected-ring__contrast": "a8ccharts-V2HDKq-selected-ring__contrast",
11842
+ "selected-ring__focus": "a8ccharts-V2HDKq-selected-ring__focus"
11843
+ };
11844
+ //#endregion
11845
+ //#region src/charts/private/pie-keyboard-navigation/selected-segment-ring.tsx
11846
+ /**
11847
+ * Encodes `value` for an SVG id, losslessly so distinct chart ids never share a clip path.
11848
+ *
11849
+ * @param value - Any string.
11850
+ * @return `value` with each character outside `[A-Za-z0-9-]` written as `_<hex code point>_`.
11851
+ */
11852
+ const toSvgId = (value) => Array.from(value, (character) => /[A-Za-z0-9-]/.test(character) ? character : `_${character.codePointAt(0)?.toString(16)}_`).join("");
11853
+ /**
11854
+ * Marks the selected segment with a two-tone ring drawn inside its edge, so the SVG edge cannot cut it off.
11855
+ *
11856
+ * @param {SelectedSegmentRingProps} props - Component props
11857
+ * @return {JSX.Element} The ring
11858
+ */
11859
+ const SelectedSegmentRing = ({ chartId, d }) => {
11860
+ const clipId = `pie-selected-ring-clip-${toSvgId(chartId)}`;
11861
+ const clipPath = `url(#${clipId})`;
11862
+ return /* @__PURE__ */ jsxs("g", {
11863
+ pointerEvents: "none",
11864
+ "aria-hidden": "true",
11865
+ children: [
11866
+ /* @__PURE__ */ jsx("clipPath", {
11867
+ id: clipId,
11868
+ children: /* @__PURE__ */ jsx("path", { d })
11869
+ }),
11870
+ /* @__PURE__ */ jsx("path", {
11871
+ d,
11872
+ clipPath,
11873
+ className: pie_keyboard_navigation_module_default["selected-ring__contrast"]
11874
+ }),
11875
+ /* @__PURE__ */ jsx("path", {
11876
+ d,
11877
+ clipPath,
11878
+ className: pie_keyboard_navigation_module_default["selected-ring__focus"]
11879
+ })
11880
+ ]
11881
+ });
11882
+ };
11883
+ //#endregion
11884
+ //#region src/charts/private/pie-keyboard-navigation/use-pie-keyboard-navigation.ts
11885
+ const usePieKeyboardNavigation = ({ navigationArcs, withTooltips, tooltipOffsetX, tooltipOffsetY }) => {
11886
+ const chartRef = useRef(null);
11887
+ const svgRef = useRef(null);
11888
+ const [selectedIndex, setSelectedIndex] = useState(void 0);
11889
+ const [isNavigating, setIsNavigating] = useState(false);
11890
+ const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = useTooltip();
11891
+ const { tooltipRef: focusTooltip, onChartFocus, onChartBlur, onChartKeyDown, onChartPointerMove } = useKeyboardNavigation({
11892
+ selectedIndex,
11893
+ setSelectedIndex,
11894
+ isNavigating,
11895
+ setIsNavigating,
11896
+ chartRef,
11897
+ totalPoints: navigationArcs.length,
11898
+ visibleSeriesKey: JSON.stringify(navigationArcs.map((arcDatum) => arcDatum.data.label))
11899
+ });
11900
+ const selectedArc = selectedIndex === void 0 ? void 0 : navigationArcs[selectedIndex];
11901
+ const keyboardTooltip = useRef(null);
11902
+ const tooltipLostFocus = useRef(false);
11903
+ const tooltipRef = useCallback((element) => {
11904
+ if (element) {
11905
+ keyboardTooltip.current = element;
11906
+ focusTooltip(element);
11907
+ } else if (keyboardTooltip.current?.ownerDocument.activeElement === keyboardTooltip.current) tooltipLostFocus.current = true;
11908
+ }, [focusTooltip]);
11909
+ useLayoutEffect(() => {
11910
+ if (!tooltipLostFocus.current) return;
11911
+ tooltipLostFocus.current = false;
11912
+ const { activeElement, body } = chartRef.current?.ownerDocument ?? document;
11913
+ if (activeElement === null || activeElement === body) chartRef.current?.focus();
11914
+ });
11915
+ const getSegmentHandlers = (data, navigationIndex) => ({
11916
+ onMouseMove: (event) => {
11917
+ onChartPointerMove(navigationIndex);
11918
+ if (!withTooltips) return;
11919
+ const bounds = chartRef.current?.getBoundingClientRect();
11920
+ if (!bounds) return;
11921
+ showTooltip({
11922
+ tooltipData: data,
11923
+ tooltipLeft: event.clientX - bounds.left + tooltipOffsetX,
11924
+ tooltipTop: event.clientY - bounds.top + tooltipOffsetY
11925
+ });
11926
+ },
11927
+ onMouseLeave: withTooltips ? hideTooltip : void 0
11928
+ });
11929
+ return {
11930
+ chartRef,
11931
+ svgRef,
11932
+ selectedArc,
11933
+ getSegmentHandlers,
11934
+ getKeyboardTooltipAnchor: useCallback((originX, originY, [x, y]) => withTooltips ? {
11935
+ left: originX + x + tooltipOffsetX,
11936
+ top: originY + y + tooltipOffsetY
11937
+ } : void 0, [
11938
+ withTooltips,
11939
+ tooltipOffsetX,
11940
+ tooltipOffsetY
11941
+ ]),
11942
+ selectionOutputProps: {
11943
+ withTooltips,
11944
+ selectedIndex,
11945
+ selectedData: selectedArc?.data,
11946
+ chartRef,
11947
+ svgRef,
11948
+ tooltipRef,
11949
+ pointerTooltip: tooltipOpen ? {
11950
+ data: tooltipData,
11951
+ left: tooltipLeft || 0,
11952
+ top: tooltipTop || 0
11953
+ } : void 0
11954
+ },
11955
+ chartProps: {
11956
+ role: "application",
11957
+ tabIndex: 0,
11958
+ onKeyDown: onChartKeyDown,
11959
+ onFocus: onChartFocus,
11960
+ onBlur: onChartBlur
11961
+ }
11962
+ };
11963
+ };
11964
+ //#endregion
11439
11965
  //#region src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx
11440
11966
  /**
11441
11967
  * Renders a SVG mask that creates a radial wipe animation effect.
@@ -11488,18 +12014,13 @@ var pie_chart_module_default = {
11488
12014
  //#region src/charts/pie-chart/pie-chart.tsx
11489
12015
  /**
11490
12016
  * Default tooltip renderer for pie charts.
11491
- * Renders a BaseTooltip with the hovered segment's data.
12017
+ * Renders the default `label: value` tooltip content for the hovered segment.
11492
12018
  *
11493
12019
  * @param {PieChartRenderTooltipParams} params - The tooltip parameters containing the hovered data point
11494
12020
  * @return {ReactNode} The rendered tooltip content
11495
12021
  */
11496
12022
  const renderDefaultPieTooltip = ({ tooltipData }) => {
11497
- return /* @__PURE__ */ jsx(BaseTooltip, {
11498
- data: tooltipData,
11499
- top: 0,
11500
- left: 0,
11501
- renderContainer: false
11502
- });
12023
+ return /* @__PURE__ */ jsx(LabelValueContent, { data: tooltipData });
11503
12024
  };
11504
12025
  /**
11505
12026
  * Validates the pie chart data
@@ -11536,20 +12057,13 @@ const LABEL_TEXT_MODIFIER = {
11536
12057
  * @param {PieChartProps} props - Component props
11537
12058
  * @return {JSX.Element} The rendered chart component
11538
12059
  */
11539
- const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false, className, showLegend = false, legend = {}, width: propWidth, height: propHeight, size, animation, thickness = 1, padding = 0, gapScale = 0, cornerScale = 0, showLabels = true, legendValueDisplay = "percentage", children = null, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieTooltip, gap = "md" }) => {
12060
+ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false, className, showLegend = false, legend = {}, width: propWidth, height: propHeight, size, animation, thickness = 1, padding = 0, gapScale = 0, cornerScale = 0, showLabels = true, legendValueDisplay = "percentage", children = null, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieTooltip, ariaLabel, gap = "md" }) => {
11540
12061
  const legendInteractive = legend.interactive ?? false;
11541
12062
  const legendPosition = legend.position ?? "bottom";
11542
12063
  const providerTheme = useGlobalChartsTheme();
11543
12064
  const chartId = useChartId(providedChartId);
11544
- const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = useTooltip();
11545
- const standaloneScopeClass = useStandaloneScopeClass();
11546
- const containerRef = useRef(null);
11547
12065
  const rootRef = useRef(null);
11548
12066
  const [labelRoles, setLabelRoles] = useState(null);
11549
- const onMouseLeave = useCallback(() => {
11550
- if (!withTooltips) return;
11551
- hideTooltip();
11552
- }, [withTooltips, hideTooltip]);
11553
12067
  const { getElementStyles, isSeriesVisible, isColorPaletteResolved } = useGlobalChartsContext();
11554
12068
  const { isValid, message } = validateData$1(data);
11555
12069
  useLayoutEffect(() => {
@@ -11593,13 +12107,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
11593
12107
  metadata: chartMetadata
11594
12108
  });
11595
12109
  const prefersReducedMotion = usePrefersReducedMotion();
11596
- if (!isValid) return /* @__PURE__ */ jsx("div", {
11597
- className: clsx("pie-chart", pie_chart_module_default["pie-chart"], className),
11598
- children: /* @__PURE__ */ jsx("div", {
11599
- className: pie_chart_module_default["error-message"],
11600
- children: message
11601
- })
11602
- });
12110
+ const wipeMask = animation && !prefersReducedMotion ? `url(#radial-wipe-${chartId})` : null;
11603
12111
  const padAngle = gapScale * (2 * Math.PI / data.length);
11604
12112
  const dataWithIndex = visibleData.map((d) => {
11605
12113
  const originalIndex = data.findIndex((item) => item.label === d.label);
@@ -11617,6 +12125,24 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
11617
12125
  }).color;
11618
12126
  }
11619
12127
  };
12128
+ const arcs = pie({
12129
+ value: accessors.value,
12130
+ padAngle
12131
+ })(dataWithIndex);
12132
+ const navigationArcs = orderArcsForNavigation(arcs);
12133
+ const { chartRef, svgRef, selectedArc, getSegmentHandlers, getKeyboardTooltipAnchor, selectionOutputProps, chartProps } = usePieKeyboardNavigation({
12134
+ navigationArcs,
12135
+ withTooltips,
12136
+ tooltipOffsetX,
12137
+ tooltipOffsetY
12138
+ });
12139
+ if (!isValid) return /* @__PURE__ */ jsx("div", {
12140
+ className: clsx("pie-chart", pie_chart_module_default["pie-chart"], className),
12141
+ children: /* @__PURE__ */ jsx("div", {
12142
+ className: pie_chart_module_default["error-message"],
12143
+ children: message
12144
+ })
12145
+ });
11620
12146
  const legendElement = showLegend && /* @__PURE__ */ jsx(Legend, {
11621
12147
  orientation: legend.orientation ?? "horizontal",
11622
12148
  position: legendPosition,
@@ -11655,102 +12181,96 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
11655
12181
  const innerRadius = thickness === 0 ? 0 : outerRadius * (1 - thickness);
11656
12182
  const maxCornerRadius = (outerRadius - innerRadius) / 2;
11657
12183
  const cornerRadius = cornerScale ? Math.min(cornerScale * outerRadius, maxCornerRadius) : 0;
12184
+ const path = arc({
12185
+ innerRadius,
12186
+ outerRadius,
12187
+ cornerRadius
12188
+ });
12189
+ const svgLabelSmall = providerTheme.svgLabelSmall;
12190
+ const fontSize = resolveFontSize(svgLabelSmall?.fontSize) ?? 12;
12191
+ const renderLabel = (arcDatum, index) => {
12192
+ if (arcDatum.endAngle - arcDatum.startAngle < .25) return null;
12193
+ const [centroidX, centroidY] = path.centroid(arcDatum);
12194
+ const backgroundWidth = getStringWidth$1(arcDatum.data.label, {
12195
+ fontSize,
12196
+ fontFamily: svgLabelSmall?.fontFamily,
12197
+ fontWeight: svgLabelSmall?.fontWeight
12198
+ }) + 12;
12199
+ const backgroundHeight = fontSize + 12;
12200
+ return /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
12201
+ className: pie_chart_module_default["pie-chart__label-plate"],
12202
+ x: centroidX - backgroundWidth / 2,
12203
+ y: centroidY - backgroundHeight / 2,
12204
+ width: backgroundWidth,
12205
+ height: backgroundHeight,
12206
+ rx: 4,
12207
+ ry: 4,
12208
+ pointerEvents: "none"
12209
+ }), /* @__PURE__ */ jsx("text", {
12210
+ className: clsx(pie_chart_module_default["pie-chart__label-text"], LABEL_TEXT_MODIFIER[pickLabelTextColor(accessors.fill(arcDatum.data), labelRoles, "label-inverse")]),
12211
+ x: centroidX,
12212
+ y: centroidY,
12213
+ dy: ".33em",
12214
+ fontSize,
12215
+ textAnchor: "middle",
12216
+ pointerEvents: "none",
12217
+ children: arcDatum.data.label
12218
+ })] }, `label-${index}`);
12219
+ };
11658
12220
  return /* @__PURE__ */ jsxs(Center, {
11659
- ref: containerRef,
12221
+ ref: chartRef,
11660
12222
  className: pie_chart_module_default["pie-chart__plot"],
12223
+ ...chartProps,
12224
+ "aria-label": ariaLabel ?? __("Pie chart", "jetpack-charts"),
11661
12225
  children: [/* @__PURE__ */ jsxs("svg", {
12226
+ ref: svgRef,
11662
12227
  viewBox: `0 0 ${width} ${height}`,
11663
12228
  preserveAspectRatio: "xMidYMid meet",
11664
12229
  width,
11665
12230
  height,
11666
- children: [/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(RadialWipeAnimation, {
11667
- id: `radial-wipe-${chartId}`,
11668
- radius: outerRadius,
11669
- innerRadius
11670
- }) }), /* @__PURE__ */ jsxs(Group, {
11671
- top: centerY,
11672
- left: centerX,
11673
- mask: animation && !prefersReducedMotion ? `url(#radial-wipe-${chartId})` : null,
11674
- children: [allSegmentsHidden ? /* @__PURE__ */ jsx(SvgEmptyState, {
11675
- x: 0,
11676
- y: 0,
11677
- width,
11678
- height,
11679
- children: getAllHiddenMessage(legendInteractive, "segments")
11680
- }) : /* @__PURE__ */ jsx(Pie, {
11681
- data: dataWithIndex,
11682
- pieValue: accessors.value,
11683
- outerRadius,
11684
- innerRadius,
11685
- padAngle,
11686
- cornerRadius,
11687
- children: (pie) => {
11688
- return pie.arcs.map((arc, index) => {
11689
- const [centroidX, centroidY] = pie.path.centroid(arc);
11690
- const hasSpaceForLabel = arc.endAngle - arc.startAngle >= .25;
11691
- const handleMouseMove = (event) => {
11692
- if (!withTooltips) return;
11693
- const bounds = containerRef.current?.getBoundingClientRect();
11694
- if (!bounds) return;
11695
- showTooltip({
11696
- tooltipData: arc.data,
11697
- tooltipLeft: event.clientX - bounds.left + tooltipOffsetX,
11698
- tooltipTop: event.clientY - bounds.top + tooltipOffsetY
11699
- });
11700
- };
11701
- const fill = accessors.fill(arc.data);
11702
- const pathProps = {
11703
- d: pie.path(arc) || "",
11704
- fill,
11705
- "data-testid": "pie-segment"
11706
- };
11707
- const groupProps = {};
11708
- if (withTooltips) {
11709
- groupProps.onMouseMove = handleMouseMove;
11710
- groupProps.onMouseLeave = onMouseLeave;
11711
- }
11712
- const svgLabelSmall = providerTheme.svgLabelSmall;
11713
- const fontSize = resolveFontSize(svgLabelSmall?.fontSize) ?? 12;
11714
- const backgroundWidth = getStringWidth$1(arc.data.label, {
11715
- fontSize,
11716
- fontFamily: svgLabelSmall?.fontFamily,
11717
- fontWeight: svgLabelSmall?.fontWeight
11718
- }) + 12;
11719
- const backgroundHeight = fontSize + 12;
11720
- return /* @__PURE__ */ jsxs("g", {
11721
- ...groupProps,
11722
- children: [/* @__PURE__ */ jsx("path", { ...pathProps }), showLabels && hasSpaceForLabel && /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
11723
- className: pie_chart_module_default["pie-chart__label-plate"],
11724
- x: centroidX - backgroundWidth / 2,
11725
- y: centroidY - backgroundHeight / 2,
11726
- width: backgroundWidth,
11727
- height: backgroundHeight,
11728
- rx: 4,
11729
- ry: 4,
11730
- pointerEvents: "none"
11731
- }), /* @__PURE__ */ jsx("text", {
11732
- className: clsx(pie_chart_module_default["pie-chart__label-text"], LABEL_TEXT_MODIFIER[pickLabelTextColor(fill, labelRoles, "label-inverse")]),
11733
- x: centroidX,
11734
- y: centroidY,
11735
- dy: ".33em",
11736
- fontSize,
11737
- textAnchor: "middle",
11738
- pointerEvents: "none",
11739
- children: arc.data.label
11740
- })] })]
11741
- }, `arc-${index}`);
11742
- });
11743
- }
11744
- }), !allSegmentsHidden && svgChildren]
11745
- })]
11746
- }), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ jsx(BoundedTooltip, {
11747
- top: tooltipTop || 0,
11748
- left: tooltipLeft || 0,
11749
- children: /* @__PURE__ */ jsx("div", {
11750
- className: standaloneScopeClass,
11751
- role: "tooltip",
11752
- children: renderTooltip({ tooltipData })
11753
- })
12231
+ children: [
12232
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(RadialWipeAnimation, {
12233
+ id: `radial-wipe-${chartId}`,
12234
+ radius: outerRadius,
12235
+ innerRadius
12236
+ }) }),
12237
+ /* @__PURE__ */ jsx(Group, {
12238
+ top: centerY,
12239
+ left: centerX,
12240
+ mask: wipeMask,
12241
+ children: allSegmentsHidden ? /* @__PURE__ */ jsx(SvgEmptyState, {
12242
+ x: 0,
12243
+ y: 0,
12244
+ width,
12245
+ height,
12246
+ children: getAllHiddenMessage(legendInteractive, "segments")
12247
+ }) : arcs.map((arcDatum, index) => /* @__PURE__ */ jsx("g", {
12248
+ ...getSegmentHandlers(arcDatum.data, navigationArcs.indexOf(arcDatum)),
12249
+ children: /* @__PURE__ */ jsx("path", {
12250
+ d: path(arcDatum) || "",
12251
+ fill: accessors.fill(arcDatum.data)
12252
+ })
12253
+ }, `arc-${index}`))
12254
+ }),
12255
+ selectedArc && /* @__PURE__ */ jsx(Group, {
12256
+ top: centerY,
12257
+ left: centerX,
12258
+ children: /* @__PURE__ */ jsx(SelectedSegmentRing, {
12259
+ chartId,
12260
+ d: path(selectedArc) || ""
12261
+ })
12262
+ }),
12263
+ !allSegmentsHidden && /* @__PURE__ */ jsxs(Group, {
12264
+ top: centerY,
12265
+ left: centerX,
12266
+ mask: wipeMask,
12267
+ children: [showLabels && arcs.map(renderLabel), svgChildren]
12268
+ })
12269
+ ]
12270
+ }), /* @__PURE__ */ jsx(PieSelectionOutput, {
12271
+ ...selectionOutputProps,
12272
+ keyboardTooltipAnchor: selectedArc && getKeyboardTooltipAnchor(centerX, centerY, path.centroid(selectedArc)),
12273
+ renderTooltip
11754
12274
  })]
11755
12275
  });
11756
12276
  }
@@ -11785,18 +12305,13 @@ var pie_semi_circle_chart_module_default = {
11785
12305
  //#region src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx
11786
12306
  /**
11787
12307
  * Default tooltip renderer for semi-circle pie charts.
11788
- * Renders a BaseTooltip with the hovered segment's data.
12308
+ * Renders the default `label: value` tooltip content for the hovered segment.
11789
12309
  *
11790
12310
  * @param {PieSemiCircleChartRenderTooltipParams} params - The tooltip parameters containing the hovered data point
11791
12311
  * @return {ReactNode} The rendered tooltip content
11792
12312
  */
11793
12313
  const renderDefaultPieSemiCircleTooltip = ({ tooltipData }) => {
11794
- return /* @__PURE__ */ jsx(BaseTooltip, {
11795
- data: tooltipData,
11796
- top: 0,
11797
- left: 0,
11798
- renderContainer: false
11799
- });
12314
+ return /* @__PURE__ */ jsx(LabelValueContent, { data: tooltipData });
11800
12315
  };
11801
12316
  const PAD_ANGLE = .03;
11802
12317
  const DEFAULT_WIDTH$1 = 400;
@@ -11823,32 +12338,10 @@ const validateData = (data) => {
11823
12338
  message: ""
11824
12339
  };
11825
12340
  };
11826
- const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: propWidth, height: propHeight, thickness = .4, clockwise = true, withTooltips = false, showLegend = false, legend = {}, legendValueDisplay = "percentage", label, animation, note, className, children, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieSemiCircleTooltip, gap = "md" }) => {
12341
+ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: propWidth, height: propHeight, thickness = .4, clockwise = true, withTooltips = false, showLegend = false, legend = {}, legendValueDisplay = "percentage", label, animation, note, className, children, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieSemiCircleTooltip, ariaLabel, gap = "md" }) => {
11827
12342
  const legendInteractive = legend.interactive ?? false;
11828
12343
  const legendPosition = legend.position ?? "bottom";
11829
12344
  const chartId = useChartId(providedChartId);
11830
- const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = useTooltip();
11831
- const standaloneScopeClass = useStandaloneScopeClass();
11832
- const containerRef = useRef(null);
11833
- const handleMouseMove = useCallback((event, arc) => {
11834
- const bounds = containerRef.current?.getBoundingClientRect();
11835
- if (!bounds) return;
11836
- showTooltip({
11837
- tooltipData: arc.data,
11838
- tooltipLeft: event.clientX - bounds.left + tooltipOffsetX,
11839
- tooltipTop: event.clientY - bounds.top + tooltipOffsetY
11840
- });
11841
- }, [
11842
- showTooltip,
11843
- tooltipOffsetX,
11844
- tooltipOffsetY
11845
- ]);
11846
- const handleMouseLeave = useCallback(() => {
11847
- hideTooltip();
11848
- }, [hideTooltip]);
11849
- const handleArcMouseMove = useCallback((arc) => (event) => {
11850
- handleMouseMove(event, arc);
11851
- }, [handleMouseMove]);
11852
12345
  const { isValid, message } = validateData(data);
11853
12346
  const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
11854
12347
  const dataWithPercentages = useDataWithPercentages(data);
@@ -11882,7 +12375,31 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
11882
12375
  metadata: chartMetadata
11883
12376
  });
11884
12377
  const prefersReducedMotion = usePrefersReducedMotion();
12378
+ const wipeMask = animation && !prefersReducedMotion ? `url(#radial-wipe-${chartId})` : null;
11885
12379
  const effectiveWidth = propWidth || DEFAULT_WIDTH$1;
12380
+ const dataWithIndex = visibleData.map((d) => {
12381
+ const originalIndex = data.findIndex((item) => item.label === d.label);
12382
+ return {
12383
+ ...d,
12384
+ index: originalIndex >= 0 ? originalIndex : 0
12385
+ };
12386
+ });
12387
+ const startAngle = clockwise ? -Math.PI / 2 : Math.PI / 2;
12388
+ const endAngle = clockwise ? Math.PI / 2 : -Math.PI / 2;
12389
+ const arcs = pie({
12390
+ value: accessors.value,
12391
+ sort: accessors.sort,
12392
+ padAngle: PAD_ANGLE,
12393
+ startAngle,
12394
+ endAngle
12395
+ })(dataWithIndex);
12396
+ const navigationArcs = orderArcsForNavigation(arcs);
12397
+ const { chartRef, svgRef, selectedArc, getSegmentHandlers, getKeyboardTooltipAnchor, selectionOutputProps, chartProps } = usePieKeyboardNavigation({
12398
+ navigationArcs,
12399
+ withTooltips,
12400
+ tooltipOffsetX,
12401
+ tooltipOffsetY
12402
+ });
11886
12403
  if (!isValid) {
11887
12404
  const errorWidth = propHeight ? Math.min(propWidth || propHeight * 2, propHeight * 2) : effectiveWidth;
11888
12405
  const errorHeight = errorWidth / 2;
@@ -11901,15 +12418,6 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
11901
12418
  })
11902
12419
  });
11903
12420
  }
11904
- const dataWithIndex = visibleData.map((d) => {
11905
- const originalIndex = data.findIndex((item) => item.label === d.label);
11906
- return {
11907
- ...d,
11908
- index: originalIndex >= 0 ? originalIndex : 0
11909
- };
11910
- });
11911
- const startAngle = clockwise ? -Math.PI / 2 : Math.PI / 2;
11912
- const endAngle = clockwise ? Math.PI / 2 : -Math.PI / 2;
11913
12421
  const legendElement = showLegend && /* @__PURE__ */ jsx(Legend, {
11914
12422
  orientation: legend.orientation ?? "horizontal",
11915
12423
  position: legendPosition,
@@ -11942,52 +12450,60 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
11942
12450
  const height = width / 2;
11943
12451
  const radius = height;
11944
12452
  const innerRadius = radius * (1 - thickness);
12453
+ const path = arc({
12454
+ innerRadius,
12455
+ outerRadius: radius,
12456
+ cornerRadius: 3
12457
+ });
11945
12458
  return /* @__PURE__ */ jsxs(Center, {
11946
- ref: containerRef,
12459
+ ref: chartRef,
11947
12460
  className: pie_semi_circle_chart_module_default["pie-semi-circle-chart__plot"],
12461
+ ...chartProps,
12462
+ "aria-label": ariaLabel ?? __("Semi-circle chart", "jetpack-charts"),
11948
12463
  children: [/* @__PURE__ */ jsxs("svg", {
12464
+ ref: svgRef,
11949
12465
  width,
11950
12466
  height,
11951
12467
  viewBox: `0 0 ${width} ${height}`,
11952
- children: [/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(RadialWipeAnimation, {
11953
- id: `radial-wipe-${chartId}`,
11954
- radius,
11955
- innerRadius,
11956
- startAngle: "-180deg",
11957
- wipePercentage: 50
11958
- }) }), /* @__PURE__ */ jsx(Group, {
11959
- top: height,
11960
- left: width / 2,
11961
- mask: animation && !prefersReducedMotion ? `url(#radial-wipe-${chartId})` : null,
11962
- children: allSegmentsHidden ? /* @__PURE__ */ jsx(SvgEmptyState, {
11963
- x: 0,
11964
- y: -radius / 2,
11965
- width,
11966
- height,
11967
- children: getAllHiddenMessage(legendInteractive, "segments")
11968
- }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
11969
- /* @__PURE__ */ jsx(Pie, {
11970
- data: dataWithIndex,
11971
- pieValue: accessors.value,
11972
- outerRadius: radius,
11973
- innerRadius,
11974
- cornerRadius: 3,
11975
- padAngle: PAD_ANGLE,
11976
- startAngle,
11977
- endAngle,
11978
- pieSort: accessors.sort,
11979
- children: (pie) => {
11980
- return pie.arcs.map((arc) => /* @__PURE__ */ jsx("g", {
11981
- onMouseMove: withTooltips ? handleArcMouseMove(arc) : void 0,
11982
- onMouseLeave: withTooltips ? handleMouseLeave : void 0,
11983
- children: /* @__PURE__ */ jsx("path", {
11984
- d: pie.path(arc) || "",
11985
- fill: accessors.fill(arc.data)
11986
- })
11987
- }, arc.data.label));
11988
- }
11989
- }),
11990
- /* @__PURE__ */ jsxs(Group, { children: [/* @__PURE__ */ jsx(Text, {
12468
+ children: [
12469
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(RadialWipeAnimation, {
12470
+ id: `radial-wipe-${chartId}`,
12471
+ radius,
12472
+ innerRadius,
12473
+ startAngle: "-180deg",
12474
+ wipePercentage: 50
12475
+ }) }),
12476
+ /* @__PURE__ */ jsx(Group, {
12477
+ top: height,
12478
+ left: width / 2,
12479
+ mask: wipeMask,
12480
+ children: allSegmentsHidden ? /* @__PURE__ */ jsx(SvgEmptyState, {
12481
+ x: 0,
12482
+ y: -radius / 2,
12483
+ width,
12484
+ height,
12485
+ children: getAllHiddenMessage(legendInteractive, "segments")
12486
+ }) : arcs.map((arcDatum) => /* @__PURE__ */ jsx("g", {
12487
+ ...getSegmentHandlers(arcDatum.data, navigationArcs.indexOf(arcDatum)),
12488
+ children: /* @__PURE__ */ jsx("path", {
12489
+ d: path(arcDatum) || "",
12490
+ fill: accessors.fill(arcDatum.data)
12491
+ })
12492
+ }, arcDatum.data.label))
12493
+ }),
12494
+ selectedArc && /* @__PURE__ */ jsx(Group, {
12495
+ top: height,
12496
+ left: width / 2,
12497
+ children: /* @__PURE__ */ jsx(SelectedSegmentRing, {
12498
+ chartId,
12499
+ d: path(selectedArc) || ""
12500
+ })
12501
+ }),
12502
+ !allSegmentsHidden && /* @__PURE__ */ jsxs(Group, {
12503
+ top: height,
12504
+ left: width / 2,
12505
+ mask: wipeMask,
12506
+ children: [/* @__PURE__ */ jsxs(Group, { children: [/* @__PURE__ */ jsx(Text, {
11991
12507
  textAnchor: "middle",
11992
12508
  verticalAnchor: "start",
11993
12509
  y: -40,
@@ -11999,18 +12515,13 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
11999
12515
  y: -20,
12000
12516
  className: pie_semi_circle_chart_module_default.note,
12001
12517
  children: note
12002
- })] }),
12003
- !allSegmentsHidden && svgChildren
12004
- ] })
12005
- })]
12006
- }), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ jsx(BoundedTooltip, {
12007
- top: tooltipTop || 0,
12008
- left: tooltipLeft || 0,
12009
- children: /* @__PURE__ */ jsx("div", {
12010
- className: standaloneScopeClass,
12011
- role: "tooltip",
12012
- children: renderTooltip({ tooltipData })
12013
- })
12518
+ })] }), svgChildren]
12519
+ })
12520
+ ]
12521
+ }), /* @__PURE__ */ jsx(PieSelectionOutput, {
12522
+ ...selectionOutputProps,
12523
+ keyboardTooltipAnchor: selectedArc && getKeyboardTooltipAnchor(width / 2, height, path.centroid(selectedArc)),
12524
+ renderTooltip
12014
12525
  })]
12015
12526
  });
12016
12527
  }
@@ -12236,6 +12747,6 @@ function TrendIndicator({ direction, value, className, style, showIcon = true })
12236
12747
  });
12237
12748
  }
12238
12749
  //#endregion
12239
- export { AccessibleTooltip, AreaChartResponsive as AreaChart, AreaChart as AreaChartUnresponsive, BarChartResponsive as BarChart, BarChart as BarChartUnresponsive, BarListChartResponsive as BarListChart, BarListChart as BarListChartUnresponsive, BaseTooltip, ConversionFunnelChartWithProvider as ConversionFunnelChart, GeoChartResponsive as GeoChart, GeoChartWithProvider as GeoChartUnresponsive, GlobalChartsContext, GlobalChartsProvider, GlobalChartsProvider as ThemeProvider, GoogleDataTableColumnRoleType, HeatmapChartResponsive as HeatmapChart, HeatmapChart as HeatmapChartUnresponsive, LeaderboardChartResponsive as LeaderboardChart, LeaderboardChart as LeaderboardChartUnresponsive, Legend, LineChartResponsive as LineChart, LineChart as LineChartUnresponsive, PieChartResponsive as PieChart, PieChart as PieChartUnresponsive, PieSemiCircleChartResponsive as PieSemiCircleChart, PieSemiCircleChart as PieSemiCircleChartUnresponsive, Sparkline, SparklineUnresponsive, TrendIndicator, buildCalendarHeatmapData, buildMonthCalendarHeatmapData, defaultTheme, formatMetricValue, formatPercentage, getBucketInfo, getColorDistance, hexToRgba, isValidHexColor, lightenHexColor, mergeThemes, mixHexColors, normalizeColorToHex, parseAsLocalDate, parseHslString, prefersLightText, relativeLuminance, resolveCssVariable, useCalendarHeatmapData, useChartFormatting, useChartLegendItems, useChartRegistration, useChartScopeElement, useGlobalChartsContext, useGlobalChartsTheme, useLeaderboardLegendItems, useMonthCalendarHeatmapData, validateHexColor };
12750
+ export { AccessibleTooltip, AreaChartResponsive as AreaChart, AreaChart as AreaChartUnresponsive, BarChartResponsive as BarChart, BarChart as BarChartUnresponsive, BarListChartResponsive as BarListChart, BarListChart as BarListChartUnresponsive, BaseTooltip, ConversionFunnelChartWithProvider as ConversionFunnelChart, GeoChartResponsive as GeoChart, GeoChartWithProvider as GeoChartUnresponsive, GlobalChartsContext, GlobalChartsProvider, GlobalChartsProvider as ThemeProvider, GoogleDataTableColumnRoleType, HeatmapChartResponsive as HeatmapChart, HeatmapChart as HeatmapChartUnresponsive, LeaderboardChartResponsive as LeaderboardChart, LeaderboardChart as LeaderboardChartUnresponsive, Legend, LineChartResponsive as LineChart, LineChart as LineChartUnresponsive, PieChartResponsive as PieChart, PieChart as PieChartUnresponsive, PieSemiCircleChartResponsive as PieSemiCircleChart, PieSemiCircleChart as PieSemiCircleChartUnresponsive, Sparkline, SparklineUnresponsive, TooltipBox, TrendIndicator, XYChartTooltip, buildCalendarHeatmapData, buildMonthCalendarHeatmapData, defaultTheme, formatMetricValue, formatPercentage, getBucketInfo, getColorDistance, hexToRgba, isValidHexColor, lightenHexColor, mergeThemes, mixHexColors, normalizeColorToHex, parseAsLocalDate, parseHslString, prefersLightText, relativeLuminance, resolveCssVariable, useCalendarHeatmapData, useChartFormatting, useChartLegendItems, useChartRegistration, useChartScopeElement, useGlobalChartsContext, useGlobalChartsTheme, useLeaderboardLegendItems, useMonthCalendarHeatmapData, validateHexColor };
12240
12751
 
12241
12752
  //# sourceMappingURL=index.js.map