@automattic/charts 4.12.0 → 4.13.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 (39) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/index.cjs +641 -636
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.css +40 -12
  5. package/dist/index.d.cts +26 -121
  6. package/dist/index.d.ts +26 -121
  7. package/dist/index.js +630 -613
  8. package/dist/index.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/charts/area-chart/area-chart.tsx +16 -6
  11. package/src/charts/area-chart/test/area-chart.test.tsx +42 -9
  12. package/src/charts/bar-chart/bar-chart.tsx +17 -12
  13. package/src/charts/bar-chart/private/index.ts +1 -1
  14. package/src/charts/bar-chart/private/slot-tooltip-members.tsx +4 -5
  15. package/src/charts/bar-chart/private/use-bar-stops.ts +1 -3
  16. package/src/charts/bar-chart/private/use-overlap-slots.ts +35 -16
  17. package/src/charts/bar-chart/test/bar-chart.test.tsx +115 -0
  18. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +24 -11
  19. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +235 -182
  20. package/src/charts/conversion-funnel-chart/index.ts +2 -0
  21. package/src/charts/conversion-funnel-chart/private/index.ts +1 -0
  22. package/src/charts/conversion-funnel-chart/private/use-funnel-selection.ts +9 -47
  23. package/src/charts/conversion-funnel-chart/private/use-roving-step-focus.ts +83 -0
  24. package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +312 -92
  25. package/src/charts/conversion-funnel-chart/test/use-funnel-selection.test.ts +23 -188
  26. package/src/charts/conversion-funnel-chart/types.ts +22 -0
  27. package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +41 -1
  28. package/src/charts/leaderboard-chart/leaderboard-chart.tsx +101 -30
  29. package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +47 -0
  30. package/src/charts/line-chart/line-chart.tsx +10 -8
  31. package/src/charts/line-chart/test/line-chart.test.tsx +75 -0
  32. package/src/components/tooltip/private/at-nearest-date.ts +49 -0
  33. package/src/components/tooltip/private/keyboard-stops.ts +67 -0
  34. package/src/components/tooltip/private/xy-chart-tooltip-overlay.tsx +10 -2
  35. package/src/components/tooltip/test/keyboard-stops.test.ts +36 -0
  36. package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +135 -1
  37. package/src/components/tooltip/xy-chart-tooltip.tsx +8 -12
  38. package/src/index.ts +2 -0
  39. package/src/types.ts +4 -3
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region \0rolldown/runtime.js
2
+ // \0rolldown/runtime.js
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -21,7 +21,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  value: mod,
22
22
  enumerable: true
23
23
  }) : target, mod));
24
- //#endregion
25
24
  let _automattic_number_formatters = require("@automattic/number-formatters");
26
25
  let _visx_xychart = require("@visx/xychart");
27
26
  let _wordpress_i18n = require("@wordpress/i18n");
@@ -55,25 +54,22 @@ dompurify = __toESM(dompurify, 1);
55
54
  require("@babel/runtime/helpers/esm/extends");
56
55
  let _wordpress_icons = require("@wordpress/icons");
57
56
  let _visx_shape = require("@visx/shape");
58
- //#region src/charts/private/chart-instance-context/chart-instance-context.ts
57
+ // src/charts/private/chart-instance-context/chart-instance-context.ts
59
58
  const ChartInstanceContext = (0, react.createContext)(null);
60
- //#endregion
61
- //#region src/charts/private/chart-instance-context/use-chart-instance-context.ts
59
+ // src/charts/private/chart-instance-context/use-chart-instance-context.ts
62
60
  const useChartInstanceContext = () => {
63
61
  const context = (0, react.useContext)(ChartInstanceContext);
64
62
  if (!context) throw new Error("useChartInstanceContext must be used within a Chart component");
65
63
  return context;
66
64
  };
67
- //#endregion
68
- //#region src/styles/chart-scope-class.ts
65
+ // src/styles/chart-scope-class.ts
69
66
  /**
70
67
  * Stable class that carries the `--a8c-charts-*` catalog. Applied to the `GlobalChartsProvider` wrapper, to portal-rendered surfaces (which sit outside the provider tree), and to standalone components when no provider is above them.
71
68
  *
72
69
  * Deliberately unhashed: consumers are documented as being able to target it to override a token on the provider element.
73
70
  */
74
71
  const CHART_SCOPE_CLASS = "a8c-charts-scope";
75
- //#endregion
76
- //#region src/utils/create-composition.ts
72
+ // src/utils/create-composition.ts
77
73
  /**
78
74
  * Utility function to create chart components with composition API.
79
75
  *
@@ -87,8 +83,7 @@ const CHART_SCOPE_CLASS = "a8c-charts-scope";
87
83
  function attachSubComponents(Chart, subComponents) {
88
84
  return Object.assign(Chart, subComponents);
89
85
  }
90
- //#endregion
91
- //#region src/utils/warn-once.ts
86
+ // src/utils/warn-once.ts
92
87
  const warned = /* @__PURE__ */ new Set();
93
88
  /**
94
89
  * Warns about a host-supplied value once per process, and never in production.
@@ -101,8 +96,7 @@ const warnOnce = (key, message) => {
101
96
  warned.add(key);
102
97
  console.warn(`[Charts] ${message}`);
103
98
  };
104
- //#endregion
105
- //#region src/utils/date-parsing.ts
99
+ // src/utils/date-parsing.ts
106
100
  /**
107
101
  * @file Date parsing: a naive string is dated in a supplied IANA zone, or the runtime's own
108
102
  *
@@ -197,8 +191,7 @@ const parseAsLocalDate = (dateString, timeZone) => {
197
191
  }
198
192
  return /* @__PURE__ */ new Date(NaN);
199
193
  };
200
- //#endregion
201
- //#region src/utils/bucket-info.ts
194
+ // src/utils/bucket-info.ts
202
195
  const getInstant = (point) => {
203
196
  if (!point) return;
204
197
  if ("date" in point && point.date) return point.date.getTime();
@@ -230,8 +223,7 @@ const getBucketInfo = (data, tickResolution) => ({
230
223
  bucket: tickResolution ?? getBucketResolution(data),
231
224
  displayResolution: getBucketResolution(data, tickResolution)
232
225
  });
233
- //#endregion
234
- //#region src/utils/format-metric-value.ts
226
+ // src/utils/format-metric-value.ts
235
227
  /**
236
228
  * Format a numeric metric value based on type, precision and scale.
237
229
  * Supports currency, number and percentage, using `@automattic/number-formatters`.
@@ -280,8 +272,7 @@ const formatMetricValue = (value, type = "number", { decimals, useMultipliers =
280
272
  });
281
273
  }
282
274
  };
283
- //#endregion
284
- //#region src/utils/format-percentage.ts
275
+ // src/utils/format-percentage.ts
285
276
  /**
286
277
  * Format a percentage value with smart decimal handling.
287
278
  * Uses `@automattic/number-formatters` for consistent formatting.
@@ -297,8 +288,7 @@ const formatPercentage = (value) => {
297
288
  maximumFractionDigits: 2
298
289
  } });
299
290
  };
300
- //#endregion
301
- //#region src/utils/get-edge-tick-widths.ts
291
+ // src/utils/get-edge-tick-widths.ts
302
292
  /**
303
293
  * Rendered widths of the first and last tick labels on an axis.
304
294
  *
@@ -322,8 +312,7 @@ const getEdgeTickWidths = (ticks, formatTick, labelStyle) => {
322
312
  last: (0, _visx_text.getStringWidth)(label(ticks[lastIndex], lastIndex), labelStyle) ?? 0
323
313
  };
324
314
  };
325
- //#endregion
326
- //#region src/utils/get-longest-tick-width.ts
315
+ // src/utils/get-longest-tick-width.ts
327
316
  /**
328
317
  * Returns the width of the longest tick.
329
318
  *
@@ -337,8 +326,7 @@ const getLongestTickWidth = (ticks, formatTick, labelStyle) => {
337
326
  const longestTick = formattedTicks.reduce((longest, current) => longest.length >= current.length ? longest : current, formattedTicks[0]);
338
327
  return (0, _visx_text.getStringWidth)(longestTick, labelStyle);
339
328
  };
340
- //#endregion
341
- //#region src/utils/get-styles.ts
329
+ // src/utils/get-styles.ts
342
330
  /**
343
331
  * Utility function to get consolidated line styles for a series
344
332
  * This consolidates the logic used by both LineChart and Legend components
@@ -391,19 +379,16 @@ function getItemShapeStyles(series, index, theme, legendShape) {
391
379
  ...barShapeStyles
392
380
  };
393
381
  }
394
- //#endregion
395
- //#region src/utils/is-safari.ts
382
+ // src/utils/is-safari.ts
396
383
  const isSafari = () => {
397
384
  if (typeof navigator !== "undefined" && navigator.userAgent) return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
398
385
  return false;
399
386
  };
400
- //#endregion
401
- //#region src/utils/merge-themes.ts
387
+ // src/utils/merge-themes.ts
402
388
  function mergeThemes(baseTheme, overrideTheme) {
403
389
  return (0, deepmerge.default)(baseTheme, overrideTheme, { arrayMerge: (_destinationArray, sourceArray) => sourceArray });
404
390
  }
405
- //#endregion
406
- //#region src/utils/color-utils.ts
391
+ // src/utils/color-utils.ts
407
392
  /**
408
393
  * Check if a value is a valid 6-digit hex color
409
394
  * @param hex - The value to check
@@ -570,8 +555,7 @@ const prefersLightText = (backgroundHex) => {
570
555
  if (!isValidHexColor(backgroundHex)) return false;
571
556
  return relativeLuminance(backgroundHex) <= .179;
572
557
  };
573
- //#endregion
574
- //#region src/utils/resolve-css-var.ts
558
+ // src/utils/resolve-css-var.ts
575
559
  /**
576
560
  * Pattern for valid CSS custom property names (e.g., '--my-color', '--jp-gray-10')
577
561
  */
@@ -668,8 +652,7 @@ function readCustomProperty(varName, styles) {
668
652
  return null;
669
653
  }
670
654
  }
671
- //#endregion
672
- //#region src/utils/resolve-font-size.ts
655
+ // src/utils/resolve-font-size.ts
673
656
  const toFontSize = (size) => Number.isFinite(size) && size >= 0 ? size : void 0;
674
657
  /**
675
658
  * Resolve a theme `fontSize` value into a plain number suitable for
@@ -696,8 +679,7 @@ const resolveFontSize = (val) => {
696
679
  return match ? toFontSize(parseFloat(match[1])) : void 0;
697
680
  }
698
681
  };
699
- //#endregion
700
- //#region src/utils/date-formatting.ts
682
+ // src/utils/date-formatting.ts
701
683
  const formatters = /* @__PURE__ */ new Map();
702
684
  const getFormatter$1 = (options, { locale, timeZone }) => {
703
685
  const key = `${locale ?? ""}|${timeZone ?? ""}|${JSON.stringify(options)}`;
@@ -796,8 +778,7 @@ const createZonedClock = (timeZone) => {
796
778
  };
797
779
  };
798
780
  };
799
- //#endregion
800
- //#region src/providers/chart-scope/chart-scope-context.ts
781
+ // src/providers/chart-scope/chart-scope-context.ts
801
782
  /**
802
783
  * The nearest chart element, published so JS token resolution reads the same CSS cascade that paints the chart's own colours.
803
784
  *
@@ -814,8 +795,7 @@ const seriesRole = (slot) => `--a8c-charts-color-series-${slot}`;
814
795
  const SERIES_SLOT_1_FALLBACK = "#3858e9";
815
796
  /** The catalog pointer for every slot, in slot order. */
816
797
  const SERIES_PALETTE_POINTERS = Array.from({ length: 5 }, (_, index) => index === 0 ? `var(${seriesRole(1)}, ${SERIES_SLOT_1_FALLBACK})` : `var(${seriesRole(index + 1)})`);
817
- //#endregion
818
- //#region src/providers/chart-context/private/catalog-pointers.ts
798
+ // src/providers/chart-context/private/catalog-pointers.ts
819
799
  /** Terminal literals the provider also generates from before its first read, so SSR and the first client render agree. */
820
800
  const BACKGROUND_FALLBACK = "#ffffff";
821
801
  const LABEL_FALLBACK = "#1e1e1e";
@@ -855,8 +835,7 @@ const ANNOTATION_POINTERS = {
855
835
  radius: 5
856
836
  }
857
837
  };
858
- //#endregion
859
- //#region src/providers/chart-context/private/perceptual-color.ts
838
+ // src/providers/chart-context/private/perceptual-color.ts
860
839
  const DEUTERANOPIA = [
861
840
  .367322,
862
841
  .860646,
@@ -1262,16 +1241,14 @@ const buildPaletteGenerator = (normalizedSeeds, background, labelColors) => {
1262
1241
  return palette[index].hex;
1263
1242
  };
1264
1243
  };
1265
- //#endregion
1266
- //#region src/providers/chart-context/private/resolve-opaque-hex.ts
1244
+ // src/providers/chart-context/private/resolve-opaque-hex.ts
1267
1245
  const resolveOpaqueHex = (pointer, resolve) => {
1268
1246
  const raw = resolve(pointer);
1269
1247
  if (!raw || (0, _visx_vendor_d3_color.color)(raw)?.opacity !== 1) return null;
1270
1248
  const hex = normalizeColorToHex(raw);
1271
1249
  return isValidHexColor(hex) ? hex : null;
1272
1250
  };
1273
- //#endregion
1274
- //#region src/providers/chart-context/themes.ts
1251
+ // src/providers/chart-context/themes.ts
1275
1252
  /**
1276
1253
  * Default theme configuration: the shape and spacing a consumer can override.
1277
1254
  *
@@ -1314,8 +1291,7 @@ const defaultTheme = {
1314
1291
  groupGap: 24
1315
1292
  }
1316
1293
  };
1317
- //#endregion
1318
- //#region src/providers/chart-context/global-charts-provider.tsx
1294
+ // src/providers/chart-context/global-charts-provider.tsx
1319
1295
  const PLACEHOLDER_LABEL_COLORS = [LABEL_FALLBACK, LABEL_INVERSE_FALLBACK];
1320
1296
  const GlobalChartsContext = (0, react.createContext)(null);
1321
1297
  const GlobalChartsProvider = ({ children, theme, locale, timeZone }) => {
@@ -1496,21 +1472,18 @@ const GlobalChartsProvider = ({ children, theme, locale, timeZone }) => {
1496
1472
  })
1497
1473
  });
1498
1474
  };
1499
- //#endregion
1500
- //#region src/providers/chart-context/hooks/use-global-charts-context.ts
1475
+ // src/providers/chart-context/hooks/use-global-charts-context.ts
1501
1476
  const useGlobalChartsContext = () => {
1502
1477
  const context = (0, react.useContext)(GlobalChartsContext);
1503
1478
  if (!context) throw new Error("useGlobalChartsContext must be used within a GlobalChartsProvider");
1504
1479
  return context;
1505
1480
  };
1506
- //#endregion
1507
- //#region src/providers/chart-context/hooks/use-chart-id.ts
1481
+ // src/providers/chart-context/hooks/use-chart-id.ts
1508
1482
  const useChartId = (providedId) => {
1509
1483
  const generatedId = (0, react.useId)();
1510
1484
  return providedId || generatedId;
1511
1485
  };
1512
- //#endregion
1513
- //#region src/hooks/use-deep-memo.ts
1486
+ // src/hooks/use-deep-memo.ts
1514
1487
  var import_fast_deep_equal = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
1515
1488
  module.exports = function equal(a, b) {
1516
1489
  if (a === b) return true;
@@ -1551,16 +1524,14 @@ const useDeepMemo = (value) => {
1551
1524
  if (!(0, import_fast_deep_equal.default)(ref.current, value)) ref.current = value;
1552
1525
  return ref.current;
1553
1526
  };
1554
- //#endregion
1555
- //#region src/providers/chart-scope/use-chart-scope-element.ts
1527
+ // src/providers/chart-scope/use-chart-scope-element.ts
1556
1528
  /**
1557
1529
  * Returns the nearest chart scope element, or `null` when rendered outside any scope (and during SSR, before the ref is attached).
1558
1530
  *
1559
1531
  * @return {HTMLElement | null} The nearest chart scope element, or `null`.
1560
1532
  */
1561
1533
  const useChartScopeElement = () => (0, react.useContext)(ChartScopeContext);
1562
- //#endregion
1563
- //#region src/providers/chart-scope/use-standalone-scope-class.ts
1534
+ // src/providers/chart-scope/use-standalone-scope-class.ts
1564
1535
  /**
1565
1536
  * Returns the catalog class when there is no `GlobalChartsProvider` above this component, and `undefined` when there is.
1566
1537
  *
@@ -1569,8 +1540,7 @@ const useChartScopeElement = () => (0, react.useContext)(ChartScopeContext);
1569
1540
  * @return The scope class name, or undefined when a provider is present.
1570
1541
  */
1571
1542
  const useStandaloneScopeClass = () => (0, react.useContext)(GlobalChartsContext) ? void 0 : CHART_SCOPE_CLASS;
1572
- //#endregion
1573
- //#region src/hooks/use-xychart-theme.ts
1543
+ // src/hooks/use-xychart-theme.ts
1574
1544
  const STARTS_LIKE_A_NUMBER = /^[+-]?[\d.]/;
1575
1545
  const NON_NEGATIVE_CSS_NUMBER = /^\+?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:[a-z]+|%)?$/i;
1576
1546
  const isRenderableFontSize = (fontSize) => {
@@ -1626,8 +1596,7 @@ const useXYChartTheme = (data) => {
1626
1596
  scopeElement
1627
1597
  ]);
1628
1598
  };
1629
- //#endregion
1630
- //#region src/providers/chart-context/hooks/use-chart-formatting.ts
1599
+ // src/providers/chart-context/hooks/use-chart-formatting.ts
1631
1600
  const RUNTIME_FORMATTING = {};
1632
1601
  /**
1633
1602
  * The locale and time zone dates are rendered in, as set on `GlobalChartsProvider`.
@@ -1641,8 +1610,7 @@ const RUNTIME_FORMATTING = {};
1641
1610
  const useChartFormatting = () => {
1642
1611
  return (0, react.useContext)(GlobalChartsContext)?.formatting ?? RUNTIME_FORMATTING;
1643
1612
  };
1644
- //#endregion
1645
- //#region src/hooks/use-chart-data-transform.ts
1613
+ // src/hooks/use-chart-data-transform.ts
1646
1614
  /**
1647
1615
  * Hook that transforms and sorts chart data, handling date parsing and sorting
1648
1616
  *
@@ -1677,8 +1645,7 @@ const useChartDataTransform = (data) => {
1677
1645
  }));
1678
1646
  }, [data, timeZone]);
1679
1647
  };
1680
- //#endregion
1681
- //#region src/hooks/use-chart-margin.tsx
1648
+ // src/hooks/use-chart-margin.tsx
1682
1649
  /**
1683
1650
  * Base top margin used when no dynamic adjustments are necessary.
1684
1651
  */
@@ -1800,8 +1767,7 @@ const useChartMargin = (height, options, data, theme, horizontal = false) => {
1800
1767
  yTicks
1801
1768
  ]);
1802
1769
  };
1803
- //#endregion
1804
- //#region src/hooks/use-element-size.ts
1770
+ // src/hooks/use-element-size.ts
1805
1771
  /**
1806
1772
  * Hook to measure the width and height of a DOM element.
1807
1773
  * Returns a ref callback to attach to the element and the current dimensions in pixels.
@@ -1838,8 +1804,7 @@ function useElementSize({ initialWidth = 0, initialHeight = 0 } = {}) {
1838
1804
  height
1839
1805
  ];
1840
1806
  }
1841
- //#endregion
1842
- //#region src/hooks/use-text-truncation.ts
1807
+ // src/hooks/use-text-truncation.ts
1843
1808
  /**
1844
1809
  * Hook to detect if text content is truncated within its container.
1845
1810
  * Uses ResizeObserver to dynamically track changes in element size.
@@ -1880,8 +1845,7 @@ function useTextTruncation(enabled = true) {
1880
1845
  } else setIsTruncated(false);
1881
1846
  }, [enabled]), isTruncated];
1882
1847
  }
1883
- //#endregion
1884
- //#region src/hooks/use-zero-value-display.ts
1848
+ // src/hooks/use-zero-value-display.ts
1885
1849
  /**
1886
1850
  * Minimum pixel size for near-zero bars (non-zero values that would render too small).
1887
1851
  * Using 3px to be visible but not misleading - larger values might look like actual data.
@@ -1921,8 +1885,7 @@ const useZeroValueDisplay = (data, options = { enabled: false }) => {
1921
1885
  valueAxisLength
1922
1886
  ]);
1923
1887
  };
1924
- //#endregion
1925
- //#region src/hooks/use-data-with-percentages.ts
1888
+ // src/hooks/use-data-with-percentages.ts
1926
1889
  /**
1927
1890
  * Hook to calculate percentages from values for chart data.
1928
1891
  * Ensures percentages are always derived from values (single source of truth).
@@ -1939,8 +1902,7 @@ const useDataWithPercentages = (data) => {
1939
1902
  }));
1940
1903
  }, [data]);
1941
1904
  };
1942
- //#endregion
1943
- //#region src/hooks/use-legend-visibility-data.ts
1905
+ // src/hooks/use-legend-visibility-data.ts
1944
1906
  /**
1945
1907
  * Custom hook to filter and recalculate chart data based on series visibility.
1946
1908
  *
@@ -2012,8 +1974,7 @@ const useLegendVisibilityData = ({ data, chartId, isSeriesVisible }) => {
2012
1974
  ])
2013
1975
  };
2014
1976
  };
2015
- //#endregion
2016
- //#region src/hooks/use-prefers-reduced-motion.ts
1977
+ // src/hooks/use-prefers-reduced-motion.ts
2017
1978
  const QUERY = "(prefers-reduced-motion: no-preference)";
2018
1979
  const getInitialState = () => !window.matchMedia(QUERY).matches;
2019
1980
  /**
@@ -2034,11 +1995,9 @@ function usePrefersReducedMotion() {
2034
1995
  }, []);
2035
1996
  return prefersReducedMotion;
2036
1997
  }
2037
- //#endregion
2038
- //#region src/hooks/use-isomorphic-layout-effect.ts
1998
+ // src/hooks/use-isomorphic-layout-effect.ts
2039
1999
  const useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
2040
- //#endregion
2041
- //#region src/providers/chart-context/hooks/use-chart-registration.ts
2000
+ // src/providers/chart-context/hooks/use-chart-registration.ts
2042
2001
  const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, metadata }) => {
2043
2002
  const { registerChart, unregisterChart } = useGlobalChartsContext();
2044
2003
  const stableLegendItems = useDeepMemo(legendItems);
@@ -2060,8 +2019,7 @@ const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, me
2060
2019
  isDataValid
2061
2020
  ]);
2062
2021
  };
2063
- //#endregion
2064
- //#region src/providers/chart-context/hooks/use-global-charts-theme.ts
2022
+ // src/providers/chart-context/hooks/use-global-charts-theme.ts
2065
2023
  /**
2066
2024
  * Hook to get the global chart theme from GlobalChartsProvider
2067
2025
  *
@@ -2070,8 +2028,7 @@ const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, me
2070
2028
  const useGlobalChartsTheme = () => {
2071
2029
  return (0, react.useContext)(GlobalChartsContext)?.theme ?? defaultTheme;
2072
2030
  };
2073
- //#endregion
2074
- //#region src/components/legend/utils/value-or-identity.ts
2031
+ // src/components/legend/utils/value-or-identity.ts
2075
2032
  /**
2076
2033
  * Returns an object's value if defined, or the object.
2077
2034
  * @param _ - The object to return the value of.
@@ -2089,8 +2046,7 @@ function valueOrIdentity(_) {
2089
2046
  function valueOrIdentityString(_) {
2090
2047
  return String(valueOrIdentity(_));
2091
2048
  }
2092
- //#endregion
2093
- //#region src/components/legend/private/base-legend.module.scss
2049
+ // src/components/legend/private/base-legend.module.scss
2094
2050
  var base_legend_module_default = {
2095
2051
  "legend": "a8ccharts-04TogW-legend",
2096
2052
  "legend--horizontal": "a8ccharts-04TogW-legend--horizontal",
@@ -2102,8 +2058,7 @@ var base_legend_module_default = {
2102
2058
  "legend-item-text--wrap": "a8ccharts-04TogW-legend-item-text--wrap",
2103
2059
  "legend-item-value": "a8ccharts-04TogW-legend-item-value"
2104
2060
  };
2105
- //#endregion
2106
- //#region src/components/legend/private/base-legend.tsx
2061
+ // src/components/legend/private/base-legend.tsx
2107
2062
  const ALIGNMENT_TO_FLEX = {
2108
2063
  start: "flex-start",
2109
2064
  center: "center",
@@ -2268,8 +2223,7 @@ const BaseLegend = (0, react.forwardRef)(({ items: allItems, className, orientat
2268
2223
  })
2269
2224
  });
2270
2225
  });
2271
- //#endregion
2272
- //#region src/components/legend/legend.tsx
2226
+ // src/components/legend/legend.tsx
2273
2227
  const defaultShapeByChartType = {
2274
2228
  area: "rect",
2275
2229
  line: "line",
@@ -2295,8 +2249,7 @@ const Legend = (0, react.forwardRef)(({ chartId, items, shape, ...props }, ref)
2295
2249
  chartId: contextChartId
2296
2250
  });
2297
2251
  });
2298
- //#endregion
2299
- //#region src/components/legend/hooks/use-chart-legend-items.ts
2252
+ // src/components/legend/hooks/use-chart-legend-items.ts
2300
2253
  /**
2301
2254
  * Wraps `getElementStyles` so a swatch takes the color given for its series.
2302
2255
  * @param getElementStyles - Function to get element styles
@@ -2552,15 +2505,13 @@ function useChartLegendItems(data, options = {}, legendShape) {
2552
2505
  legendShape
2553
2506
  ]);
2554
2507
  }
2555
- //#endregion
2556
- //#region src/components/tooltip/private/label-value-content.tsx
2508
+ // src/components/tooltip/private/label-value-content.tsx
2557
2509
  const LabelValueContent = ({ data }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2558
2510
  data.label,
2559
2511
  ": ",
2560
2512
  data.valueDisplay || (0, _automattic_number_formatters.formatNumber)(data.value)
2561
2513
  ] });
2562
- //#endregion
2563
- //#region src/components/tooltip/private/tooltip-theme.tsx
2514
+ // src/components/tooltip/private/tooltip-theme.tsx
2564
2515
  const DEFAULT_SURFACE = "#1e1e1e";
2565
2516
  const TOOLTIP_SURFACE = `var(--a8c-charts-color-tooltip-surface, ${DEFAULT_SURFACE})`;
2566
2517
  const toSeed = (value) => {
@@ -2583,11 +2534,9 @@ const TooltipTheme = ({ children }) => {
2583
2534
  children
2584
2535
  });
2585
2536
  };
2586
- //#endregion
2587
- //#region src/components/tooltip/tooltip-box.module.scss
2537
+ // src/components/tooltip/tooltip-box.module.scss
2588
2538
  var tooltip_box_module_default = { "surface": "a8ccharts-ddpU1W-surface" };
2589
- //#endregion
2590
- //#region src/components/tooltip/tooltip-box.tsx
2539
+ // src/components/tooltip/tooltip-box.tsx
2591
2540
  /**
2592
2541
  * The chart tooltip box: the dark surface every chart tooltip draws. It does not position itself; place it with `style` or a wrapper.
2593
2542
  *
@@ -2607,8 +2556,7 @@ const TooltipBox = (0, react.forwardRef)(({ unstyled = false, role = "tooltip",
2607
2556
  return unstyled ? box : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTheme, { children: box });
2608
2557
  });
2609
2558
  TooltipBox.displayName = "TooltipBox";
2610
- //#endregion
2611
- //#region src/components/tooltip/base-tooltip.tsx
2559
+ // src/components/tooltip/base-tooltip.tsx
2612
2560
  /**
2613
2561
  * A tooltip box with children or `label: value` content. Prefer `TooltipBox`.
2614
2562
  *
@@ -2642,6 +2590,80 @@ const BaseTooltip = ({ data, top, left, component: Component = LabelValueContent
2642
2590
  children: content
2643
2591
  });
2644
2592
  };
2593
+ // src/components/tooltip/private/keyboard-stops.ts
2594
+ const timeOf$1 = (point) => point?.date?.getTime();
2595
+ const getXPositions = (series) => {
2596
+ const positions = /* @__PURE__ */ new Set();
2597
+ for (const { data } of series) for (const point of data) {
2598
+ const time = timeOf$1(point);
2599
+ if (time !== void 0) positions.add(time);
2600
+ }
2601
+ return [...positions].sort((a, b) => a - b);
2602
+ };
2603
+ /**
2604
+ * Keyboard stops over the series: the sorted union of their dates, or array indexes when no point has a date.
2605
+ *
2606
+ * Once any point has a date, a series of undated points has no stop.
2607
+ *
2608
+ * @param series - The series to step through.
2609
+ * @return The stop count, and each series' point at a stop.
2610
+ */
2611
+ const getKeyboardStops = (series) => {
2612
+ const positions = getXPositions(series);
2613
+ if (positions.length === 0) return {
2614
+ count: Math.max(0, ...series.map(({ data }) => data.length)),
2615
+ membersAt: (stop) => series.flatMap((s) => stop < s.data.length ? [{
2616
+ series: s,
2617
+ datum: s.data[stop],
2618
+ index: stop
2619
+ }] : [])
2620
+ };
2621
+ return {
2622
+ count: positions.length,
2623
+ membersAt: (stop) => {
2624
+ const time = positions[stop];
2625
+ if (time === void 0) return [];
2626
+ return series.flatMap((s) => {
2627
+ const index = s.data.findIndex((point) => timeOf$1(point) === time);
2628
+ return index === -1 ? [] : [{
2629
+ series: s,
2630
+ datum: s.data[index],
2631
+ index
2632
+ }];
2633
+ });
2634
+ }
2635
+ };
2636
+ };
2637
+ // src/components/tooltip/private/at-nearest-date.ts
2638
+ const timeOf = (datum) => datum.date?.getTime();
2639
+ /**
2640
+ * Lists every registered series at the nearest datum's date, each with its own point there.
2641
+ *
2642
+ * The pointer hands each series its own nearest point, which for a series that skips that date, or that the pointer sits nearer another date of, is a neighbor's.
2643
+ *
2644
+ * @param tooltipData - The tooltip data visx collected.
2645
+ * @param registry - The chart's data registry.
2646
+ * @return The tooltip data, unchanged when the nearest datum has no date.
2647
+ */
2648
+ const atNearestDate = (tooltipData, registry) => {
2649
+ const nearest = tooltipData?.nearestDatum?.datum;
2650
+ const time = nearest ? timeOf(nearest) : void 0;
2651
+ if (!tooltipData || time === void 0) return tooltipData;
2652
+ const datumByKey = {};
2653
+ for (const { key, data } of registry?.entries() ?? []) {
2654
+ const index = data.findIndex((datum) => timeOf(datum) === time);
2655
+ if (index !== -1) datumByKey[key] = {
2656
+ key,
2657
+ index,
2658
+ datum: data[index]
2659
+ };
2660
+ }
2661
+ for (const [key, entry] of Object.entries(tooltipData.datumByKey)) if (!datumByKey[key] && timeOf(entry.datum) === time) datumByKey[key] = entry;
2662
+ return {
2663
+ ...tooltipData,
2664
+ datumByKey
2665
+ };
2666
+ };
2645
2667
  const POINTER_HEIGHT = 6;
2646
2668
  const clamp = (position, min, max, size) => Math.min(Math.max(position, min), Math.max(min, max - size));
2647
2669
  const isClipping = (element) => {
@@ -2820,8 +2842,7 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = 10, offsetTop = 10, st
2820
2842
  }), children]
2821
2843
  });
2822
2844
  };
2823
- //#endregion
2824
- //#region src/components/tooltip/private/xy-chart-tooltip-overlay.tsx
2845
+ // src/components/tooltip/private/xy-chart-tooltip-overlay.tsx
2825
2846
  const CROSSHAIR_STROKE_WIDTH = 1.5;
2826
2847
  const CROSSHAIR_PAINT_PROPERTIES = /* @__PURE__ */ new Set([
2827
2848
  "stroke",
@@ -3006,18 +3027,21 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
3006
3027
  */
3007
3028
  const XyChartTooltipOverlay = (props) => {
3008
3029
  const tooltipContext = (0, react.useContext)(_visx_xychart.TooltipContext);
3030
+ const dataRegistry = (0, react.useContext)(_visx_xychart.DataContext)?.dataRegistry;
3009
3031
  const [container, setContainer] = (0, react.useState)(null);
3010
3032
  const anchorRef = (0, react.useCallback)((node) => {
3011
3033
  setContainer(node?.ownerSVGElement?.parentElement ?? null);
3012
3034
  }, []);
3013
3035
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("g", { ref: anchorRef }), tooltipContext?.tooltipOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(XyChartTooltipContent, {
3014
3036
  ...props,
3015
- tooltipContext,
3037
+ tooltipContext: {
3038
+ ...tooltipContext,
3039
+ tooltipData: atNearestDate(tooltipContext.tooltipData, dataRegistry)
3040
+ },
3016
3041
  container
3017
3042
  })] });
3018
3043
  };
3019
- //#endregion
3020
- //#region src/components/tooltip/xy-chart-tooltip.tsx
3044
+ // src/components/tooltip/xy-chart-tooltip.tsx
3021
3045
  const XYChartTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", verticalCrosshairStyle, horizontalCrosshairStyle, ...props }) => {
3022
3046
  const tooltipContext = (0, react.useContext)(_visx_xychart.TooltipContext);
3023
3047
  const scopeElement = useChartScopeElement();
@@ -3042,6 +3066,7 @@ const XYChartTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocu
3042
3066
  }
3043
3067
  return flattened;
3044
3068
  }, [series, mode]);
3069
+ const stops = (0, react.useMemo)(() => getKeyboardStops(series), [series]);
3045
3070
  const hasKeyboardSelection = (0, react.useRef)(false);
3046
3071
  const closeTooltipNow = (0, react.useCallback)(() => {
3047
3072
  tooltipContext?.updateTooltip({
@@ -3075,19 +3100,20 @@ const XYChartTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocu
3075
3100
  hasKeyboardSelection.current = true;
3076
3101
  if (mode === "group") {
3077
3102
  closeTooltipNow();
3078
- series.forEach((s, index) => {
3079
- if (selectedIndex < s.data.length) {
3080
- const datum = s.data[selectedIndex];
3081
- tooltipContext?.showTooltip({
3082
- datum,
3083
- key: s.label,
3084
- index
3085
- });
3086
- }
3103
+ stops.membersAt(selectedIndex).forEach(({ series: member, datum, index }) => {
3104
+ tooltipContext?.showTooltip({
3105
+ datum,
3106
+ key: member.label,
3107
+ index
3108
+ });
3087
3109
  });
3088
3110
  } else if (mode === "individual") {
3089
3111
  if (selectedIndex < tooltipData.length) {
3090
3112
  const tooltipItem = tooltipData[selectedIndex];
3113
+ tooltipContext?.updateTooltip((state) => ({
3114
+ ...state,
3115
+ tooltipData: void 0
3116
+ }));
3091
3117
  tooltipContext?.showTooltip({
3092
3118
  datum: tooltipItem.datum,
3093
3119
  key: tooltipItem.seriesLabel,
@@ -3098,7 +3124,7 @@ const XYChartTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocu
3098
3124
  }, [
3099
3125
  selectedIndex,
3100
3126
  tooltipData,
3101
- series
3127
+ stops
3102
3128
  ]);
3103
3129
  const focusableRenderTooltip = (0, react.useMemo)(() => {
3104
3130
  if (!renderTooltip) return void 0;
@@ -3248,8 +3274,7 @@ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating,
3248
3274
  onChartPointerMove
3249
3275
  };
3250
3276
  };
3251
- //#endregion
3252
- //#region src/providers/chart-context/hooks/use-default-hidden-series.ts
3277
+ // src/providers/chart-context/hooks/use-default-hidden-series.ts
3253
3278
  /**
3254
3279
  * Seeds a chart's hidden series once per chart ID, the first time the provider
3255
3280
  * sees that ID.
@@ -3284,8 +3309,7 @@ const useDefaultHiddenSeries = (chartId, seriesLabels) => {
3284
3309
  chartId
3285
3310
  ]);
3286
3311
  };
3287
- //#endregion
3288
- //#region src/charts/private/chart-composition/chart-svg.tsx
3312
+ // src/charts/private/chart-composition/chart-svg.tsx
3289
3313
  /**
3290
3314
  * Compound component for SVG children in charts.
3291
3315
  * This component serves as a marker for SVG content that should be rendered
@@ -3299,8 +3323,7 @@ const ChartSVG = ({ children }) => {
3299
3323
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
3300
3324
  };
3301
3325
  ChartSVG.displayName = "Chart.SVG";
3302
- //#endregion
3303
- //#region src/charts/private/chart-composition/chart-html.tsx
3326
+ // src/charts/private/chart-composition/chart-html.tsx
3304
3327
  /**
3305
3328
  * Compound component for HTML children in charts.
3306
3329
  * This component serves as a marker for HTML content that should be rendered
@@ -3314,8 +3337,7 @@ const ChartHTML = ({ children }) => {
3314
3337
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
3315
3338
  };
3316
3339
  ChartHTML.displayName = "Chart.HTML";
3317
- //#endregion
3318
- //#region src/charts/private/chart-composition/render-legend-slot.ts
3340
+ // src/charts/private/chart-composition/render-legend-slot.ts
3319
3341
  /**
3320
3342
  * Renders legend children filtered by position slot.
3321
3343
  *
@@ -3326,8 +3348,7 @@ ChartHTML.displayName = "Chart.HTML";
3326
3348
  function renderLegendSlot(legendChildren, position) {
3327
3349
  return legendChildren.filter((l) => l.position === position).map((l, i) => (0, react.createElement)(react.Fragment, { key: `legend-${position}-${i}` }, l.element));
3328
3350
  }
3329
- //#endregion
3330
- //#region src/charts/private/chart-composition/use-chart-children.ts
3351
+ // src/charts/private/chart-composition/use-chart-children.ts
3331
3352
  /**
3332
3353
  * Custom hook to process and categorize chart children for composition API.
3333
3354
  * Extracts children from compound components (Chart.SVG, Chart.HTML) and
@@ -3380,11 +3401,9 @@ function useChartChildren(children, chartType) {
3380
3401
  };
3381
3402
  }, [children, chartType]);
3382
3403
  }
3383
- //#endregion
3384
- //#region src/charts/private/chart-layout/chart-layout.module.scss
3404
+ // src/charts/private/chart-layout/chart-layout.module.scss
3385
3405
  var chart_layout_module_default = { "chart-layout__content": "a8ccharts-fpNVAq-chart-layout__content" };
3386
- //#endregion
3387
- //#region src/charts/private/chart-layout/chart-layout.tsx
3406
+ // src/charts/private/chart-layout/chart-layout.tsx
3388
3407
  const ChartLayout = ({ legendPosition, legendElement, legendChildren, children, trailingContent, onContentHeightChange, gap, className, rootRef, style, "data-testid": dataTestId, "data-chart-id": dataChartId }) => {
3389
3408
  const [contentRef, contentWidth, contentHeight] = useElementSize();
3390
3409
  const isRenderProp = typeof children === "function";
@@ -3427,8 +3446,7 @@ const ChartLayout = ({ legendPosition, legendElement, legendChildren, children,
3427
3446
  ]
3428
3447
  });
3429
3448
  };
3430
- //#endregion
3431
- //#region src/charts/private/default-glyph/default-glyph.tsx
3449
+ // src/charts/private/default-glyph/default-glyph.tsx
3432
3450
  const DefaultGlyph = (props) => {
3433
3451
  const { theme } = (0, react.useContext)(_visx_xychart.DataContext) || {};
3434
3452
  props.position;
@@ -3443,8 +3461,7 @@ const DefaultGlyph = (props) => {
3443
3461
  ...props.glyphStyle
3444
3462
  });
3445
3463
  };
3446
- //#endregion
3447
- //#region src/charts/private/readings.ts
3464
+ // src/charts/private/readings.ts
3448
3465
  /**
3449
3466
  * Whether a value is a reading a scale can place.
3450
3467
  *
@@ -3468,11 +3485,9 @@ const isInvalidReading = (value, { allowMissing }) => value === null ? !allowMis
3468
3485
  * @return The formatted value.
3469
3486
  */
3470
3487
  const formatReading = (value) => value == null ? (0, _wordpress_i18n.__)("No data", "jetpack-charts") : (0, _automattic_number_formatters.formatNumber)(value);
3471
- //#endregion
3472
- //#region src/charts/private/center/center.module.scss
3488
+ // src/charts/private/center/center.module.scss
3473
3489
  var center_module_default = { "center": "a8ccharts-w3qxlG-center" };
3474
- //#endregion
3475
- //#region src/charts/private/center/center.tsx
3490
+ // src/charts/private/center/center.tsx
3476
3491
  /**
3477
3492
  * Centers its children on both axes and fills its parent.
3478
3493
  *
@@ -3494,11 +3509,9 @@ const Center = (0, react.forwardRef)(({ align = "center", justify = "center", cl
3494
3509
  ...props
3495
3510
  }));
3496
3511
  Center.displayName = "Center";
3497
- //#endregion
3498
- //#region src/charts/private/svg-empty-state/svg-empty-state.module.scss
3512
+ // src/charts/private/svg-empty-state/svg-empty-state.module.scss
3499
3513
  var svg_empty_state_module_default = { "svg-empty-state": "a8ccharts-udGPVq-svg-empty-state" };
3500
- //#endregion
3501
- //#region src/charts/private/svg-empty-state/svg-empty-state.tsx
3514
+ // src/charts/private/svg-empty-state/svg-empty-state.tsx
3502
3515
  /**
3503
3516
  * Renders empty-state text inside an SVG using foreignObject so that the
3504
3517
  * message wraps onto multiple lines instead of being clipped.
@@ -3525,8 +3538,7 @@ const SvgEmptyState = ({ x, y, width, height, children }) => {
3525
3538
  })
3526
3539
  });
3527
3540
  };
3528
- //#endregion
3529
- //#region src/charts/private/svg-empty-state/get-all-hidden-message.ts
3541
+ // src/charts/private/svg-empty-state/get-all-hidden-message.ts
3530
3542
  /**
3531
3543
  * Return the empty-state message for a chart whose items are all hidden.
3532
3544
  *
@@ -3546,8 +3558,7 @@ const getAllHiddenMessage = (interactive, itemType) => {
3546
3558
  if (interactive) return (0, _wordpress_i18n._x)("All series are hidden. Click legend items to show data.", "chart empty state: interactive series", "jetpack-charts");
3547
3559
  return (0, _wordpress_i18n._x)("All series are hidden.", "chart empty state: series", "jetpack-charts");
3548
3560
  };
3549
- //#endregion
3550
- //#region src/charts/private/time-axis.ts
3561
+ // src/charts/private/time-axis.ts
3551
3562
  const X_TICK_WIDTH = 60;
3552
3563
  const getCurveType = (type, smoothing) => {
3553
3564
  if (!type) return smoothing ? _visx_curve.curveCatmullRom : _visx_curve.curveLinear;
@@ -3804,8 +3815,7 @@ const guessOptimalNumTicks = (data, chartWidth, tickFormatter) => {
3804
3815
  }
3805
3816
  return Math.max(1, secondBestGuess);
3806
3817
  };
3807
- //#endregion
3808
- //#region src/charts/private/time-axis-options.ts
3818
+ // src/charts/private/time-axis-options.ts
3809
3819
  const toDateDomain = (domain) => domain ? [new Date(domain[0]), new Date(domain[1])] : void 0;
3810
3820
  /**
3811
3821
  * The x-axis options for a continuous time chart, shared by LineChart and AreaChart.
@@ -3840,8 +3850,7 @@ const buildTimeAxisOptions = ({ dataSorted, width, axisOptions, scaleDomain, zoo
3840
3850
  ...numTicks === void 0 ? {} : { numTicks }
3841
3851
  };
3842
3852
  };
3843
- //#endregion
3844
- //#region src/charts/private/whole-number-ticks.tsx
3853
+ // src/charts/private/whole-number-ticks.tsx
3845
3854
  /**
3846
3855
  * Whether every reading in the series is a whole number.
3847
3856
  *
@@ -3888,15 +3897,13 @@ const WholeNumberTicks = ({ axis, numTicks, enabled, children }) => {
3888
3897
  const tickValues = enabled ? getWholeNumberTickValues(axis === "x" ? xScale : yScale, numTicks) : void 0;
3889
3898
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: children(tickValues) });
3890
3899
  };
3891
- //#endregion
3892
- //#region src/charts/private/with-responsive/with-responsive.module.scss
3900
+ // src/charts/private/with-responsive/with-responsive.module.scss
3893
3901
  var with_responsive_module_default = {
3894
3902
  "container": "a8ccharts-sP1gHa-container",
3895
3903
  "content": "a8ccharts-sP1gHa-content",
3896
3904
  "isContained": "a8ccharts-sP1gHa-isContained"
3897
3905
  };
3898
- //#endregion
3899
- //#region src/charts/private/with-responsive/with-responsive.tsx
3906
+ // src/charts/private/with-responsive/with-responsive.tsx
3900
3907
  /**
3901
3908
  * A higher-order component that provides responsive dimensions
3902
3909
  * to the wrapped chart component using useParentSize from `@visx/responsive`.
@@ -3975,14 +3982,12 @@ function withResponsive(WrappedComponent) {
3975
3982
  });
3976
3983
  };
3977
3984
  }
3978
- //#endregion
3979
- //#region src/charts/private/x-zoom/x-zoom.module.scss
3985
+ // src/charts/private/x-zoom/x-zoom.module.scss
3980
3986
  var x_zoom_module_default = {
3981
3987
  "x-zoom__reset": "a8ccharts-ur9dWW-x-zoom__reset",
3982
3988
  "x-zoom__selection": "a8ccharts-ur9dWW-x-zoom__selection"
3983
3989
  };
3984
- //#endregion
3985
- //#region src/charts/private/x-zoom/x-zoom.tsx
3990
+ // src/charts/private/x-zoom/x-zoom.tsx
3986
3991
  const MIN_DRAG_PIXELS = 6;
3987
3992
  /**
3988
3993
  * Drag-to-zoom state + pointer handlers for an XY chart. Designed to be
@@ -4165,11 +4170,9 @@ function ZoomResetButton({ onClick }) {
4165
4170
  })
4166
4171
  });
4167
4172
  }
4168
- //#endregion
4169
- //#region src/charts/private/xy-plot/xy-plot.module.scss
4173
+ // src/charts/private/xy-plot/xy-plot.module.scss
4170
4174
  var xy_plot_module_default = { "xy-plot": "a8ccharts-bIyhgG-xy-plot" };
4171
- //#endregion
4172
- //#region src/charts/line-chart/line-chart.module.scss
4175
+ // src/charts/line-chart/line-chart.module.scss
4173
4176
  var line_chart_module_default = {
4174
4177
  "line-chart": "a8ccharts-inuQka-line-chart",
4175
4178
  "line-chart__annotation-label": "a8ccharts-inuQka-line-chart__annotation-label",
@@ -4271,8 +4274,7 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
4271
4274
  })]
4272
4275
  });
4273
4276
  };
4274
- //#endregion
4275
- //#region src/charts/line-chart/private/line-chart-annotations-overlay.tsx
4277
+ // src/charts/line-chart/private/line-chart-annotations-overlay.tsx
4276
4278
  const LineChartAnnotationsOverlay = ({ children }) => {
4277
4279
  const { chartRef, chartWidth, chartHeight } = useChartInstanceContext();
4278
4280
  const [scales, setScales] = (0, react.useState)(null);
@@ -4355,8 +4357,7 @@ const LineChartAnnotationsOverlay = ({ children }) => {
4355
4357
  })
4356
4358
  });
4357
4359
  };
4358
- //#endregion
4359
- //#region src/charts/line-chart/private/line-chart-annotation.tsx
4360
+ // src/charts/line-chart/private/line-chart-annotation.tsx
4360
4361
  const ANNOTATION_MAX_WIDTH = 125;
4361
4362
  const ANNOTATION_INIT_HEIGHT = 100;
4362
4363
  const getLabelPosition = ({ subjectType, x, xMax, y, yMin, yMax, maxWidth, height }) => {
@@ -4549,8 +4550,7 @@ const LineChartAnnotation = ({ datum, title, subtitle, subjectType = "circle", s
4549
4550
  ]
4550
4551
  }) });
4551
4552
  };
4552
- //#endregion
4553
- //#region src/charts/line-chart/private/line-chart-glyph.tsx
4553
+ // src/charts/line-chart/private/line-chart-glyph.tsx
4554
4554
  const toNumber$1 = (val) => {
4555
4555
  const num = typeof val === "number" ? val : parseFloat(val);
4556
4556
  return isNaN(num) ? void 0 : num;
@@ -4580,8 +4580,7 @@ const LineChartGlyph = ({ data, index, color, glyphStyle, renderGlyph, accessors
4580
4580
  position
4581
4581
  });
4582
4582
  };
4583
- //#endregion
4584
- //#region src/charts/line-chart/private/nearest-pointer-events.tsx
4583
+ // src/charts/line-chart/private/nearest-pointer-events.tsx
4585
4584
  /**
4586
4585
  * Find the datum nearest a pointer along x, in one series sorted by x.
4587
4586
  *
@@ -4680,8 +4679,7 @@ function NearestPointerEvents({ onPointerDown, onPointerMove, onPointerUp }) {
4680
4679
  (0, _visx_xychart.useEventEmitter)("pointerup", handlers.pointerup);
4681
4680
  return null;
4682
4681
  }
4683
- //#endregion
4684
- //#region src/charts/line-chart/line-chart.tsx
4682
+ // src/charts/line-chart/line-chart.tsx
4685
4683
  const defaultRenderGlyph = (props) => {
4686
4684
  return /* @__PURE__ */ (0, react.createElement)(DefaultGlyph, {
4687
4685
  ...props,
@@ -4863,21 +4861,22 @@ const LineChartInternal = (0, react.forwardRef)(({ data, ariaLabel, chartId: pro
4863
4861
  isSeriesVisible,
4864
4862
  options?.yScale
4865
4863
  ]);
4866
- const activateSelectedPoint = (0, react.useCallback)((index) => {
4867
- const series = visibleSeries.find((candidate) => candidate.data[index]);
4868
- if (series) onDatumActivate?.({
4869
- datum: series.data[index],
4870
- index,
4871
- key: series.label
4864
+ const stops = (0, react.useMemo)(() => getKeyboardStops(visibleSeries), [visibleSeries]);
4865
+ const activateSelectedPoint = (0, react.useCallback)((stop) => {
4866
+ const match = stops.membersAt(stop)[0];
4867
+ if (match) onDatumActivate?.({
4868
+ datum: match.datum,
4869
+ index: match.index,
4870
+ key: match.series.label
4872
4871
  });
4873
- }, [visibleSeries, onDatumActivate]);
4872
+ }, [stops, onDatumActivate]);
4874
4873
  const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
4875
4874
  selectedIndex,
4876
4875
  setSelectedIndex,
4877
4876
  isNavigating,
4878
4877
  setIsNavigating,
4879
4878
  chartRef,
4880
- totalPoints: Math.max(0, ...visibleSeries.map((series) => series.data.length)),
4879
+ totalPoints: stops.count,
4881
4880
  visibleSeriesKey,
4882
4881
  onActivate: activateSelectedPoint,
4883
4882
  preventTooltipScroll: tooltipPlacement === "below-axis"
@@ -5211,15 +5210,13 @@ const LineChartResponsive = attachSubComponents(withResponsive(LineChartWithProv
5211
5210
  AnnotationsOverlay: LineChartAnnotationsOverlay,
5212
5211
  Annotation: LineChartAnnotation
5213
5212
  });
5214
- //#endregion
5215
- //#region src/charts/area-chart/area-chart.module.scss
5213
+ // src/charts/area-chart/area-chart.module.scss
5216
5214
  var area_chart_module_default = {
5217
5215
  "area-chart": "a8ccharts-jlynaq-area-chart",
5218
5216
  "area-chart--animated": "a8ccharts-jlynaq-area-chart--animated",
5219
5217
  "rise": "a8ccharts-jlynaq-rise"
5220
5218
  };
5221
- //#endregion
5222
- //#region src/charts/area-chart/private/validate-data.ts
5219
+ // src/charts/area-chart/private/validate-data.ts
5223
5220
  /**
5224
5221
  * Up-front data validation. Returns a localised error message when the chart
5225
5222
  * cannot safely render, otherwise `null`. Catches the cases that would
@@ -5235,8 +5232,7 @@ const validateData$3 = (data) => {
5235
5232
  if (data.some((series) => series.data.some((point) => isInvalidReading(point.value, { allowMissing: false }) || "date" in point && point.date && isNaN(point.date.getTime())))) return (0, _wordpress_i18n.__)("Invalid data", "jetpack-charts");
5236
5233
  return null;
5237
5234
  };
5238
- //#endregion
5239
- //#region src/charts/area-chart/private/overlays.tsx
5235
+ // src/charts/area-chart/private/overlays.tsx
5240
5236
  const AreaChartScalesRef = ({ chartRef, width, height, margin }) => {
5241
5237
  const context = (0, react.useContext)(_visx_xychart.DataContext);
5242
5238
  (0, react.useImperativeHandle)(chartRef, () => ({
@@ -5301,8 +5297,7 @@ const HoverGlyphs = ({ visibleSeries, stacked, stackOffset, getElementStyles, st
5301
5297
  children: circles
5302
5298
  });
5303
5299
  };
5304
- //#endregion
5305
- //#region src/charts/area-chart/area-chart.tsx
5300
+ // src/charts/area-chart/area-chart.tsx
5306
5301
  const AreaChartInternal = (0, react.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) => {
5307
5302
  const legendInteractive = legend.interactive ?? false;
5308
5303
  const legendShape = legend.shape ?? "rect";
@@ -5348,19 +5343,22 @@ const AreaChartInternal = (0, react.forwardRef)(({ data, ariaLabel, chartId: pro
5348
5343
  }));
5349
5344
  }, [dataSorted, hiddenSeries]);
5350
5345
  const allSeriesHidden = (0, react.useMemo)(() => seriesWithVisibility.every(({ isVisible }) => !isVisible), [seriesWithVisibility]);
5351
- const hasWholeNumberValues = (0, react.useMemo)(() => (!stacked || stackOffset === "none") && hasOnlyWholeNumbers(dataSorted.filter((series) => isSeriesVisible(series.label))), [
5352
- dataSorted,
5353
- isSeriesVisible,
5346
+ const visibleDataSeries = (0, react.useMemo)(() => dataSorted.filter((series) => isSeriesVisible(series.label)), [dataSorted, isSeriesVisible]);
5347
+ const hasWholeNumberValues = (0, react.useMemo)(() => (!stacked || stackOffset === "none") && hasOnlyWholeNumbers(visibleDataSeries), [
5348
+ visibleDataSeries,
5354
5349
  stacked,
5355
5350
  stackOffset
5356
5351
  ]);
5352
+ const visibleSeriesKey = (0, react.useMemo)(() => JSON.stringify(visibleDataSeries.map((series) => series.label)), [visibleDataSeries]);
5353
+ const stops = (0, react.useMemo)(() => getKeyboardStops(visibleDataSeries), [visibleDataSeries]);
5357
5354
  const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
5358
5355
  selectedIndex,
5359
5356
  setSelectedIndex,
5360
5357
  isNavigating,
5361
5358
  setIsNavigating,
5362
5359
  chartRef,
5363
- totalPoints: dataSorted[0]?.data.length || 0
5360
+ totalPoints: stops.count,
5361
+ visibleSeriesKey
5364
5362
  });
5365
5363
  const fixedYDomain = (0, react.useMemo)(() => {
5366
5364
  if (rescaleYOnVisibilityChange || !dataSorted.length || !dataSorted[0].data.length || stacked && stackOffset !== "none") return;
@@ -5648,7 +5646,7 @@ const AreaChartInternal = (0, react.forwardRef)(({ data, ariaLabel, chartId: pro
5648
5646
  selectedIndex,
5649
5647
  tooltipRef,
5650
5648
  keyboardFocusedClassName: area_chart_module_default["area-chart__tooltip--keyboard-focused"],
5651
- series: dataSorted
5649
+ series: visibleDataSeries
5652
5650
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HoverGlyphs, {
5653
5651
  visibleSeries,
5654
5652
  stacked,
@@ -5684,8 +5682,7 @@ const AreaChartWithProvider = (0, react.forwardRef)((props, ref) => {
5684
5682
  AreaChartWithProvider.displayName = "AreaChart";
5685
5683
  const AreaChart = attachSubComponents(AreaChartWithProvider, { Legend });
5686
5684
  const AreaChartResponsive = attachSubComponents(withResponsive(AreaChartWithProvider), { Legend });
5687
- //#endregion
5688
- //#region src/charts/bar-chart/bar-chart.module.scss
5685
+ // src/charts/bar-chart/bar-chart.module.scss
5689
5686
  var bar_chart_module_default = {
5690
5687
  "bar-chart": "a8ccharts-97yN9W-bar-chart",
5691
5688
  "bar-chart--animated": "a8ccharts-97yN9W-bar-chart--animated",
@@ -5693,8 +5690,7 @@ var bar_chart_module_default = {
5693
5690
  "rise": "a8ccharts-97yN9W-rise",
5694
5691
  "stretch": "a8ccharts-97yN9W-stretch"
5695
5692
  };
5696
- //#endregion
5697
- //#region src/charts/bar-chart/private/truncated-tick-component.tsx
5693
+ // src/charts/bar-chart/private/truncated-tick-component.tsx
5698
5694
  /**
5699
5695
  * Get the bandwidth of a scale
5700
5696
  *
@@ -5808,8 +5804,7 @@ const createTruncatedTickComponent = (axis) => (props) => {
5808
5804
  */
5809
5805
  const TruncatedXTickComponent = createTruncatedTickComponent("x");
5810
5806
  const TruncatedYTickComponent = createTruncatedTickComponent("y");
5811
- //#endregion
5812
- //#region src/charts/bar-chart/private/value-domain.ts
5807
+ // src/charts/bar-chart/private/value-domain.ts
5813
5808
  /** Domain for a value axis that has nothing to scale, so its ticks still read 0 to 1. */
5814
5809
  const EMPTY_DOMAIN = [0, 1];
5815
5810
  /**
@@ -5860,8 +5855,7 @@ const getValueScaleDomain = (data, includeZero, isSeriesRendered) => {
5860
5855
  if (includeZero) return [Math.min(0, min), Math.max(0, max)];
5861
5856
  return null;
5862
5857
  };
5863
- //#endregion
5864
- //#region src/charts/bar-chart/private/use-bar-chart-options.ts
5858
+ // src/charts/bar-chart/private/use-bar-chart-options.ts
5865
5859
  /** Outer padding of the category band scale (space at the chart edges). */
5866
5860
  const BASE_BAND_PADDING = .2;
5867
5861
  /** Inner padding of the category band scale (the base gap between ticks). */
@@ -6077,8 +6071,7 @@ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = A
6077
6071
  isSeriesRendered
6078
6072
  ]);
6079
6073
  }
6080
- //#endregion
6081
- //#region src/charts/bar-chart/private/band-scale.ts
6074
+ // src/charts/bar-chart/private/band-scale.ts
6082
6075
  /**
6083
6076
  * Match the inner slot scale used by visx BarGroup.
6084
6077
  * @param keys - Visible primary series keys.
@@ -6091,8 +6084,7 @@ const createGroupScale = (keys, bandwidth, padding) => (0, _visx_scale.scaleBand
6091
6084
  range: [0, bandwidth],
6092
6085
  padding
6093
6086
  });
6094
- //#endregion
6095
- //#region src/charts/bar-chart/private/comparison-bars-geometry.ts
6087
+ // src/charts/bar-chart/private/comparison-bars-geometry.ts
6096
6088
  /**
6097
6089
  * Mirrors visx's getScaleBaseline so bars drawn outside visx share the baseline of its bars, including out-of-domain zero values.
6098
6090
  *
@@ -6138,8 +6130,7 @@ function computeSlotRect(params) {
6138
6130
  height: valueLength
6139
6131
  };
6140
6132
  }
6141
- //#endregion
6142
- //#region src/charts/bar-chart/private/classified-bar-series.tsx
6133
+ // src/charts/bar-chart/private/classified-bar-series.tsx
6143
6134
  const ClassifiedBarSeries = ({ barClassName, primaryKeys, groupPadding, ...props }) => {
6144
6135
  const { xScale, yScale, horizontal } = (0, react.useContext)(_visx_xychart.DataContext);
6145
6136
  const bandScale = horizontal ? yScale : xScale;
@@ -6183,8 +6174,7 @@ const ClassifiedBarSeries = ({ barClassName, primaryKeys, groupPadding, ...props
6183
6174
  renderGlyph
6184
6175
  });
6185
6176
  };
6186
- //#endregion
6187
- //#region src/charts/bar-chart/private/slotted-bar-series.tsx
6177
+ // src/charts/bar-chart/private/slotted-bar-series.tsx
6188
6178
  const SlottedBarSeries = ({ barClassName, slotKeys, slotKey, thickness, groupPadding, ...props }) => {
6189
6179
  const { xScale, yScale, horizontal } = (0, react.useContext)(_visx_xychart.DataContext);
6190
6180
  const bandScale = horizontal ? yScale : xScale;
@@ -6227,16 +6217,14 @@ const SlottedBarSeries = ({ barClassName, slotKeys, slotKey, thickness, groupPad
6227
6217
  renderGlyph
6228
6218
  });
6229
6219
  };
6230
- //#endregion
6231
- //#region src/charts/private/selected-ring/selected-ring.module.scss
6220
+ // src/charts/private/selected-ring/selected-ring.module.scss
6232
6221
  var selected_ring_module_default = {
6233
6222
  "selected-ring__contrast": "a8ccharts-gx1_AW-selected-ring__contrast",
6234
6223
  "selected-ring__edge": "a8ccharts-gx1_AW-selected-ring__edge",
6235
6224
  "selected-ring__far": "a8ccharts-gx1_AW-selected-ring__far",
6236
6225
  "selected-ring__focus": "a8ccharts-gx1_AW-selected-ring__focus"
6237
6226
  };
6238
- //#endregion
6239
- //#region src/charts/private/selected-ring/selected-ring.tsx
6227
+ // src/charts/private/selected-ring/selected-ring.tsx
6240
6228
  const TONES = {
6241
6229
  inside: ["contrast", "focus"],
6242
6230
  outside: ["focus", "contrast"]
@@ -6283,8 +6271,7 @@ const SelectedRing = ({ chartId, d, side, testId }) => {
6283
6271
  ]
6284
6272
  });
6285
6273
  };
6286
- //#endregion
6287
- //#region src/charts/bar-chart/private/selected-bar-ring.tsx
6274
+ // src/charts/bar-chart/private/selected-bar-ring.tsx
6288
6275
  /**
6289
6276
  * Marks the keyboard-selected slot with a two-tone ring outside its edge, so the ring reads against any bar color.
6290
6277
  *
@@ -6325,8 +6312,7 @@ const SelectedBarRing = ({ chartId, selected, slotKeys, groupPadding, horizontal
6325
6312
  testId: "bar-chart-selected-ring"
6326
6313
  });
6327
6314
  };
6328
- //#endregion
6329
- //#region src/charts/bar-chart/private/bar-layer.tsx
6315
+ // src/charts/bar-chart/private/bar-layer.tsx
6330
6316
  /**
6331
6317
  * Draws the bars in front of any comparison shadows, slotted for an overlap layout and grouped by visx otherwise, then the selected bar's ring.
6332
6318
  *
@@ -6394,8 +6380,7 @@ const BarLayer = ({ chartId, overlapSlots, selectedBar, primaryEntries, primaryK
6394
6380
  yAccessor
6395
6381
  })] });
6396
6382
  };
6397
- //#endregion
6398
- //#region src/charts/bar-chart/private/slot-tooltip-members.tsx
6383
+ // src/charts/bar-chart/private/slot-tooltip-members.tsx
6399
6384
  /**
6400
6385
  * Fills the tooltip with every bar of the keyboard-selected category, and only those.
6401
6386
  *
@@ -6403,26 +6388,20 @@ const BarLayer = ({ chartId, overlapSlots, selectedBar, primaryEntries, primaryK
6403
6388
  *
6404
6389
  * @param props - Component props.
6405
6390
  * @param props.members - The category's bars, the keyboard stop last.
6406
- * @param props.index - The selected data point.
6407
6391
  * @return No visual content.
6408
6392
  */
6409
- function SlotTooltipMembers({ members, index }) {
6393
+ function SlotTooltipMembers({ members }) {
6410
6394
  const { showTooltip, updateTooltip } = (0, react.useContext)(_visx_xychart.TooltipContext) ?? {};
6411
6395
  (0, react.useEffect)(() => {
6412
6396
  updateTooltip?.((state) => ({
6413
6397
  ...state,
6414
6398
  tooltipData: void 0
6415
6399
  }));
6416
- members.forEach(({ key, datum }) => showTooltip?.({
6417
- key,
6418
- datum,
6419
- index
6420
- }));
6421
- }, [members, index]);
6400
+ members.forEach((member) => showTooltip?.(member));
6401
+ }, [members]);
6422
6402
  return null;
6423
6403
  }
6424
- //#endregion
6425
- //#region src/charts/bar-chart/private/overlap-bars.ts
6404
+ // src/charts/bar-chart/private/overlap-bars.ts
6426
6405
  const PRIMARY_SLOT = "primary";
6427
6406
  const COMPARISON_SLOT = "comparison";
6428
6407
  const OVERLAP_SLOTS = [PRIMARY_SLOT, COMPARISON_SLOT];
@@ -6530,8 +6509,7 @@ function getOverlapBarColors(series, colors, slotColors, background) {
6530
6509
  });
6531
6510
  return barColors;
6532
6511
  }
6533
- //#endregion
6534
- //#region src/charts/bar-chart/private/use-overlap-slots.ts
6512
+ // src/charts/bar-chart/private/use-overlap-slots.ts
6535
6513
  /**
6536
6514
  * Whether two data points sit at the same category: the same label, or the same date.
6537
6515
  *
@@ -6540,7 +6518,7 @@ function getOverlapBarColors(series, colors, slotColors, background) {
6540
6518
  * @return Whether `point` is at `category`.
6541
6519
  */
6542
6520
  function isSameCategory(point, category) {
6543
- return category.label != null ? point.label === category.label : !!category.date && !!point.date && point.date.getTime() === category.date.getTime();
6521
+ return category.label ? point.label === category.label : !!category.date && !!point.date && point.date.getTime() === category.date.getTime();
6544
6522
  }
6545
6523
  /**
6546
6524
  * Lays out the visible series of an overlap layout in slots and layers.
@@ -6585,7 +6563,7 @@ function useOverlapSlots(enabled, seriesWithVisibility) {
6585
6563
  * @return The category key.
6586
6564
  */
6587
6565
  function categoryKey(point) {
6588
- return point.label != null ? `label:${point.label}` : `date:${point.date?.getTime()}`;
6566
+ return point.label ? `label:${point.label}` : `date:${point.date?.getTime()}`;
6589
6567
  }
6590
6568
  /**
6591
6569
  * Lists a stop for every slot at every category that slot draws a bar at, category by category.
@@ -6623,6 +6601,25 @@ function getStopPositions(entries, slotKeys, slotOf) {
6623
6601
  }));
6624
6602
  }
6625
6603
  /**
6604
+ * Every bar at a category, each with its own data point index, the keyboard stop last.
6605
+ *
6606
+ * @param entries - The visible series.
6607
+ * @param category - The data point naming the category.
6608
+ * @param stopKey - The series the keyboard stop is on.
6609
+ * @return The category's bars; the last one shown becomes the tooltip's nearest datum.
6610
+ */
6611
+ function membersAt(entries, category, stopKey) {
6612
+ const members = entries.flatMap(({ series }) => {
6613
+ const index = series.data.findIndex((point) => isSameCategory(point, category));
6614
+ return index === -1 ? [] : [{
6615
+ key: series.label,
6616
+ datum: series.data[index],
6617
+ index
6618
+ }];
6619
+ });
6620
+ return [...members.filter(({ key }) => key !== stopKey), ...members.filter(({ key }) => key === stopKey)];
6621
+ }
6622
+ /**
6626
6623
  * The slot a keyboard index selects, and every bar at its category.
6627
6624
  *
6628
6625
  * @param slots - The overlap layout.
@@ -6632,25 +6629,17 @@ function getStopPositions(entries, slotKeys, slotOf) {
6632
6629
  function getSelectedSlot(slots, selectedIndex) {
6633
6630
  const position = selectedIndex === void 0 ? void 0 : slots?.positions[selectedIndex];
6634
6631
  if (!slots || !position) return;
6635
- const { slotKey, key: stopKey, datum: category, dataPointIndex } = position;
6636
- const members = slots.entries.flatMap(({ series }) => {
6637
- const datum = series.data.find((point) => isSameCategory(point, category));
6638
- return datum ? [{
6639
- key: series.label,
6640
- datum
6641
- }] : [];
6642
- });
6632
+ const { slotKey, key: stopKey, datum: category } = position;
6633
+ const members = membersAt(slots.entries, category, stopKey);
6643
6634
  const slotBars = members.filter(({ key, datum }) => isBarRendered(datum) && slots.slotOf(key) === slotKey);
6644
6635
  return {
6645
6636
  data: slotBars.map(({ datum }) => datum),
6646
6637
  slotKey,
6647
6638
  thickness: Math.max(...slotBars.map(({ key }) => slots.thicknessOf(key))),
6648
- index: dataPointIndex,
6649
- members: [...members.filter(({ key }) => key !== stopKey), ...members.filter(({ key }) => key === stopKey)]
6639
+ members
6650
6640
  };
6651
6641
  }
6652
- //#endregion
6653
- //#region src/charts/bar-chart/private/use-bar-stops.ts
6642
+ // src/charts/bar-chart/private/use-bar-stops.ts
6654
6643
  /**
6655
6644
  * Lays out the keyboard stops: one per slot and category in an overlap layout, else one per primary bar, series-major within each category.
6656
6645
  *
@@ -6662,7 +6651,6 @@ function useBarStops(overlapSlots, primaryEntries) {
6662
6651
  const series = (0, react.useMemo)(() => overlapSlots ? [] : primaryEntries.map((entry) => entry.series), [overlapSlots, primaryEntries]);
6663
6652
  return {
6664
6653
  count: overlapSlots?.positions.length ?? Math.max(0, ...series.map((item) => item.data.length)) * series.length,
6665
- series,
6666
6654
  key: (0, react.useMemo)(() => JSON.stringify(overlapSlots?.keys ?? series.map((item) => item.label)), [overlapSlots, series]),
6667
6655
  barAt: (0, react.useCallback)((stop) => {
6668
6656
  if (overlapSlots) {
@@ -6705,8 +6693,7 @@ const MAX_GROUP_PADDING = .9;
6705
6693
  * gap between ticks. `0.75` = a 25% reduction of the tick-gap padding.
6706
6694
  */
6707
6695
  const COMPARISON_TICK_GAP_FACTOR = .75;
6708
- //#endregion
6709
- //#region src/charts/bar-chart/private/comparison-bars.tsx
6696
+ // src/charts/bar-chart/private/comparison-bars.tsx
6710
6697
  const ComparisonBars = ({ comparisonEntries, primaryKeys, groupPadding, horizontal, xAccessor, yAccessor, getElementStyles, resolveFill }) => {
6711
6698
  const context = (0, react.useContext)(_visx_xychart.DataContext);
6712
6699
  const xScale = context?.xScale;
@@ -6765,8 +6752,7 @@ const ComparisonBars = ({ comparisonEntries, primaryKeys, groupPadding, horizont
6765
6752
  children: rects
6766
6753
  });
6767
6754
  };
6768
- //#endregion
6769
- //#region src/charts/bar-chart/private/band-highlight.tsx
6755
+ // src/charts/bar-chart/private/band-highlight.tsx
6770
6756
  /**
6771
6757
  * Render and report the active band using the chart’s registered scales.
6772
6758
  * @param root0 - Highlight options.
@@ -6825,8 +6811,7 @@ function BandHighlight({ visible, horizontal, onChange }) {
6825
6811
  fill: CATALOG_POINTERS.surfaceSecondary
6826
6812
  });
6827
6813
  }
6828
- //#endregion
6829
- //#region src/charts/bar-chart/private/band-tooltip.tsx
6814
+ // src/charts/bar-chart/private/band-tooltip.tsx
6830
6815
  /**
6831
6816
  * Find a category by its painted center, including outer padding and reversed ranges.
6832
6817
  * @param data - Registered series points.
@@ -6945,8 +6930,7 @@ function BandTooltip({ keys, slots, groupPadding, withTooltips, onPointerDown, o
6945
6930
  (0, _visx_xychart.useEventEmitter)("pointerup", onPointerUp ? handlePointer : void 0);
6946
6931
  return null;
6947
6932
  }
6948
- //#endregion
6949
- //#region src/charts/bar-chart/private/grouped-bars.ts
6933
+ // src/charts/bar-chart/private/grouped-bars.ts
6950
6934
  /**
6951
6935
  * Pairs each comparison series with the primary of its `group`, or with the only primary.
6952
6936
  *
@@ -6986,8 +6970,7 @@ function getGroupedBarColors(series, colors, background) {
6986
6970
  });
6987
6971
  return barColors;
6988
6972
  }
6989
- //#endregion
6990
- //#region src/charts/bar-chart/use-bar-colors.ts
6973
+ // src/charts/bar-chart/use-bar-colors.ts
6991
6974
  /**
6992
6975
  * Reads the colors `BarChart` fills series with, so a custom tooltip or legend can match the bars.
6993
6976
  *
@@ -7009,8 +6992,7 @@ function useBarColors() {
7009
6992
  comparisonOpacity
7010
6993
  ]);
7011
6994
  }
7012
- //#endregion
7013
- //#region src/charts/bar-chart/use-bar-legend-items.ts
6995
+ // src/charts/bar-chart/use-bar-legend-items.ts
7014
6996
  const isComparison = (data, label) => data.some((series) => series.label === label && series.options?.type === "comparison");
7015
6997
  /**
7016
6998
  * Applies what a bar layout changes about a legend: overlap lists every primary before every comparison, as it draws their slots, with every swatch opaque like its bar; a collapsed grouped item takes its comparison's tint, the wider bar that frames the group.
@@ -7074,8 +7056,7 @@ function useBarLegendItems(data, options = {}, legendShape) {
7074
7056
  seriesColors
7075
7057
  ]);
7076
7058
  }
7077
- //#endregion
7078
- //#region src/charts/bar-chart/bar-chart.tsx
7059
+ // src/charts/bar-chart/bar-chart.tsx
7079
7060
  const validateData$2 = (data) => {
7080
7061
  if (!data?.length) return (0, _wordpress_i18n.__)("No data available", "jetpack-charts");
7081
7062
  if (data.some((series) => series.data.some((point) => isInvalidReading(point.value, { allowMissing: true }) || !point.label && (!("date" in point && point.date) || isNaN(point.date.getTime()))))) return (0, _wordpress_i18n.__)("Invalid data", "jetpack-charts");
@@ -7266,10 +7247,7 @@ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, he
7266
7247
  const primaryKey = tooltipData?.nearestDatum?.key;
7267
7248
  const categoryLabel = chartOptions.tooltip.labelFormatter(nearestDatum.label || (nearestDatum.date ? nearestDatum.date.getTime() : 0), 0, []);
7268
7249
  const comparisonEntry = comparisonEntries.find((entry) => entry.primaryKey === primaryKey);
7269
- const comparisonDatum = comparisonEntry?.series.data.find((point) => {
7270
- const p = point;
7271
- return nearestDatum.label != null ? p.label === nearestDatum.label : !!nearestDatum.date && !!p.date && p.date.getTime() === nearestDatum.date.getTime();
7272
- });
7250
+ const comparisonDatum = comparisonEntry?.series.data.find((point) => isSameCategory(point, nearestDatum));
7273
7251
  if (comparisonEntry && comparisonDatum) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7274
7252
  className: bar_chart_module_default["bar-chart__tooltip"],
7275
7253
  children: [
@@ -7339,6 +7317,17 @@ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, he
7339
7317
  slotOf: overlapSlots.slotOf
7340
7318
  }, [overlapSlots]);
7341
7319
  const selectedSlot = (0, react.useMemo)(() => getSelectedSlot(overlapSlots, selectedIndex), [overlapSlots, selectedIndex]);
7320
+ const selectedGroup = (0, react.useMemo)(() => {
7321
+ const stop = overlapSlots || selectedIndex === void 0 ? void 0 : barAt(selectedIndex);
7322
+ if (!stop) return;
7323
+ return membersAt(primaryEntries, stop.datum, stop.key);
7324
+ }, [
7325
+ overlapSlots,
7326
+ selectedIndex,
7327
+ barAt,
7328
+ primaryEntries
7329
+ ]);
7330
+ const selectedMembers = selectedSlot?.members ?? selectedGroup;
7342
7331
  const selectedBar = (0, react.useMemo)(() => {
7343
7332
  if (overlapSlots) return selectedSlot;
7344
7333
  const bar = selectedIndex === void 0 ? void 0 : barAt(selectedIndex);
@@ -7501,10 +7490,7 @@ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, he
7501
7490
  ...!horizontal && valueTicks ? { tickValues: valueTicks } : {}
7502
7491
  })] })
7503
7492
  }),
7504
- withTooltips && selectedSlot && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SlotTooltipMembers, {
7505
- members: selectedSlot.members,
7506
- index: selectedSlot.index
7507
- }),
7493
+ withTooltips && selectedMembers && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SlotTooltipMembers, { members: selectedMembers }),
7508
7494
  withTooltips && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(XYChartTooltip, {
7509
7495
  tooltipPlacement,
7510
7496
  tooltipAnchorTop,
@@ -7516,7 +7502,6 @@ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, he
7516
7502
  selectedIndex,
7517
7503
  tooltipRef,
7518
7504
  keyboardFocusedClassName: bar_chart_module_default["bar-chart__tooltip--keyboard-focused"],
7519
- series: stops.series,
7520
7505
  mode: "individual"
7521
7506
  })
7522
7507
  ]
@@ -7534,8 +7519,7 @@ const BarChartWithProvider = (props) => {
7534
7519
  BarChartWithProvider.displayName = "BarChart";
7535
7520
  const BarChart = attachSubComponents(BarChartWithProvider, { Legend });
7536
7521
  const BarChartResponsive = attachSubComponents(withResponsive(BarChartWithProvider), { Legend });
7537
- //#endregion
7538
- //#region src/charts/bar-list-chart/bar-list-chart.tsx
7522
+ // src/charts/bar-list-chart/bar-list-chart.tsx
7539
7523
  /**
7540
7524
  * Get the bandwidth of a scale
7541
7525
  * @param scale - The scale to get the bandwidth of
@@ -7704,8 +7688,7 @@ const BarListChart = (props) => {
7704
7688
  };
7705
7689
  BarListChart.displayName = "BarListChart";
7706
7690
  const BarListChartResponsive = withResponsive(BarListChart);
7707
- //#endregion
7708
- //#region src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss
7691
+ // src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss
7709
7692
  var conversion_funnel_chart_module_default = {
7710
7693
  "bar-container": "a8ccharts-mGEVca-bar-container",
7711
7694
  "change-indicator": "a8ccharts-mGEVca-change-indicator",
@@ -7724,83 +7707,131 @@ var conversion_funnel_chart_module_default = {
7724
7707
  "main-rate": "a8ccharts-mGEVca-main-rate",
7725
7708
  "step-label": "a8ccharts-mGEVca-step-label",
7726
7709
  "step-rate": "a8ccharts-mGEVca-step-rate",
7710
+ "step-text": "a8ccharts-mGEVca-step-text",
7727
7711
  "stretch": "a8ccharts-mGEVca-stretch",
7728
- "tooltip-content": "a8ccharts-mGEVca-tooltip-content",
7729
- "tooltip-title": "a8ccharts-mGEVca-tooltip-title"
7712
+ "tooltip-label": "a8ccharts-mGEVca-tooltip-label",
7713
+ "tooltip-title": "a8ccharts-mGEVca-tooltip-title",
7714
+ "tooltip-value": "a8ccharts-mGEVca-tooltip-value"
7730
7715
  };
7731
- //#endregion
7732
- //#region src/charts/conversion-funnel-chart/private/use-funnel-selection.ts
7716
+ // src/charts/conversion-funnel-chart/private/use-funnel-selection.ts
7733
7717
  /**
7734
- * Custom hook to manage funnel bar selection state and interactions
7718
+ * Custom hook to manage funnel step selection state
7735
7719
  * @param hideTooltip - Function to hide tooltip when selection is cleared
7736
- * @return Object containing selection state and event handlers
7720
+ * @return Object containing selection state and its setters
7737
7721
  */
7738
7722
  const useFunnelSelection = (hideTooltip) => {
7739
- const [clickedStep, setClickedStep] = (0, react.useState)(null);
7723
+ const [selectedStepId, setSelectedStepId] = (0, react.useState)(null);
7740
7724
  return {
7741
- clickedStep,
7742
- handleBarClick: (0, react.useCallback)((stepId) => {
7743
- if (clickedStep === stepId) {
7744
- setClickedStep(null);
7745
- hideTooltip?.();
7746
- } else setClickedStep(stepId);
7747
- }, [clickedStep, hideTooltip]),
7748
- handleBarKeyDown: (0, react.useCallback)((stepId, event) => {
7749
- if (event.key === "Enter" || event.key === " ") {
7750
- event.preventDefault();
7751
- if (clickedStep === stepId) {
7752
- setClickedStep(null);
7753
- hideTooltip?.();
7754
- } else setClickedStep(stepId);
7755
- } else if (event.key === "Escape") {
7756
- event.preventDefault();
7757
- setClickedStep(null);
7758
- hideTooltip?.();
7759
- }
7760
- }, [clickedStep, hideTooltip]),
7725
+ selectedStepId,
7726
+ selectStep: setSelectedStepId,
7761
7727
  clearSelection: (0, react.useCallback)(() => {
7762
- setClickedStep(null);
7728
+ setSelectedStepId(null);
7763
7729
  hideTooltip?.();
7764
7730
  }, [hideTooltip]),
7765
7731
  getStepState: (0, react.useCallback)((stepId) => ({
7766
- isClicked: clickedStep === stepId,
7767
- isBlurred: clickedStep !== null && clickedStep !== stepId
7768
- }), [clickedStep])
7732
+ isSelected: selectedStepId === stepId,
7733
+ isBlurred: selectedStepId !== null && selectedStepId !== stepId
7734
+ }), [selectedStepId])
7735
+ };
7736
+ };
7737
+ // src/charts/conversion-funnel-chart/private/use-roving-step-focus.ts
7738
+ const getTargetIndex = (key, index, count, isRtl) => {
7739
+ const nextKey = isRtl ? "ArrowLeft" : "ArrowRight";
7740
+ const previousKey = isRtl ? "ArrowRight" : "ArrowLeft";
7741
+ switch (key) {
7742
+ case nextKey: return Math.min(index + 1, count - 1);
7743
+ case previousKey: return Math.max(index - 1, 0);
7744
+ case "Home": return 0;
7745
+ case "End": return count - 1;
7746
+ default: return;
7747
+ }
7748
+ };
7749
+ /**
7750
+ * Roving tabindex for the funnel steps: one Tab stop, and arrow keys, Home and End move focus between steps.
7751
+ *
7752
+ * @param stepIds - Step ids in visual order.
7753
+ * @param selectedStepId - The selected step, which holds the Tab stop until any step has taken focus.
7754
+ * @return Tab index, element registration, focus and key handlers for each step.
7755
+ */
7756
+ const useRovingStepFocus = (stepIds, selectedStepId) => {
7757
+ const [focusedStepId, setFocusedStepId] = (0, react.useState)(null);
7758
+ const stepElements = (0, react.useRef)(/* @__PURE__ */ new Map());
7759
+ const tabStopId = [focusedStepId, selectedStepId].find((id) => id !== null && stepIds.includes(id)) ?? stepIds[0];
7760
+ return {
7761
+ getTabIndex: (0, react.useCallback)((stepId) => stepId === tabStopId ? 0 : -1, [tabStopId]),
7762
+ setStepElement: (0, react.useCallback)((stepId, element) => {
7763
+ if (element) stepElements.current.set(stepId, element);
7764
+ else stepElements.current.delete(stepId);
7765
+ }, []),
7766
+ handleStepFocus: (0, react.useCallback)((stepId) => {
7767
+ setFocusedStepId(stepId);
7768
+ }, []),
7769
+ handleNavigationKey: (0, react.useCallback)((stepId, event) => {
7770
+ if (event.altKey || event.ctrlKey || event.metaKey) return false;
7771
+ const isRtl = getComputedStyle(event.currentTarget).direction === "rtl";
7772
+ const targetIndex = getTargetIndex(event.key, stepIds.indexOf(stepId), stepIds.length, isRtl);
7773
+ if (targetIndex === void 0) return false;
7774
+ event.preventDefault();
7775
+ stepElements.current.get(stepIds[targetIndex])?.focus();
7776
+ return true;
7777
+ }, [stepIds])
7769
7778
  };
7770
7779
  };
7771
- //#endregion
7772
- //#region src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx
7780
+ // src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx
7773
7781
  /** Chart height (px) below which the funnel tightens its gaps so the bars keep their room. */
7774
7782
  const SHORT_CHART_HEIGHT = 180;
7783
+ const formatStepCount = (count) => (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n._n)("%s item", "%s items", count, "jetpack-charts"), formatMetricValue(count));
7784
+ const getDefaultTooltipContent = (step) => ({
7785
+ value: step.count === void 0 ? void 0 : formatStepCount(step.count),
7786
+ rows: [{
7787
+ label: (0, _wordpress_i18n.__)("Conversion rate", "jetpack-charts"),
7788
+ value: formatPercentage(step.rate)
7789
+ }]
7790
+ });
7791
+ const getDefaultTooltipIds = (tooltipId, { rows = [] }) => ({
7792
+ value: `${tooltipId}-value`,
7793
+ rows: rows.map((_, index) => ({
7794
+ label: `${tooltipId}-row-${index}-label`,
7795
+ value: `${tooltipId}-row-${index}-value`
7796
+ }))
7797
+ });
7798
+ const getDefaultTooltipDescriptionIds = (tooltipId, content) => {
7799
+ const ids = getDefaultTooltipIds(tooltipId, content);
7800
+ return [...content.value ? [ids.value] : [], ...ids.rows.flatMap((row) => [row.label, row.value])].join(" ");
7801
+ };
7775
7802
  /**
7776
7803
  * Internal ConversionFunnelChart component with chart registration
7777
7804
  *
7778
- * @param props - Component props
7779
- * @param props.chartId - Optional unique identifier for the chart
7780
- * @param props.mainRate - Main conversion rate to highlight
7781
- * @param props.changeIndicator - Change indicator (e.g., +2%, -1.5%)
7782
- * @param props.steps - Array of funnel steps
7783
- * @param props.loading - Whether the chart is in loading state
7784
- * @param props.animation - Whether to show chart animation on initial render or not
7785
- * @param props.className - Additional CSS class name
7786
- * @param props.ariaLabel - Accessible name for the chart group
7787
- * @param props.height - Height of the chart container. Falls back to style.height if set, otherwise defaults to "100%".
7788
- * @param props.style - Custom styling
7789
- * @param props.renderStepLabel - Custom render function for step labels
7790
- * @param props.renderStepRate - Custom render function for step rates
7791
- * @param props.renderMainMetric - Custom render function for the entire main metric section
7792
- * @param props.renderTooltip - Custom render function for tooltip content
7793
- * @param props.tooltipStyle - Inline styles merged over the tooltip box defaults
7805
+ * @param props - Component props
7806
+ * @param props.chartId - Optional unique identifier for the chart
7807
+ * @param props.mainRate - Main conversion rate to highlight
7808
+ * @param props.changeIndicator - Change indicator (e.g., +2%, -1.5%)
7809
+ * @param props.steps - Array of funnel steps
7810
+ * @param props.loading - Whether the chart is in loading state
7811
+ * @param props.animation - Whether to show chart animation on initial render or not
7812
+ * @param props.className - Additional CSS class name
7813
+ * @param props.ariaLabel - Accessible name for the chart group
7814
+ * @param props.height - Height of the chart container. Falls back to style.height if set, otherwise defaults to "100%".
7815
+ * @param props.style - Custom styling
7816
+ * @param props.renderStepLabel - Custom render function for step labels
7817
+ * @param props.renderStepRate - Custom render function for step rates
7818
+ * @param props.renderMainMetric - Custom render function for the entire main metric section
7819
+ * @param props.renderTooltip - Custom render function for tooltip content
7820
+ * @param props.tooltipStyle - Inline styles merged over the tooltip box defaults
7821
+ * @param props.getTooltipContent - What each step's tooltip shows, which screen readers also read
7794
7822
  * @return JSX element representing the conversion funnel chart
7795
7823
  */
7796
- const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, ariaLabel, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip, tooltipStyle }) => {
7824
+ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, ariaLabel, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip, tooltipStyle, getTooltipContent = getDefaultTooltipContent }) => {
7797
7825
  const chartId = useChartId(providedChartId);
7798
7826
  const { getElementStyles, isColorPaletteResolved } = useGlobalChartsContext();
7799
7827
  const chartRef = (0, react.useRef)(null);
7800
- const selectedBarRef = (0, react.useRef)(null);
7828
+ const isPointerFocusRef = (0, react.useRef)(false);
7801
7829
  const [scopeNode, setScopeNode] = (0, react.useState)(null);
7830
+ const tooltipId = (0, react.useId)();
7802
7831
  const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = (0, _visx_tooltip.useTooltip)();
7803
- const { handleBarClick, handleBarKeyDown, clearSelection, getStepState } = useFunnelSelection(hideTooltip);
7832
+ const { selectedStepId, selectStep, clearSelection, getStepState } = useFunnelSelection(hideTooltip);
7833
+ const stepIds = (0, react.useMemo)(() => steps?.map((step) => step.id) ?? [], [steps]);
7834
+ const { getTabIndex, setStepElement, handleStepFocus, handleNavigationKey } = useRovingStepFocus(stepIds, selectedStepId);
7804
7835
  const standaloneScopeClass = useStandaloneScopeClass();
7805
7836
  const [measureChartRef, , chartHeight] = useElementSize();
7806
7837
  const gap = chartHeight > 0 && chartHeight < SHORT_CHART_HEIGHT ? "sm" : "xl";
@@ -7809,94 +7840,71 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
7809
7840
  setScopeNode(node);
7810
7841
  measureChartRef(node);
7811
7842
  }, [measureChartRef]);
7812
- const clearSelectionAndRef = (0, react.useCallback)(() => {
7813
- clearSelection();
7814
- selectedBarRef.current = null;
7815
- hideTooltip();
7816
- }, [clearSelection, hideTooltip]);
7817
- const showTooltipAt = (0, react.useCallback)((step, x, y) => {
7818
- showTooltip({
7843
+ const selectStepAt = (0, react.useCallback)((step, x, y) => {
7844
+ selectStep(step.id);
7845
+ const bounds = chartRef.current?.getBoundingClientRect();
7846
+ if (bounds) showTooltip({
7819
7847
  tooltipData: step,
7820
- tooltipLeft: x,
7821
- tooltipTop: y - 10
7848
+ tooltipLeft: x - bounds.left,
7849
+ tooltipTop: y - bounds.top - 10
7822
7850
  });
7823
- }, [showTooltip]);
7824
- const getMouseTooltipCoords = (0, react.useCallback)((event) => {
7825
- const bounds = chartRef.current?.getBoundingClientRect();
7826
- if (!bounds) return null;
7827
- return {
7828
- x: event.clientX - bounds.left,
7829
- y: event.clientY - bounds.top
7830
- };
7831
- }, []);
7832
- const getKeyboardTooltipCoords = (0, react.useCallback)((event) => {
7833
- const bounds = chartRef.current?.getBoundingClientRect();
7834
- if (!bounds) return null;
7835
- const rect = event.currentTarget.getBoundingClientRect();
7836
- return {
7837
- x: rect.left + rect.width / 2 - bounds.left,
7838
- y: rect.top - bounds.top
7839
- };
7840
- }, []);
7841
- const handleStepInteraction = (0, react.useCallback)((step, event, interactionType) => {
7842
- selectedBarRef.current = event.currentTarget;
7843
- const { isClicked } = getStepState(step.id);
7844
- if (isClicked) {
7845
- if (interactionType === "click") handleBarClick(step.id);
7846
- else handleBarKeyDown(step.id, event);
7847
- return;
7848
- }
7849
- if (interactionType === "click") {
7850
- handleBarClick(step.id);
7851
- const coords = getMouseTooltipCoords(event);
7852
- if (coords) showTooltipAt(step, coords.x, coords.y);
7853
- } else {
7854
- handleBarKeyDown(step.id, event);
7855
- const coords = getKeyboardTooltipCoords(event);
7856
- if (coords) showTooltipAt(step, coords.x, coords.y);
7857
- }
7858
- }, [
7859
- getStepState,
7860
- handleBarClick,
7861
- handleBarKeyDown,
7862
- showTooltipAt,
7863
- getMouseTooltipCoords,
7864
- getKeyboardTooltipCoords
7865
- ]);
7851
+ }, [selectStep, showTooltip]);
7852
+ const selectStepAtElement = (0, react.useCallback)((step, element) => {
7853
+ const rect = element.getBoundingClientRect();
7854
+ selectStepAt(step, rect.left + rect.width / 2, rect.top);
7855
+ }, [selectStepAt]);
7866
7856
  const stepHandlers = (0, react.useMemo)(() => {
7867
7857
  const handlers = /* @__PURE__ */ new Map();
7868
7858
  steps.forEach((step) => {
7859
+ const onPointerDown = () => {
7860
+ isPointerFocusRef.current = true;
7861
+ };
7869
7862
  const onClick = (event) => {
7870
- event.stopPropagation();
7871
- handleStepInteraction(step, event, "click");
7863
+ isPointerFocusRef.current = false;
7864
+ selectStepAt(step, event.clientX, event.clientY);
7865
+ };
7866
+ const onFocus = (event) => {
7867
+ handleStepFocus(step.id);
7868
+ if (isPointerFocusRef.current) isPointerFocusRef.current = false;
7869
+ else if (step.id !== selectedStepId) selectStepAtElement(step, event.currentTarget);
7872
7870
  };
7873
7871
  const onKeyDown = (event) => {
7874
- if (event.key === "Enter" || event.key === " ") handleStepInteraction(step, event, "keyboard");
7875
- else {
7876
- selectedBarRef.current = event.currentTarget;
7877
- handleBarKeyDown(step.id, event);
7872
+ isPointerFocusRef.current = false;
7873
+ if (handleNavigationKey(step.id, event)) return;
7874
+ if (event.key === "Enter" || event.key === " ") {
7875
+ event.preventDefault();
7876
+ selectStepAtElement(step, event.currentTarget);
7877
+ } else if (event.key === "Escape" && selectedStepId !== null) {
7878
+ event.preventDefault();
7879
+ clearSelection();
7878
7880
  }
7879
7881
  };
7882
+ const ref = (element) => setStepElement(step.id, element);
7880
7883
  handlers.set(step.id, {
7884
+ onPointerDown,
7881
7885
  onClick,
7882
- onKeyDown
7886
+ onKeyDown,
7887
+ onFocus,
7888
+ ref
7883
7889
  });
7884
7890
  });
7885
7891
  return handlers;
7886
7892
  }, [
7887
7893
  steps,
7888
- handleStepInteraction,
7889
- handleBarKeyDown
7894
+ selectedStepId,
7895
+ selectStepAt,
7896
+ selectStepAtElement,
7897
+ clearSelection,
7898
+ handleNavigationKey,
7899
+ handleStepFocus,
7900
+ setStepElement
7890
7901
  ]);
7891
- (0, react.useEffect)(() => {
7892
- const handleDocumentClick = (event) => {
7893
- if (selectedBarRef.current && !selectedBarRef.current.contains(event.target)) clearSelectionAndRef();
7894
- };
7895
- document.addEventListener("mousedown", handleDocumentClick);
7896
- return () => {
7897
- document.removeEventListener("mousedown", handleDocumentClick);
7898
- };
7899
- }, [clearSelectionAndRef]);
7902
+ const handleStepsBlur = (0, react.useCallback)((event) => {
7903
+ if (!event.currentTarget.contains(event.relatedTarget) && document.hasFocus()) {
7904
+ isPointerFocusRef.current = false;
7905
+ clearSelection();
7906
+ }
7907
+ }, [clearSelection]);
7900
7908
  const resolvedHeight = height ?? style?.height ?? "100%";
7901
7909
  const { color: barColor } = getElementStyles ? getElementStyles({ index: 0 }) : { color: "#000000" };
7902
7910
  const isPositiveChange = changeIndicator?.startsWith("+");
@@ -7908,18 +7916,41 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
7908
7916
  className: (0, clsx.default)(conversion_funnel_chart_module_default["change-indicator"], conversion_funnel_chart_module_default[isPositiveChange ? "change-indicator--positive" : "change-indicator--negative"]),
7909
7917
  children: changeIndicator
7910
7918
  })] });
7911
- const renderDefaultTooltip = (step) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7912
- direction: "column",
7913
- align: "flex-start",
7914
- gap: "xs",
7915
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7916
- className: conversion_funnel_chart_module_default["tooltip-title"],
7917
- children: step.label
7918
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7919
- className: conversion_funnel_chart_module_default["tooltip-content"],
7920
- children: [formatPercentage(step.rate), ` • ${step.count ?? "no"} items`]
7921
- })]
7922
- });
7919
+ const renderDefaultTooltip = (step, content) => {
7920
+ const ids = getDefaultTooltipIds(tooltipId, content);
7921
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7922
+ direction: "column",
7923
+ gap: "xs",
7924
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7925
+ direction: "row",
7926
+ justify: "space-between",
7927
+ align: "baseline",
7928
+ gap: "sm",
7929
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7930
+ className: conversion_funnel_chart_module_default["tooltip-title"],
7931
+ children: step.label
7932
+ }), content.value && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7933
+ id: ids.value,
7934
+ className: conversion_funnel_chart_module_default["tooltip-value"],
7935
+ children: content.value
7936
+ })]
7937
+ }), content.rows?.map((row, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7938
+ direction: "row",
7939
+ justify: "space-between",
7940
+ align: "baseline",
7941
+ gap: "sm",
7942
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7943
+ id: ids.rows[index].label,
7944
+ className: conversion_funnel_chart_module_default["tooltip-label"],
7945
+ children: row.label
7946
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7947
+ id: ids.rows[index].value,
7948
+ className: conversion_funnel_chart_module_default["tooltip-value"],
7949
+ children: row.value
7950
+ })]
7951
+ }, row.label))]
7952
+ });
7953
+ };
7923
7954
  const isDataValid = Boolean(steps && steps.length > 0);
7924
7955
  const chartMetadata = (0, react.useMemo)(() => ({
7925
7956
  mainRate,
@@ -7954,6 +7985,26 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
7954
7985
  })
7955
7986
  });
7956
7987
  const maxRate = Math.max(...steps.map((step) => step.rate));
7988
+ const tooltipStep = tooltipOpen ? tooltipData : void 0;
7989
+ let tooltipContent = null;
7990
+ let tooltipDescriptionIds = "";
7991
+ if (tooltipStep) {
7992
+ const index = steps.findIndex((s) => s.id === tooltipStep.id);
7993
+ const content = getTooltipContent(tooltipStep, index);
7994
+ if (renderTooltip) {
7995
+ tooltipContent = renderTooltip({
7996
+ step: tooltipStep,
7997
+ index,
7998
+ content,
7999
+ top: tooltipTop,
8000
+ left: tooltipLeft
8001
+ });
8002
+ tooltipDescriptionIds = tooltipId;
8003
+ } else {
8004
+ tooltipContent = renderDefaultTooltip(tooltipStep, content);
8005
+ tooltipDescriptionIds = getDefaultTooltipDescriptionIds(tooltipId, content);
8006
+ }
8007
+ }
7957
8008
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7958
8009
  direction: "column",
7959
8010
  gap,
@@ -7982,10 +8033,16 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
7982
8033
  direction: "row",
7983
8034
  align: "flex-end",
7984
8035
  gap: "lg",
8036
+ role: "listbox",
8037
+ "aria-label": (0, _wordpress_i18n.__)("Funnel steps", "jetpack-charts"),
8038
+ "aria-orientation": "horizontal",
8039
+ onBlur: handleStepsBlur,
7985
8040
  className: conversion_funnel_chart_module_default["funnel-container"],
7986
8041
  children: steps.map((step, index) => {
7987
8042
  const barHeight = step.rate / maxRate * 100;
7988
- const { isBlurred } = getStepState(step.id);
8043
+ const { isSelected, isBlurred } = getStepState(step.id);
8044
+ const handlers = stepHandlers.get(step.id);
8045
+ const isDescribedByTooltip = Boolean(tooltipContent && tooltipDescriptionIds) && tooltipStep?.id === step.id;
7989
8046
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7990
8047
  direction: "column",
7991
8048
  className: (0, clsx.default)(conversion_funnel_chart_module_default["funnel-step"], isColorPaletteResolved && conversion_funnel_chart_module_default["funnel-step--animated"], isBlurred && conversion_funnel_chart_module_default["funnel-step--blurred"]),
@@ -7993,6 +8050,8 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
7993
8050
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
7994
8051
  direction: "column",
7995
8052
  gap: "xs",
8053
+ className: conversion_funnel_chart_module_default["step-text"],
8054
+ "aria-hidden": "true",
7996
8055
  children: [renderStepLabel ? renderStepLabel({
7997
8056
  step,
7998
8057
  index,
@@ -8012,11 +8071,16 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
8012
8071
  direction: "column",
8013
8072
  justify: "flex-end",
8014
8073
  className: conversion_funnel_chart_module_default["bar-container"],
8015
- onClick: stepHandlers.get(step.id)?.onClick,
8016
- onKeyDown: stepHandlers.get(step.id)?.onKeyDown,
8017
- role: "button",
8018
- tabIndex: isBlurred ? -1 : 0,
8019
- "aria-label": step.label,
8074
+ ref: handlers?.ref,
8075
+ onPointerDown: handlers?.onPointerDown,
8076
+ onClick: handlers?.onClick,
8077
+ onKeyDown: handlers?.onKeyDown,
8078
+ onFocus: handlers?.onFocus,
8079
+ role: "option",
8080
+ tabIndex: getTabIndex(step.id),
8081
+ "aria-label": (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("%1$s, %2$s", "jetpack-charts"), step.label, formatPercentage(step.rate)),
8082
+ "aria-selected": isSelected,
8083
+ "aria-describedby": isDescribedByTooltip ? tooltipDescriptionIds : void 0,
8020
8084
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8021
8085
  className: (0, clsx.default)(conversion_funnel_chart_module_default["funnel-bar"], { [conversion_funnel_chart_module_default["funnel-bar--animated"]]: animation && !loading && !prefersReducedMotion }),
8022
8086
  style: {
@@ -8028,25 +8092,17 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
8028
8092
  }, step.id);
8029
8093
  })
8030
8094
  })]
8031
- }), tooltipOpen && tooltipData && (() => {
8032
- const tooltipContent = renderTooltip ? renderTooltip({
8033
- step: tooltipData,
8034
- index: steps.findIndex((s) => s.id === tooltipData.id),
8035
- top: tooltipTop,
8036
- left: tooltipLeft
8037
- }) : renderDefaultTooltip(tooltipData);
8038
- if (!tooltipContent) return null;
8039
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundedTooltip, {
8040
- top: tooltipTop,
8041
- left: tooltipLeft,
8042
- className: standaloneScopeClass,
8043
- style: tooltipStyle,
8044
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8045
- role: "tooltip",
8046
- children: tooltipContent
8047
- })
8048
- });
8049
- })()]
8095
+ }), tooltipContent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundedTooltip, {
8096
+ top: tooltipTop,
8097
+ left: tooltipLeft,
8098
+ className: standaloneScopeClass,
8099
+ style: tooltipStyle,
8100
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8101
+ id: tooltipId,
8102
+ "aria-hidden": "true",
8103
+ children: tooltipContent
8104
+ })
8105
+ })]
8050
8106
  });
8051
8107
  };
8052
8108
  /**
@@ -8060,8 +8116,7 @@ const ConversionFunnelChartWithProvider = (props) => {
8060
8116
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalChartsProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConversionFunnelChartInternal, { ...props }) });
8061
8117
  };
8062
8118
  ConversionFunnelChartWithProvider.displayName = "ConversionFunnelChart";
8063
- //#endregion
8064
- //#region src/utils/sanitize-html.ts
8119
+ // src/utils/sanitize-html.ts
8065
8120
  /**
8066
8121
  * External dependencies
8067
8122
  */
@@ -8109,11 +8164,9 @@ function sanitizeHtml(html) {
8109
8164
  ]
8110
8165
  });
8111
8166
  }
8112
- //#endregion
8113
- //#region src/charts/geo-chart/geo-chart.module.scss
8167
+ // src/charts/geo-chart/geo-chart.module.scss
8114
8168
  var geo_chart_module_default = { "container": "a8ccharts-8hS2IW-container" };
8115
- //#endregion
8116
- //#region src/charts/geo-chart/private/use-tooltip-position.ts
8169
+ // src/charts/geo-chart/private/use-tooltip-position.ts
8117
8170
  const TOOLTIP_CLASS = "google-visualization-tooltip";
8118
8171
  const isTooltip = (node) => node instanceof HTMLElement && node.classList.contains(TOOLTIP_CLASS);
8119
8172
  /**
@@ -8197,8 +8250,7 @@ function useTooltipPosition(containerRef) {
8197
8250
  };
8198
8251
  }, [containerRef]);
8199
8252
  }
8200
- //#endregion
8201
- //#region src/charts/geo-chart/geo-chart.tsx
8253
+ // src/charts/geo-chart/geo-chart.tsx
8202
8254
  /**
8203
8255
  * External dependencies
8204
8256
  */
@@ -8418,8 +8470,7 @@ const GeoChartWithProvider = (props) => {
8418
8470
  };
8419
8471
  GeoChartWithProvider.displayName = "GeoChart";
8420
8472
  const GeoChartResponsive = withResponsive(GeoChartWithProvider);
8421
- //#endregion
8422
- //#region src/types.ts
8473
+ // src/types.ts
8423
8474
  let GoogleDataTableColumnRoleType = /* @__PURE__ */ function(GoogleDataTableColumnRoleType) {
8424
8475
  GoogleDataTableColumnRoleType["annotation"] = "annotation";
8425
8476
  GoogleDataTableColumnRoleType["annotationText"] = "annotationText";
@@ -8499,8 +8550,7 @@ const pickLabelTextColor = (fill, roles, defaultRole) => {
8499
8550
  if (!isValidHexColor(fillHex)) return defaultRole;
8500
8551
  return pickLabelTextColorForFill(hexToRgb(fillHex), roles, defaultRole);
8501
8552
  };
8502
- //#endregion
8503
- //#region src/charts/heatmap-chart/heatmap-chart.module.scss
8553
+ // src/charts/heatmap-chart/heatmap-chart.module.scss
8504
8554
  var heatmap_chart_module_default = {
8505
8555
  "heatmap-chart": "a8ccharts-O3YMOW-heatmap-chart",
8506
8556
  "heatmap-chart__cell": "a8ccharts-O3YMOW-heatmap-chart__cell",
@@ -8531,8 +8581,7 @@ var heatmap_chart_module_default = {
8531
8581
  "heatmap-chart__row-label": "a8ccharts-O3YMOW-heatmap-chart__row-label",
8532
8582
  "heatmap-chart--height-capped": "a8ccharts-O3YMOW-heatmap-chart--height-capped"
8533
8583
  };
8534
- //#endregion
8535
- //#region src/charts/heatmap-chart/private/use-heatmap-colors.ts
8584
+ // src/charts/heatmap-chart/private/use-heatmap-colors.ts
8536
8585
  const isPresent = (value) => value !== null && value !== void 0 && !isNaN(value);
8537
8586
  /**
8538
8587
  * Get the min and max values from heatmap data, ignoring null/NaN and the zeros
@@ -8611,12 +8660,10 @@ const getHeatmapScale = (primary, background, emptyCell) => {
8611
8660
  high
8612
8661
  };
8613
8662
  };
8614
- //#endregion
8615
- //#region src/charts/heatmap-chart/private/heatmap-context.ts
8663
+ // src/charts/heatmap-chart/private/heatmap-context.ts
8616
8664
  /** Shared by the chart and legend without importing back from `heatmap-chart.tsx`. */
8617
8665
  const HeatmapContext = (0, react.createContext)(null);
8618
- //#endregion
8619
- //#region src/charts/heatmap-chart/private/heatmap-legend.tsx
8666
+ // src/charts/heatmap-chart/private/heatmap-legend.tsx
8620
8667
  const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }) => {
8621
8668
  const context = (0, react.useContext)(HeatmapContext);
8622
8669
  const { legend } = useGlobalChartsTheme();
@@ -8660,8 +8707,7 @@ const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }
8660
8707
  ]
8661
8708
  });
8662
8709
  };
8663
- //#endregion
8664
- //#region src/charts/heatmap-chart/private/column-groups.ts
8710
+ // src/charts/heatmap-chart/private/column-groups.ts
8665
8711
  const isSpan = (span) => Number.isInteger(span) && span > 0;
8666
8712
  /**
8667
8713
  * Validates column groups and lays them over the columns.
@@ -8767,8 +8813,7 @@ const wrapColumnGroups = (layout, bands) => {
8767
8813
  slotSpans
8768
8814
  };
8769
8815
  };
8770
- //#endregion
8771
- //#region src/charts/heatmap-chart/private/fit-compact-cells.ts
8816
+ // src/charts/heatmap-chart/private/fit-compact-cells.ts
8772
8817
  /**
8773
8818
  * Largest whole-pixel square cell, and the band count giving it, for a compact grid in a box.
8774
8819
  *
@@ -8806,8 +8851,7 @@ const fitCompactCells = (input) => {
8806
8851
  cellSize: minCellSize
8807
8852
  };
8808
8853
  };
8809
- //#endregion
8810
- //#region src/charts/heatmap-chart/private/keyboard-navigation.ts
8854
+ // src/charts/heatmap-chart/private/keyboard-navigation.ts
8811
8855
  const ARROW_KEYS = [
8812
8856
  "ArrowLeft",
8813
8857
  "ArrowRight",
@@ -8937,8 +8981,7 @@ const stepCalendarCell = (grid, blocks, from, key) => {
8937
8981
  const before = page.slice(0, at === -1 ? page.length : at).reverse();
8938
8982
  return firstSelectable(grid, after) ?? firstSelectable(grid, before);
8939
8983
  };
8940
- //#endregion
8941
- //#region src/charts/heatmap-chart/heatmap-chart.tsx
8984
+ // src/charts/heatmap-chart/heatmap-chart.tsx
8942
8985
  const CELL_VALUE_MODIFIER = {
8943
8986
  label: void 0,
8944
8987
  "label-inverse": heatmap_chart_module_default["heatmap-chart__cell-value--inverse"],
@@ -9393,8 +9436,7 @@ const HeatmapChartResponsiveInner = (props) => /* @__PURE__ */ (0, react_jsx_run
9393
9436
  });
9394
9437
  HeatmapChartResponsiveInner.displayName = "HeatmapChart";
9395
9438
  const HeatmapChartResponsive = attachSubComponents(withResponsive(HeatmapChartResponsiveInner), { Legend: HeatmapLegend });
9396
- //#endregion
9397
- //#region src/charts/heatmap-chart/private/civil-day.ts
9439
+ // src/charts/heatmap-chart/private/civil-day.ts
9398
9440
  const DAY_MS = 864e5;
9399
9441
  const KEY_OPTIONS = {
9400
9442
  calendar: "gregory",
@@ -9543,8 +9585,7 @@ const startOfCivilWeek = (date, weekStartsOn) => {
9543
9585
  * @return Columns needed to cover the span, inclusive.
9544
9586
  */
9545
9587
  const civilWeekSpan = (from, to, weekStartsOn) => Math.floor((startOfCivilWeek(to, weekStartsOn).getTime() - startOfCivilWeek(from, weekStartsOn).getTime()) / (7 * DAY_MS)) + 1;
9546
- //#endregion
9547
- //#region src/charts/heatmap-chart/build-calendar-data.ts
9588
+ // src/charts/heatmap-chart/build-calendar-data.ts
9548
9589
  /** Rows that get a weekday label (Mon, Wed, Fri with a Monday week start). */
9549
9590
  const LABELLED_ROWS = [
9550
9591
  0,
@@ -9646,8 +9687,7 @@ const buildCalendarHeatmapData = (series, options = {}) => {
9646
9687
  rowLabels
9647
9688
  };
9648
9689
  };
9649
- //#endregion
9650
- //#region src/charts/heatmap-chart/build-month-calendar-data.ts
9690
+ // src/charts/heatmap-chart/build-month-calendar-data.ts
9651
9691
  /** Week rows per month, fixed so every month block is the same height. */
9652
9692
  const MONTH_ROWS = 6;
9653
9693
  const DAYS_PER_WEEK = 7;
@@ -9729,8 +9769,7 @@ const buildMonthCalendarHeatmapData = (valueByDay, range, options = {}) => {
9729
9769
  columnGroups
9730
9770
  };
9731
9771
  };
9732
- //#endregion
9733
- //#region src/charts/heatmap-chart/use-calendar-heatmap-data.ts
9772
+ // src/charts/heatmap-chart/use-calendar-heatmap-data.ts
9734
9773
  /**
9735
9774
  * `buildCalendarHeatmapData` with the locale and zone taken from
9736
9775
  * `GlobalChartsProvider` where the caller names neither.
@@ -9765,8 +9804,7 @@ const useCalendarHeatmapData = (series, options = {}) => {
9765
9804
  gridEnd
9766
9805
  ]);
9767
9806
  };
9768
- //#endregion
9769
- //#region src/charts/heatmap-chart/use-month-calendar-heatmap-data.ts
9807
+ // src/charts/heatmap-chart/use-month-calendar-heatmap-data.ts
9770
9808
  /**
9771
9809
  * `buildMonthCalendarHeatmapData` with the locale taken from `GlobalChartsProvider`
9772
9810
  * where the caller names none.
@@ -9795,8 +9833,7 @@ const useMonthCalendarHeatmapData = (valueByDay, range, options = {}) => {
9795
9833
  weekStartsOn
9796
9834
  ]);
9797
9835
  };
9798
- //#endregion
9799
- //#region ../../../node_modules/.pnpm/is-plain-object@5.1.0/node_modules/is-plain-object/dist/is-plain-object.mjs
9836
+ // ../../../node_modules/.pnpm/is-plain-object@5.1.0/node_modules/is-plain-object/dist/is-plain-object.mjs
9800
9837
  /*!
9801
9838
  * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
9802
9839
  *
@@ -9816,8 +9853,7 @@ function isPlainObject(o) {
9816
9853
  if (prot.hasOwnProperty("isPrototypeOf") === false) return false;
9817
9854
  return true;
9818
9855
  }
9819
- //#endregion
9820
- //#region ../../../node_modules/.pnpm/lower-case@2.0.2/node_modules/lower-case/dist/index.js
9856
+ // ../../../node_modules/.pnpm/lower-case@2.0.2/node_modules/lower-case/dist/index.js
9821
9857
  var require_dist$14 = /* @__PURE__ */ __commonJSMin(((exports) => {
9822
9858
  Object.defineProperty(exports, "__esModule", { value: true });
9823
9859
  exports.lowerCase = exports.localeLowerCase = void 0;
@@ -9872,8 +9908,7 @@ var require_dist$14 = /* @__PURE__ */ __commonJSMin(((exports) => {
9872
9908
  }
9873
9909
  exports.lowerCase = lowerCase;
9874
9910
  }));
9875
- //#endregion
9876
- //#region ../../../node_modules/.pnpm/no-case@3.0.4/node_modules/no-case/dist/index.js
9911
+ // ../../../node_modules/.pnpm/no-case@3.0.4/node_modules/no-case/dist/index.js
9877
9912
  var require_dist$13 = /* @__PURE__ */ __commonJSMin(((exports) => {
9878
9913
  Object.defineProperty(exports, "__esModule", { value: true });
9879
9914
  exports.noCase = void 0;
@@ -9904,8 +9939,7 @@ var require_dist$13 = /* @__PURE__ */ __commonJSMin(((exports) => {
9904
9939
  }, input);
9905
9940
  }
9906
9941
  }));
9907
- //#endregion
9908
- //#region ../../../node_modules/.pnpm/pascal-case@3.1.2/node_modules/pascal-case/dist/index.js
9942
+ // ../../../node_modules/.pnpm/pascal-case@3.1.2/node_modules/pascal-case/dist/index.js
9909
9943
  var require_dist$12 = /* @__PURE__ */ __commonJSMin(((exports) => {
9910
9944
  Object.defineProperty(exports, "__esModule", { value: true });
9911
9945
  exports.pascalCase = exports.pascalCaseTransformMerge = exports.pascalCaseTransform = void 0;
@@ -9931,8 +9965,7 @@ var require_dist$12 = /* @__PURE__ */ __commonJSMin(((exports) => {
9931
9965
  }
9932
9966
  exports.pascalCase = pascalCase;
9933
9967
  }));
9934
- //#endregion
9935
- //#region ../../../node_modules/.pnpm/camel-case@4.1.2/node_modules/camel-case/dist/index.js
9968
+ // ../../../node_modules/.pnpm/camel-case@4.1.2/node_modules/camel-case/dist/index.js
9936
9969
  var require_dist$11 = /* @__PURE__ */ __commonJSMin(((exports) => {
9937
9970
  Object.defineProperty(exports, "__esModule", { value: true });
9938
9971
  exports.camelCase = exports.camelCaseTransformMerge = exports.camelCaseTransform = void 0;
@@ -9954,8 +9987,7 @@ var require_dist$11 = /* @__PURE__ */ __commonJSMin(((exports) => {
9954
9987
  }
9955
9988
  exports.camelCase = camelCase;
9956
9989
  }));
9957
- //#endregion
9958
- //#region ../../../node_modules/.pnpm/upper-case-first@2.0.2/node_modules/upper-case-first/dist/index.js
9990
+ // ../../../node_modules/.pnpm/upper-case-first@2.0.2/node_modules/upper-case-first/dist/index.js
9959
9991
  var require_dist$10 = /* @__PURE__ */ __commonJSMin(((exports) => {
9960
9992
  Object.defineProperty(exports, "__esModule", { value: true });
9961
9993
  exports.upperCaseFirst = void 0;
@@ -9967,8 +9999,7 @@ var require_dist$10 = /* @__PURE__ */ __commonJSMin(((exports) => {
9967
9999
  }
9968
10000
  exports.upperCaseFirst = upperCaseFirst;
9969
10001
  }));
9970
- //#endregion
9971
- //#region ../../../node_modules/.pnpm/capital-case@1.0.4/node_modules/capital-case/dist/index.js
10002
+ // ../../../node_modules/.pnpm/capital-case@1.0.4/node_modules/capital-case/dist/index.js
9972
10003
  var require_dist$9 = /* @__PURE__ */ __commonJSMin(((exports) => {
9973
10004
  Object.defineProperty(exports, "__esModule", { value: true });
9974
10005
  exports.capitalCase = exports.capitalCaseTransform = void 0;
@@ -9988,8 +10019,7 @@ var require_dist$9 = /* @__PURE__ */ __commonJSMin(((exports) => {
9988
10019
  }
9989
10020
  exports.capitalCase = capitalCase;
9990
10021
  }));
9991
- //#endregion
9992
- //#region ../../../node_modules/.pnpm/upper-case@2.0.2/node_modules/upper-case/dist/index.js
10022
+ // ../../../node_modules/.pnpm/upper-case@2.0.2/node_modules/upper-case/dist/index.js
9993
10023
  var require_dist$8 = /* @__PURE__ */ __commonJSMin(((exports) => {
9994
10024
  Object.defineProperty(exports, "__esModule", { value: true });
9995
10025
  exports.upperCase = exports.localeUpperCase = void 0;
@@ -10036,8 +10066,7 @@ var require_dist$8 = /* @__PURE__ */ __commonJSMin(((exports) => {
10036
10066
  }
10037
10067
  exports.upperCase = upperCase;
10038
10068
  }));
10039
- //#endregion
10040
- //#region ../../../node_modules/.pnpm/constant-case@3.0.4/node_modules/constant-case/dist/index.js
10069
+ // ../../../node_modules/.pnpm/constant-case@3.0.4/node_modules/constant-case/dist/index.js
10041
10070
  var require_dist$7 = /* @__PURE__ */ __commonJSMin(((exports) => {
10042
10071
  Object.defineProperty(exports, "__esModule", { value: true });
10043
10072
  exports.constantCase = void 0;
@@ -10053,8 +10082,7 @@ var require_dist$7 = /* @__PURE__ */ __commonJSMin(((exports) => {
10053
10082
  }
10054
10083
  exports.constantCase = constantCase;
10055
10084
  }));
10056
- //#endregion
10057
- //#region ../../../node_modules/.pnpm/dot-case@3.0.4/node_modules/dot-case/dist/index.js
10085
+ // ../../../node_modules/.pnpm/dot-case@3.0.4/node_modules/dot-case/dist/index.js
10058
10086
  var require_dist$6 = /* @__PURE__ */ __commonJSMin(((exports) => {
10059
10087
  Object.defineProperty(exports, "__esModule", { value: true });
10060
10088
  exports.dotCase = void 0;
@@ -10066,8 +10094,7 @@ var require_dist$6 = /* @__PURE__ */ __commonJSMin(((exports) => {
10066
10094
  }
10067
10095
  exports.dotCase = dotCase;
10068
10096
  }));
10069
- //#endregion
10070
- //#region ../../../node_modules/.pnpm/header-case@2.0.4/node_modules/header-case/dist/index.js
10097
+ // ../../../node_modules/.pnpm/header-case@2.0.4/node_modules/header-case/dist/index.js
10071
10098
  var require_dist$5 = /* @__PURE__ */ __commonJSMin(((exports) => {
10072
10099
  Object.defineProperty(exports, "__esModule", { value: true });
10073
10100
  exports.headerCase = void 0;
@@ -10079,8 +10106,7 @@ var require_dist$5 = /* @__PURE__ */ __commonJSMin(((exports) => {
10079
10106
  }
10080
10107
  exports.headerCase = headerCase;
10081
10108
  }));
10082
- //#endregion
10083
- //#region ../../../node_modules/.pnpm/param-case@3.0.4/node_modules/param-case/dist/index.js
10109
+ // ../../../node_modules/.pnpm/param-case@3.0.4/node_modules/param-case/dist/index.js
10084
10110
  var require_dist$4 = /* @__PURE__ */ __commonJSMin(((exports) => {
10085
10111
  Object.defineProperty(exports, "__esModule", { value: true });
10086
10112
  exports.paramCase = void 0;
@@ -10092,8 +10118,7 @@ var require_dist$4 = /* @__PURE__ */ __commonJSMin(((exports) => {
10092
10118
  }
10093
10119
  exports.paramCase = paramCase;
10094
10120
  }));
10095
- //#endregion
10096
- //#region ../../../node_modules/.pnpm/path-case@3.0.4/node_modules/path-case/dist/index.js
10121
+ // ../../../node_modules/.pnpm/path-case@3.0.4/node_modules/path-case/dist/index.js
10097
10122
  var require_dist$3 = /* @__PURE__ */ __commonJSMin(((exports) => {
10098
10123
  Object.defineProperty(exports, "__esModule", { value: true });
10099
10124
  exports.pathCase = void 0;
@@ -10105,8 +10130,7 @@ var require_dist$3 = /* @__PURE__ */ __commonJSMin(((exports) => {
10105
10130
  }
10106
10131
  exports.pathCase = pathCase;
10107
10132
  }));
10108
- //#endregion
10109
- //#region ../../../node_modules/.pnpm/sentence-case@3.0.4/node_modules/sentence-case/dist/index.js
10133
+ // ../../../node_modules/.pnpm/sentence-case@3.0.4/node_modules/sentence-case/dist/index.js
10110
10134
  var require_dist$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
10111
10135
  Object.defineProperty(exports, "__esModule", { value: true });
10112
10136
  exports.sentenceCase = exports.sentenceCaseTransform = void 0;
@@ -10128,8 +10152,7 @@ var require_dist$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
10128
10152
  }
10129
10153
  exports.sentenceCase = sentenceCase;
10130
10154
  }));
10131
- //#endregion
10132
- //#region ../../../node_modules/.pnpm/snake-case@3.0.4/node_modules/snake-case/dist/index.js
10155
+ // ../../../node_modules/.pnpm/snake-case@3.0.4/node_modules/snake-case/dist/index.js
10133
10156
  var require_dist$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
10134
10157
  Object.defineProperty(exports, "__esModule", { value: true });
10135
10158
  exports.snakeCase = void 0;
@@ -10141,8 +10164,7 @@ var require_dist$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
10141
10164
  }
10142
10165
  exports.snakeCase = snakeCase;
10143
10166
  }));
10144
- //#endregion
10145
- //#region ../../../node_modules/.pnpm/change-case@4.1.2/node_modules/change-case/dist/index.js
10167
+ // ../../../node_modules/.pnpm/change-case@4.1.2/node_modules/change-case/dist/index.js
10146
10168
  var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
10147
10169
  Object.defineProperty(exports, "__esModule", { value: true });
10148
10170
  var tslib_1 = require("tslib");
@@ -10158,11 +10180,9 @@ var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
10158
10180
  tslib_1.__exportStar(require_dist$2(), exports);
10159
10181
  tslib_1.__exportStar(require_dist$1(), exports);
10160
10182
  }));
10161
- //#endregion
10162
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.57.0/node_modules/@wordpress/warning/build-module/utils.mjs
10183
+ // ../../../node_modules/.pnpm/@wordpress+warning@3.57.0/node_modules/@wordpress/warning/build-module/utils.mjs
10163
10184
  var logged = /* @__PURE__ */ new Set();
10164
- //#endregion
10165
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.57.0/node_modules/@wordpress/warning/build-module/index.mjs
10185
+ // ../../../node_modules/.pnpm/@wordpress+warning@3.57.0/node_modules/@wordpress/warning/build-module/index.mjs
10166
10186
  function isDev() {
10167
10187
  return globalThis.SCRIPT_DEBUG === true;
10168
10188
  }
@@ -10175,8 +10195,7 @@ function warning(message) {
10175
10195
  } catch {}
10176
10196
  logged.add(message);
10177
10197
  }
10178
- //#endregion
10179
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
10198
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
10180
10199
  function useUpdateEffect(effect, deps) {
10181
10200
  const mountedRef = (0, react.useRef)(false);
10182
10201
  (0, react.useEffect)(() => {
@@ -10188,8 +10207,7 @@ function useUpdateEffect(effect, deps) {
10188
10207
  }, []);
10189
10208
  }
10190
10209
  var use_update_effect_default = useUpdateEffect;
10191
- //#endregion
10192
- //#region ../../../node_modules/.pnpm/@emotion+sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js
10210
+ // ../../../node_modules/.pnpm/@emotion+sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js
10193
10211
  function sheetForTag(tag) {
10194
10212
  if (tag.sheet) return tag.sheet;
10195
10213
  /* istanbul ignore next */
@@ -10251,8 +10269,7 @@ var StyleSheet = /*#__PURE__*/ function() {
10251
10269
  };
10252
10270
  return StyleSheet;
10253
10271
  }();
10254
- //#endregion
10255
- //#region ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js
10272
+ // ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js
10256
10273
  var MS = "-ms-";
10257
10274
  var MOZ = "-moz-";
10258
10275
  var WEBKIT = "-webkit-";
@@ -10262,8 +10279,7 @@ var DECLARATION = "decl";
10262
10279
  var IMPORT = "@import";
10263
10280
  var KEYFRAMES = "@keyframes";
10264
10281
  var LAYER = "@layer";
10265
- //#endregion
10266
- //#region ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js
10282
+ // ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js
10267
10283
  /**
10268
10284
  * @param {number}
10269
10285
  * @return {number}
@@ -10366,8 +10382,7 @@ function append(value, array) {
10366
10382
  function combine(array, callback) {
10367
10383
  return array.map(callback).join("");
10368
10384
  }
10369
- //#endregion
10370
- //#region ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js
10385
+ // ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js
10371
10386
  var line = 1;
10372
10387
  var column = 1;
10373
10388
  var length = 0;
@@ -10553,8 +10568,7 @@ function identifier(index) {
10553
10568
  while (!token(peek())) next();
10554
10569
  return slice(index, position);
10555
10570
  }
10556
- //#endregion
10557
- //#region ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js
10571
+ // ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js
10558
10572
  /**
10559
10573
  * @param {string} value
10560
10574
  * @return {object[]}
@@ -10707,8 +10721,7 @@ function comment(value, root, parent) {
10707
10721
  function declaration(value, root, parent, length) {
10708
10722
  return node(value, root, parent, DECLARATION, substr(value, 0, length), substr(value, length + 1, -1), length);
10709
10723
  }
10710
- //#endregion
10711
- //#region ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js
10724
+ // ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js
10712
10725
  /**
10713
10726
  * @param {object[]} children
10714
10727
  * @param {function} callback
@@ -10738,8 +10751,7 @@ function stringify(element, index, children, callback) {
10738
10751
  }
10739
10752
  return strlen(children = serialize(element.children, callback)) ? element.return = element.value + "{" + children + "}" : "";
10740
10753
  }
10741
- //#endregion
10742
- //#region ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js
10754
+ // ../../../node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js
10743
10755
  /**
10744
10756
  * @param {function[]} collection
10745
10757
  * @return {function}
@@ -10763,8 +10775,7 @@ function rulesheet(callback) {
10763
10775
  }
10764
10776
  };
10765
10777
  }
10766
- //#endregion
10767
- //#region ../../../node_modules/.pnpm/@emotion+weak-memoize@0.4.0/node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js
10778
+ // ../../../node_modules/.pnpm/@emotion+weak-memoize@0.4.0/node_modules/@emotion/weak-memoize/dist/emotion-weak-memoize.esm.js
10768
10779
  var weakMemoize = function weakMemoize(func) {
10769
10780
  var cache = /* @__PURE__ */ new WeakMap();
10770
10781
  return function(arg) {
@@ -10774,8 +10785,7 @@ var weakMemoize = function weakMemoize(func) {
10774
10785
  return ret;
10775
10786
  };
10776
10787
  };
10777
- //#endregion
10778
- //#region ../../../node_modules/.pnpm/@emotion+memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js
10788
+ // ../../../node_modules/.pnpm/@emotion+memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js
10779
10789
  function memoize(fn) {
10780
10790
  var cache = Object.create(null);
10781
10791
  return function(arg) {
@@ -10783,8 +10793,7 @@ function memoize(fn) {
10783
10793
  return cache[arg];
10784
10794
  };
10785
10795
  }
10786
- //#endregion
10787
- //#region ../../../node_modules/.pnpm/@emotion+cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.esm.js
10796
+ // ../../../node_modules/.pnpm/@emotion+cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.esm.js
10788
10797
  var isBrowser$2 = typeof document !== "undefined";
10789
10798
  var identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) {
10790
10799
  var previous = 0;
@@ -11042,8 +11051,7 @@ var createCache = function createCache(options) {
11042
11051
  cache.sheet.hydrate(nodesToHydrate);
11043
11052
  return cache;
11044
11053
  };
11045
- //#endregion
11046
- //#region ../../../node_modules/.pnpm/@emotion+utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.esm.js
11054
+ // ../../../node_modules/.pnpm/@emotion+utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.esm.js
11047
11055
  var isBrowser$1 = typeof document !== "undefined";
11048
11056
  function getRegisteredStyles$1(registered, registeredStyles, classNames) {
11049
11057
  var rawClassName = "";
@@ -11071,8 +11079,7 @@ var insertStyles = function insertStyles(cache, serialized, isStringTag) {
11071
11079
  if (!isBrowser$1 && stylesForSSR.length !== 0) return stylesForSSR;
11072
11080
  }
11073
11081
  };
11074
- //#endregion
11075
- //#region ../../../node_modules/.pnpm/@emotion+hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js
11082
+ // ../../../node_modules/.pnpm/@emotion+hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js
11076
11083
  function murmur2(str) {
11077
11084
  var h = 0;
11078
11085
  var k, i = 0, len = str.length;
@@ -11093,8 +11100,7 @@ function murmur2(str) {
11093
11100
  h = (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
11094
11101
  return ((h ^ h >>> 15) >>> 0).toString(36);
11095
11102
  }
11096
- //#endregion
11097
- //#region ../../../node_modules/.pnpm/@emotion+unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js
11103
+ // ../../../node_modules/.pnpm/@emotion+unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js
11098
11104
  var unitlessKeys = {
11099
11105
  animationIterationCount: 1,
11100
11106
  aspectRatio: 1,
@@ -11144,8 +11150,7 @@ var unitlessKeys = {
11144
11150
  strokeOpacity: 1,
11145
11151
  strokeWidth: 1
11146
11152
  };
11147
- //#endregion
11148
- //#region ../../../node_modules/.pnpm/@emotion+serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js
11153
+ // ../../../node_modules/.pnpm/@emotion+serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js
11149
11154
  var isDevelopment = false;
11150
11155
  var hyphenateRegex = /[A-Z]|^ms/g;
11151
11156
  var animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g;
@@ -11270,8 +11275,7 @@ function serializeStyles(args, registered, mergedProps) {
11270
11275
  };
11271
11276
  }
11272
11277
  react["useInsertionEffect"] && react["useInsertionEffect"] || react.useLayoutEffect;
11273
- //#endregion
11274
- //#region ../../../node_modules/.pnpm/@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.0/node_modules/@emotion/react/dist/emotion-element-d59e098f.esm.js
11278
+ // ../../../node_modules/.pnpm/@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.0/node_modules/@emotion/react/dist/emotion-element-d59e098f.esm.js
11275
11279
  var isBrowser = typeof document !== "undefined";
11276
11280
  var EmotionCacheContext = /* #__PURE__ */ react.createContext(typeof HTMLElement !== "undefined" ? /* #__PURE__ */ createCache({ key: "css" }) : null);
11277
11281
  EmotionCacheContext.Provider;
@@ -11280,8 +11284,7 @@ var __unsafe_useEmotionCache = function useEmotionCache() {
11280
11284
  };
11281
11285
  if (!isBrowser);
11282
11286
  ({}).hasOwnProperty;
11283
- //#endregion
11284
- //#region ../../../node_modules/.pnpm/@emotion+css@11.13.5/node_modules/@emotion/css/create-instance/dist/emotion-css-create-instance.esm.js
11287
+ // ../../../node_modules/.pnpm/@emotion+css@11.13.5/node_modules/@emotion/css/create-instance/dist/emotion-css-create-instance.esm.js
11285
11288
  function insertWithoutScoping(cache, serialized) {
11286
11289
  if (cache.inserted[serialized.name] === void 0) return cache.insert("", serialized, cache.sheet, true);
11287
11290
  }
@@ -11366,8 +11369,7 @@ var classnames = function classnames(args) {
11366
11369
  }
11367
11370
  return cls;
11368
11371
  };
11369
- //#endregion
11370
- //#region ../../../node_modules/.pnpm/@emotion+css@11.13.5/node_modules/@emotion/css/dist/emotion-css.esm.js
11372
+ // ../../../node_modules/.pnpm/@emotion+css@11.13.5/node_modules/@emotion/css/dist/emotion-css.esm.js
11371
11373
  var _createEmotion = createEmotion({ key: "css" });
11372
11374
  _createEmotion.flush;
11373
11375
  _createEmotion.hydrate;
@@ -11379,8 +11381,7 @@ _createEmotion.keyframes;
11379
11381
  _createEmotion.css;
11380
11382
  _createEmotion.sheet;
11381
11383
  _createEmotion.cache;
11382
- //#endregion
11383
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/hooks/use-cx.mjs
11384
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/hooks/use-cx.mjs
11384
11385
  var isSerializedStyles = (o) => typeof o !== "undefined" && o !== null && ["name", "styles"].every((p) => typeof o[p] !== "undefined");
11385
11386
  var useCx = () => {
11386
11387
  const cache = __unsafe_useEmotionCache();
@@ -11395,8 +11396,7 @@ var useCx = () => {
11395
11396
  }));
11396
11397
  }, [cache]);
11397
11398
  };
11398
- //#endregion
11399
- //#region ../../../node_modules/.pnpm/memize@2.1.1/node_modules/memize/dist/index.js
11399
+ // ../../../node_modules/.pnpm/memize@2.1.1/node_modules/memize/dist/index.js
11400
11400
  /**
11401
11401
  * Memize options object.
11402
11402
  *
@@ -11486,8 +11486,7 @@ function memize(fn, options) {
11486
11486
  };
11487
11487
  return memoized;
11488
11488
  }
11489
- //#endregion
11490
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
11489
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
11491
11490
  var import_es6 = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
11492
11491
  module.exports = function equal(a, b) {
11493
11492
  if (a === b) return true;
@@ -11554,20 +11553,17 @@ var BaseContextSystemProvider = ({ children, value }) => {
11554
11553
  });
11555
11554
  };
11556
11555
  (0, react.memo)(BaseContextSystemProvider);
11557
- //#endregion
11558
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/constants.mjs
11556
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/constants.mjs
11559
11557
  var COMPONENT_NAMESPACE = "data-wp-component";
11560
11558
  var CONNECTED_NAMESPACE = "data-wp-c16t";
11561
11559
  var CONNECT_STATIC_NAMESPACE = "__contextSystemKey__";
11562
- //#endregion
11563
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/get-styled-class-name-from-key.mjs
11560
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/get-styled-class-name-from-key.mjs
11564
11561
  var import_dist = require_dist();
11565
11562
  function getStyledClassName(namespace) {
11566
11563
  return `components-${(0, import_dist.paramCase)(namespace)}`;
11567
11564
  }
11568
11565
  var getStyledClassNameFromKey = memize(getStyledClassName);
11569
- //#endregion
11570
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/context-connect.mjs
11566
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/context-connect.mjs
11571
11567
  function contextConnect(Component, namespace) {
11572
11568
  return _contextConnect(Component, namespace, { forwardsRef: true });
11573
11569
  }
@@ -11583,16 +11579,14 @@ function _contextConnect(Component, namespace, options) {
11583
11579
  selector: `.${getStyledClassNameFromKey(namespace)}`
11584
11580
  });
11585
11581
  }
11586
- //#endregion
11587
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/utils.mjs
11582
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/utils.mjs
11588
11583
  function getNamespace(componentName) {
11589
11584
  return { [COMPONENT_NAMESPACE]: componentName };
11590
11585
  }
11591
11586
  function getConnectedNamespace() {
11592
11587
  return { [CONNECTED_NAMESPACE]: true };
11593
11588
  }
11594
- //#endregion
11595
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/use-context-system.mjs
11589
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/context/use-context-system.mjs
11596
11590
  function useContextSystem(props, namespace) {
11597
11591
  const contextSystemProps = useComponentsContext();
11598
11592
  if (typeof namespace === "undefined") globalThis.SCRIPT_DEBUG === true && warning("useContextSystem: Please provide a namespace");
@@ -11613,8 +11607,7 @@ function useContextSystem(props, namespace) {
11613
11607
  finalComponentProps.className = classes;
11614
11608
  return finalComponentProps;
11615
11609
  }
11616
- //#endregion
11617
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/visually-hidden/styles.mjs
11610
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/visually-hidden/styles.mjs
11618
11611
  var visuallyHidden = {
11619
11612
  border: 0,
11620
11613
  clip: "rect(1px, 1px, 1px, 1px)",
@@ -11629,8 +11622,7 @@ var visuallyHidden = {
11629
11622
  wordWrap: "normal",
11630
11623
  wordBreak: "normal"
11631
11624
  };
11632
- //#endregion
11633
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/polymorphic-element.mjs
11625
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/polymorphic-element.mjs
11634
11626
  var customAttributeRegExp = /^(data|aria|x)-/i;
11635
11627
  var eventHandlerRegExp = /^on[A-Z]/;
11636
11628
  var svgElementNames = new Set(`animate animateMotion animateTransform circle clipPath defs desc ellipse
@@ -11719,8 +11711,7 @@ function UnforwardedPolymorphicElement({ as, ...props }, ref) {
11719
11711
  });
11720
11712
  }
11721
11713
  var PolymorphicElement = (0, react.forwardRef)(UnforwardedPolymorphicElement);
11722
- //#endregion
11723
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/view/component.mjs
11714
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/view/component.mjs
11724
11715
  function UnforwardedView({ css, ...restProps }, ref) {
11725
11716
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PolymorphicElement, {
11726
11717
  ref,
@@ -11728,8 +11719,7 @@ function UnforwardedView({ css, ...restProps }, ref) {
11728
11719
  });
11729
11720
  }
11730
11721
  var component_default$2 = Object.assign((0, react.forwardRef)(UnforwardedView), { selector: ".components-view" });
11731
- //#endregion
11732
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/visually-hidden/component.mjs
11722
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/visually-hidden/component.mjs
11733
11723
  function UnconnectedVisuallyHidden(props, forwardedRef) {
11734
11724
  const { style: styleProp, ...contextProps } = useContextSystem(props, "VisuallyHidden");
11735
11725
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$2, {
@@ -11743,8 +11733,7 @@ function UnconnectedVisuallyHidden(props, forwardedRef) {
11743
11733
  });
11744
11734
  }
11745
11735
  var component_default$1 = contextConnect(UnconnectedVisuallyHidden, "VisuallyHidden");
11746
- //#endregion
11747
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/use-responsive-value.mjs
11736
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/utils/use-responsive-value.mjs
11748
11737
  var breakpoints = [
11749
11738
  "40em",
11750
11739
  "52em",
@@ -11782,8 +11771,7 @@ function useResponsiveValue(values, options = {}) {
11782
11771
  const array = values || [];
11783
11772
  return array[index >= array.length ? array.length - 1 : index];
11784
11773
  }
11785
- //#endregion
11786
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/grid/utils.mjs
11774
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/grid/utils.mjs
11787
11775
  var ALIGNMENTS = {
11788
11776
  bottom: {
11789
11777
  alignItems: "flex-end",
@@ -11830,8 +11818,7 @@ var ALIGNMENTS = {
11830
11818
  function getAlignmentProps(alignment) {
11831
11819
  return alignment ? ALIGNMENTS[alignment] ?? {} : {};
11832
11820
  }
11833
- //#endregion
11834
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/grid/hook.mjs
11821
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/grid/hook.mjs
11835
11822
  var STYLE_HASH_ATTRIBUTE = "data-wp-hash";
11836
11823
  function getRuntime() {
11837
11824
  const globalScope = globalThis;
@@ -11975,8 +11962,7 @@ function useGrid(props) {
11975
11962
  }
11976
11963
  };
11977
11964
  }
11978
- //#endregion
11979
- //#region ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/grid/component.mjs
11965
+ // ../../../node_modules/.pnpm/@wordpress+components@42.0.0_@date-fns+tz@1.5.0_@types+react-dom@19.3.0_@types+react@19_6d0393a58a031b78f608040e2ecbe6e0/node_modules/@wordpress/components/build-module/grid/component.mjs
11980
11966
  function UnconnectedGrid(props, forwardedRef) {
11981
11967
  const gridProps = useGrid(props);
11982
11968
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$2, {
@@ -11985,8 +11971,7 @@ function UnconnectedGrid(props, forwardedRef) {
11985
11971
  });
11986
11972
  }
11987
11973
  var component_default = contextConnect(UnconnectedGrid, "Grid");
11988
- //#endregion
11989
- //#region src/charts/leaderboard-chart/hooks/use-fitted-row-count.ts
11974
+ // src/charts/leaderboard-chart/hooks/use-fitted-row-count.ts
11990
11975
  /**
11991
11976
  * Fractional layout rounding can put a row's bottom a hair past the container's
11992
11977
  * without any visible clipping. Allow that much slack before hiding a row.
@@ -12069,8 +12054,7 @@ function useFittedRowCount(enabled, rowCount, data) {
12069
12054
  isMeasurable
12070
12055
  };
12071
12056
  }
12072
- //#endregion
12073
- //#region src/charts/leaderboard-chart/hooks/use-leaderboard-legend-items.ts
12057
+ // src/charts/leaderboard-chart/hooks/use-leaderboard-legend-items.ts
12074
12058
  /**
12075
12059
  * Hook to create legend items from leaderboard data
12076
12060
  * @param root0 - Configuration object
@@ -12118,11 +12102,12 @@ function useLeaderboardLegendItems({ data, primaryColor, secondaryColor, withCom
12118
12102
  withOverlayLabel
12119
12103
  ]);
12120
12104
  }
12121
- //#endregion
12122
- //#region src/charts/leaderboard-chart/leaderboard-chart.module.scss
12105
+ // src/charts/leaderboard-chart/leaderboard-chart.module.scss
12123
12106
  var leaderboard_chart_module_default = {
12124
12107
  "bar": "a8ccharts-GovfoW-bar",
12125
12108
  "bar--animated": "a8ccharts-GovfoW-bar--animated",
12109
+ "bar--negative": "a8ccharts-GovfoW-bar--negative",
12110
+ "barTrack": "a8ccharts-GovfoW-barTrack",
12126
12111
  "barWithLabelContainer": "a8ccharts-GovfoW-barWithLabelContainer",
12127
12112
  "chevron": "a8ccharts-GovfoW-chevron",
12128
12113
  "deltaPlaceholder": "a8ccharts-GovfoW-deltaPlaceholder",
@@ -12149,8 +12134,7 @@ var leaderboard_chart_module_default = {
12149
12134
  "stretch": "a8ccharts-GovfoW-stretch",
12150
12135
  "valueContainer": "a8ccharts-GovfoW-valueContainer"
12151
12136
  };
12152
- //#endregion
12153
- //#region src/charts/leaderboard-chart/leaderboard-chart.tsx
12137
+ // src/charts/leaderboard-chart/leaderboard-chart.tsx
12154
12138
  const ROW_GAP = "var(--a8c-charts-dimension-leaderboard-row-gap, 12px)";
12155
12139
  const COLUMN_GAP = "var(--a8c-charts-dimension-leaderboard-column-gap, 4px)";
12156
12140
  /** Indexed by `Math.sign( delta ) + 1`, so [negative, neutral, positive]. */
@@ -12210,27 +12194,43 @@ const BarLabel = ({ label }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react
12210
12194
  className: leaderboard_chart_module_default.label,
12211
12195
  children: label
12212
12196
  }) : label });
12213
- const BarWithLabel = ({ entry, withComparison, withOverlayLabel, primaryColor, secondaryColor, animation, isPrimaryVisible = true, isComparisonVisible = true }) => {
12197
+ const Bar = ({ share, color, animation, divergingScale }) => {
12198
+ const isNegative = share < 0;
12199
+ const sideMax = divergingScale?.[isNegative ? "negative" : "positive"];
12200
+ const width = sideMax ? Math.abs(share) / sideMax * 100 : Math.abs(share);
12201
+ const bar = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12202
+ className: (0, clsx.default)(leaderboard_chart_module_default.bar, {
12203
+ [leaderboard_chart_module_default["bar--animated"]]: animation,
12204
+ [leaderboard_chart_module_default["bar--negative"]]: divergingScale && isNegative
12205
+ }),
12206
+ style: {
12207
+ width: getBarWidth(width),
12208
+ backgroundColor: color
12209
+ }
12210
+ });
12211
+ if (!divergingScale) return bar;
12212
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12213
+ className: leaderboard_chart_module_default.barTrack,
12214
+ style: { gridTemplateColumns: `${divergingScale.negative}fr ${divergingScale.positive}fr` },
12215
+ children: bar
12216
+ });
12217
+ };
12218
+ const BarWithLabel = ({ entry, withComparison, withOverlayLabel, primaryColor, secondaryColor, animation, divergingScale, isPrimaryVisible = true, isComparisonVisible = true }) => {
12214
12219
  const showComparisonBar = withComparison && !withOverlayLabel && isComparisonVisible;
12220
+ const bars = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [isPrimaryVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
12221
+ share: entry.currentShare,
12222
+ color: primaryColor,
12223
+ animation,
12224
+ divergingScale
12225
+ }), showComparisonBar && hasPreviousValue(entry) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Bar, {
12226
+ share: entry.previousShare,
12227
+ color: secondaryColor,
12228
+ animation,
12229
+ divergingScale
12230
+ })] });
12215
12231
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12216
12232
  className: (0, clsx.default)(leaderboard_chart_module_default.barWithLabelContainer, { [leaderboard_chart_module_default["is-overlay"]]: withOverlayLabel }),
12217
- children: [
12218
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BarLabel, { label: entry.label }),
12219
- isPrimaryVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12220
- className: (0, clsx.default)(leaderboard_chart_module_default.bar, { [leaderboard_chart_module_default["bar--animated"]]: animation }),
12221
- style: {
12222
- width: getBarWidth(entry.currentShare),
12223
- backgroundColor: primaryColor
12224
- }
12225
- }),
12226
- showComparisonBar && hasPreviousValue(entry) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
12227
- className: (0, clsx.default)(leaderboard_chart_module_default.bar, { [leaderboard_chart_module_default["bar--animated"]]: animation }),
12228
- style: {
12229
- width: getBarWidth(entry.previousShare),
12230
- backgroundColor: secondaryColor
12231
- }
12232
- })
12233
- ]
12233
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(BarLabel, { label: entry.label }), bars]
12234
12234
  });
12235
12235
  };
12236
12236
  /**
@@ -12315,6 +12315,26 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
12315
12315
  withComparison,
12316
12316
  withOverlayLabel
12317
12317
  ]);
12318
+ const divergingScale = (0, react.useMemo)(() => {
12319
+ const withComparisonBars = withComparison && !withOverlayLabel;
12320
+ const scale = {
12321
+ negative: 0,
12322
+ positive: 0
12323
+ };
12324
+ for (const entry of data ?? []) {
12325
+ const shares = [entry.currentShare];
12326
+ if (withComparisonBars && hasPreviousValue(entry)) shares.push(entry.previousShare);
12327
+ for (const share of shares) {
12328
+ const side = share < 0 ? "negative" : "positive";
12329
+ scale[side] = Math.max(scale[side], Math.abs(share));
12330
+ }
12331
+ }
12332
+ return scale.negative > 0 ? scale : void 0;
12333
+ }, [
12334
+ data,
12335
+ withComparison,
12336
+ withOverlayLabel
12337
+ ]);
12318
12338
  const isDataValid = Boolean(data && data.length > 0);
12319
12339
  const chartMetadata = (0, react.useMemo)(() => ({
12320
12340
  withComparison,
@@ -12330,6 +12350,8 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
12330
12350
  const prefersReducedMotion = usePrefersReducedMotion();
12331
12351
  const { contentRef, fittedCount, isMeasurable } = useFittedRowCount(fitRows && !allSeriesHidden, data?.length ?? 0, data);
12332
12352
  const shouldFitRows = fitRows && isMeasurable;
12353
+ const showComparisonColumn = withComparison && isComparisonVisible;
12354
+ const templateColumns = showComparisonColumn && isPrimaryVisible ? "minmax(0, 1fr) auto auto" : "minmax(0, 1fr) auto";
12333
12355
  if (!data || data.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartInstanceContext.Provider, {
12334
12356
  value: { chartId },
12335
12357
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartLayout, {
@@ -12394,13 +12416,12 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
12394
12416
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default, {
12395
12417
  role: "list",
12396
12418
  "aria-label": ariaLabel ?? (0, _wordpress_i18n.__)("Leaderboard chart", "jetpack-charts"),
12397
- templateColumns: "minmax(0, 1fr) auto",
12419
+ templateColumns,
12398
12420
  rowGap: ROW_GAP,
12399
12421
  columnGap: COLUMN_GAP,
12400
12422
  "data-leaderboard-grid": true,
12401
12423
  children: data.map((entry, rowIndex) => {
12402
12424
  const rowStyle = shouldFitRows && rowIndex >= fittedCount ? { visibility: "hidden" } : void 0;
12403
- const showComparisonColumn = withComparison && isComparisonVisible;
12404
12425
  const hasPreviousPeriodValue = hasPreviousValue(entry);
12405
12426
  const hasDelta = hasDeltaValue(entry);
12406
12427
  const showComparisonValue = showComparisonColumn && hasDelta;
@@ -12415,13 +12436,12 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
12415
12436
  withOverlayLabel,
12416
12437
  primaryColor: resolvedPrimaryColor,
12417
12438
  secondaryColor: resolvedSecondaryColor,
12439
+ divergingScale,
12418
12440
  isPrimaryVisible,
12419
12441
  isComparisonVisible,
12420
12442
  animation: animation && !loading && !prefersReducedMotion
12421
12443
  })
12422
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
12423
- direction: "row",
12424
- gap: "xs",
12444
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
12425
12445
  className: (0, clsx.default)(leaderboard_chart_module_default.valueContainer, { [leaderboard_chart_module_default.overlayLabel]: withOverlayLabel }),
12426
12446
  children: [
12427
12447
  isPrimaryVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Text, { children: valueFormatter(entry.currentValue) }),
@@ -12502,8 +12522,7 @@ const LeaderboardChartWithProvider = (props) => {
12502
12522
  LeaderboardChartWithProvider.displayName = "LeaderboardChart";
12503
12523
  const LeaderboardChart = attachSubComponents(LeaderboardChartWithProvider, { Legend });
12504
12524
  const LeaderboardChartResponsive = attachSubComponents(withResponsive(LeaderboardChartWithProvider), { Legend });
12505
- //#endregion
12506
- //#region src/charts/private/pie-keyboard-navigation/order-arcs-for-navigation.ts
12525
+ // src/charts/private/pie-keyboard-navigation/order-arcs-for-navigation.ts
12507
12526
  /**
12508
12527
  * Orders arcs the way they appear: clockwise from 12 o'clock, which for a semi-circle is left to right.
12509
12528
  *
@@ -12511,15 +12530,13 @@ const LeaderboardChartResponsive = attachSubComponents(withResponsive(Leaderboar
12511
12530
  * @return A copy of `arcs` sorted by angular midpoint.
12512
12531
  */
12513
12532
  const orderArcsForNavigation = (arcs) => [...arcs].sort((a, b) => a.startAngle + a.endAngle - (b.startAngle + b.endAngle));
12514
- //#endregion
12515
- //#region src/charts/private/pie-keyboard-navigation/pie-selection-announcement.tsx
12533
+ // src/charts/private/pie-keyboard-navigation/pie-selection-announcement.tsx
12516
12534
  const PieSelectionAnnouncement = ({ data }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.VisuallyHidden, {
12517
12535
  role: "status",
12518
12536
  "aria-atomic": "true",
12519
12537
  children: data && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LabelValueContent, { data })
12520
12538
  });
12521
- //#endregion
12522
- //#region src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx
12539
+ // src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx
12523
12540
  const TOOLTIP_BOX_STYLE = { zIndex: 3 };
12524
12541
  const PieTooltip = ({ top, left, selectedIndex, tooltipRef, children }) => {
12525
12542
  const standaloneScopeClass = useStandaloneScopeClass();
@@ -12541,8 +12558,7 @@ const PieTooltip = ({ top, left, selectedIndex, tooltipRef, children }) => {
12541
12558
  }, `chart-tooltip-${selectedIndex}`)
12542
12559
  });
12543
12560
  };
12544
- //#endregion
12545
- //#region src/charts/private/pie-keyboard-navigation/pie-selection-output.tsx
12561
+ // src/charts/private/pie-keyboard-navigation/pie-selection-output.tsx
12546
12562
  /**
12547
12563
  * Reports the selected segment: a focused tooltip for a keyboard selection, a pointer tooltip on hover, or a screen reader announcement without tooltips.
12548
12564
  *
@@ -12582,8 +12598,7 @@ const PieSelectionOutput = ({ withTooltips, selectedIndex, selectedData, keyboar
12582
12598
  })
12583
12599
  ] });
12584
12600
  };
12585
- //#endregion
12586
- //#region src/charts/private/pie-keyboard-navigation/use-pie-keyboard-navigation.ts
12601
+ // src/charts/private/pie-keyboard-navigation/use-pie-keyboard-navigation.ts
12587
12602
  const usePieKeyboardNavigation = ({ navigationArcs, withTooltips, tooltipOffsetX, tooltipOffsetY }) => {
12588
12603
  const chartRef = (0, react.useRef)(null);
12589
12604
  const svgRef = (0, react.useRef)(null);
@@ -12663,8 +12678,7 @@ const usePieKeyboardNavigation = ({ navigationArcs, withTooltips, tooltipOffsetX
12663
12678
  }
12664
12679
  };
12665
12680
  };
12666
- //#endregion
12667
- //#region src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx
12681
+ // src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx
12668
12682
  /**
12669
12683
  * Renders a SVG mask that creates a radial wipe animation effect.
12670
12684
  *
@@ -12701,8 +12715,7 @@ function RadialWipeAnimation({ id, radius, innerRadius = 0, durationMs = 1e3, wi
12701
12715
  })
12702
12716
  });
12703
12717
  }
12704
- //#endregion
12705
- //#region src/charts/pie-chart/pie-chart.module.scss
12718
+ // src/charts/pie-chart/pie-chart.module.scss
12706
12719
  var pie_chart_module_default = {
12707
12720
  "pie-chart": "a8ccharts-gnszbG-pie-chart",
12708
12721
  "pie-chart__label-plate": "a8ccharts-gnszbG-pie-chart__label-plate",
@@ -12713,8 +12726,7 @@ var pie_chart_module_default = {
12713
12726
  "pie-chart__plot": "a8ccharts-gnszbG-pie-chart__plot",
12714
12727
  "pie-chart--responsive": "a8ccharts-gnszbG-pie-chart--responsive"
12715
12728
  };
12716
- //#endregion
12717
- //#region src/charts/pie-chart/pie-chart.tsx
12729
+ // src/charts/pie-chart/pie-chart.tsx
12718
12730
  /**
12719
12731
  * Default tooltip renderer for pie charts.
12720
12732
  * Renders the default `label: value` tooltip content for the hovered segment.
@@ -12997,8 +13009,7 @@ const PieChartResponsive = attachSubComponents(withResponsive(PieChartWithProvid
12997
13009
  SVG: ChartSVG,
12998
13010
  HTML: ChartHTML
12999
13011
  });
13000
- //#endregion
13001
- //#region src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss
13012
+ // src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss
13002
13013
  var pie_semi_circle_chart_module_default = {
13003
13014
  "label": "a8ccharts-YtTOxW-label",
13004
13015
  "note": "a8ccharts-YtTOxW-note",
@@ -13006,8 +13017,7 @@ var pie_semi_circle_chart_module_default = {
13006
13017
  "pie-semi-circle-chart__plot": "a8ccharts-YtTOxW-pie-semi-circle-chart__plot",
13007
13018
  "pie-semi-circle-chart--responsive": "a8ccharts-YtTOxW-pie-semi-circle-chart--responsive"
13008
13019
  };
13009
- //#endregion
13010
- //#region src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx
13020
+ // src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx
13011
13021
  /**
13012
13022
  * Default tooltip renderer for semi-circle pie charts.
13013
13023
  * Renders the default `label: value` tooltip content for the hovered segment.
@@ -13250,14 +13260,12 @@ const PieSemiCircleChartResponsive = attachSubComponents(withResponsive(PieSemiC
13250
13260
  SVG: ChartSVG,
13251
13261
  HTML: ChartHTML
13252
13262
  });
13253
- //#endregion
13254
- //#region src/charts/sparkline/sparkline.module.scss
13263
+ // src/charts/sparkline/sparkline.module.scss
13255
13264
  var sparkline_module_default = {
13256
13265
  "sparkline": "a8ccharts-GtgAVa-sparkline",
13257
13266
  "sparkline--empty": "a8ccharts-GtgAVa-sparkline--empty"
13258
13267
  };
13259
- //#endregion
13260
- //#region src/charts/sparkline/sparkline.tsx
13268
+ // src/charts/sparkline/sparkline.tsx
13261
13269
  const DEFAULT_WIDTH = 100;
13262
13270
  const DEFAULT_HEIGHT = 40;
13263
13271
  /**
@@ -13399,8 +13407,7 @@ SparklineUnresponsive.displayName = "SparklineUnresponsive";
13399
13407
  * Responsive Sparkline chart component
13400
13408
  */
13401
13409
  const Sparkline = withResponsive(SparklineUnresponsive);
13402
- //#endregion
13403
- //#region src/components/trend-indicator/trend-indicator.module.scss
13410
+ // src/components/trend-indicator/trend-indicator.module.scss
13404
13411
  var trend_indicator_module_default = {
13405
13412
  "trend-indicator": "a8ccharts-zR7F7G-trend-indicator",
13406
13413
  "trend-indicator__icon": "a8ccharts-zR7F7G-trend-indicator__icon",
@@ -13409,8 +13416,7 @@ var trend_indicator_module_default = {
13409
13416
  "trend-indicator--neutral": "a8ccharts-zR7F7G-trend-indicator--neutral",
13410
13417
  "trend-indicator--up": "a8ccharts-zR7F7G-trend-indicator--up"
13411
13418
  };
13412
- //#endregion
13413
- //#region src/components/trend-indicator/trend-indicator.tsx
13419
+ // src/components/trend-indicator/trend-indicator.tsx
13414
13420
  const DIRECTION_LABELS = {
13415
13421
  up: "Increase",
13416
13422
  down: "Decrease",
@@ -13453,7 +13459,6 @@ function TrendIndicator({ direction, value, className, style, showIcon = true })
13453
13459
  })]
13454
13460
  });
13455
13461
  }
13456
- //#endregion
13457
13462
  exports.AccessibleTooltip = AccessibleTooltip;
13458
13463
  exports.AreaChart = AreaChartResponsive;
13459
13464
  exports.AreaChartUnresponsive = AreaChart;