@automattic/charts 3.1.0 → 3.2.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 (41) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/TOKENS.md +51 -12
  3. package/dist/index.cjs +307 -213
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +7 -1
  6. package/dist/index.d.cts +223 -127
  7. package/dist/index.d.ts +223 -127
  8. package/dist/index.js +306 -212
  9. package/dist/index.js.map +1 -1
  10. package/package.json +8 -8
  11. package/src/charts/area-chart/area-chart.tsx +2 -2
  12. package/src/charts/area-chart/test/area-chart.test.tsx +45 -0
  13. package/src/charts/bar-chart/bar-chart.tsx +36 -10
  14. package/src/charts/bar-chart/private/use-bar-chart-options.ts +19 -12
  15. package/src/charts/bar-chart/test/bar-chart-pointer-events.test.tsx +67 -0
  16. package/src/charts/bar-chart/test/bar-chart.test.tsx +101 -0
  17. package/src/charts/bar-list-chart/bar-list-chart.tsx +40 -2
  18. package/src/charts/bar-list-chart/test/bar-list-chart.test.tsx +38 -0
  19. package/src/charts/line-chart/line-chart.tsx +18 -3
  20. package/src/charts/line-chart/test/line-chart.test.tsx +98 -0
  21. package/src/charts/sparkline/sparkline.tsx +9 -3
  22. package/src/charts/sparkline/types.ts +1 -1
  23. package/src/components/tooltip/accessible-tooltip.tsx +32 -2
  24. package/src/components/tooltip/test/accessible-tooltip.test.tsx +68 -0
  25. package/src/hooks/test/use-xychart-theme-provider-override.test.tsx +4 -4
  26. package/src/hooks/test/use-xychart-theme-style-reads.test.tsx +17 -10
  27. package/src/hooks/test/use-xychart-theme.test.tsx +50 -5
  28. package/src/hooks/use-xychart-theme.ts +14 -20
  29. package/src/providers/chart-context/global-charts-provider.tsx +44 -33
  30. package/src/providers/chart-context/private/series-palette.ts +45 -0
  31. package/src/providers/chart-context/private/theme-override-vars.ts +46 -2
  32. package/src/providers/chart-context/private/with-catalog-pointers.ts +45 -2
  33. package/src/providers/chart-context/test/sparse-theme.test.ts +16 -2
  34. package/src/providers/chart-context/test/theme-override-vars.test.ts +65 -0
  35. package/src/providers/chart-context/test/use-global-charts-theme.test.tsx +8 -1
  36. package/src/providers/chart-context/test/with-catalog-pointers.test.ts +57 -0
  37. package/src/providers/chart-context/themes.ts +8 -3
  38. package/src/styles/chart-scope.scss +52 -24
  39. package/src/styles/test/chart-scope.test.ts +22 -9
  40. package/src/types.ts +148 -31
  41. package/src/utils/get-styles.ts +7 -1
package/dist/index.cjs CHANGED
@@ -17,7 +17,7 @@ var __copyProps = (to, from, except, desc) => {
17
17
  }
18
18
  return to;
19
19
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
21
21
  value: mod,
22
22
  enumerable: true
23
23
  }) : target, mod));
@@ -28,7 +28,7 @@ let _wordpress_i18n = require("@wordpress/i18n");
28
28
  let clsx = require("clsx");
29
29
  clsx = __toESM(clsx, 1);
30
30
  let react = require("react");
31
- react = __toESM(react, 1);
31
+ react = __toESM(react);
32
32
  let _visx_vendor_d3_color = require("@visx/vendor/d3-color");
33
33
  let date_fns = require("date-fns");
34
34
  let _visx_text = require("@visx/text");
@@ -252,7 +252,8 @@ const formatPercentage = (value) => {
252
252
  */
253
253
  const getLongestTickWidth = (ticks, formatTick, labelStyle) => {
254
254
  const formattedTicks = ticks.map((tick) => formatTick(tick, 0, []));
255
- return (0, _visx_text.getStringWidth)(formattedTicks.reduce((longest, current) => longest.length >= current.length ? longest : current, formattedTicks[0]), labelStyle);
255
+ const longestTick = formattedTicks.reduce((longest, current) => longest.length >= current.length ? longest : current, formattedTicks[0]);
256
+ return (0, _visx_text.getStringWidth)(longestTick, labelStyle);
256
257
  };
257
258
  //#endregion
258
259
  //#region src/utils/get-styles.ts
@@ -762,6 +763,16 @@ const getChartColor = (index, colorCache) => {
762
763
  const fallbackLightness = BASE_LIGHTNESS + index % LIGHTNESS_VARIATION_STEPS * LIGHTNESS_INCREMENT;
763
764
  return (0, _visx_vendor_d3_color.hsl)(Math.round(fallbackHue), fallbackSaturation / 100, fallbackLightness / 100).formatHex();
764
765
  };
766
+ /**
767
+ * The catalog role holding one series-palette slot.
768
+ *
769
+ * @param slot - The one-based slot number.
770
+ * @return The role name.
771
+ */
772
+ const seriesRole = (slot) => `--a8c-charts-color-series-${slot}`;
773
+ const SERIES_SLOT_1_FALLBACK = "#3858e9";
774
+ /** The catalog pointer for every slot, in slot order. */
775
+ const SERIES_PALETTE_POINTERS = Array.from({ length: 5 }, (_, index) => index === 0 ? `var(${seriesRole(1)}, ${SERIES_SLOT_1_FALLBACK})` : `var(${seriesRole(index + 1)})`);
765
776
  //#endregion
766
777
  //#region src/providers/chart-context/private/theme-override-vars.ts
767
778
  const ROLE_FOR_FIELD = [
@@ -769,8 +780,22 @@ const ROLE_FOR_FIELD = [
769
780
  ["--a8c-charts-color-grid", (theme) => theme.gridStyles?.stroke],
770
781
  ["--a8c-charts-color-axis", (theme) => theme.xAxisLineStyles?.stroke],
771
782
  ["--a8c-charts-color-tick", (theme) => theme.xTickLineStyles?.stroke],
772
- ["--a8c-charts-color-label-axis", (theme) => theme.svgLabelSmall?.fill]
783
+ ["--a8c-charts-color-label-axis", (theme) => theme.svgLabelSmall?.fill],
784
+ ["--a8c-charts-color-label-background", (theme) => theme.labelBackgroundColor],
785
+ ["--a8c-charts-color-label-on-fill", (theme) => theme.labelTextColor],
786
+ ...Array.from({ length: 5 }, (_, index) => [seriesRole(index + 1), (theme) => theme.colors?.[index]])
773
787
  ];
788
+ let warnedAboutExtraColors = false;
789
+ /**
790
+ * Warns once when a consumer passes more colors than there are slots to publish them into.
791
+ *
792
+ * @param count - How many entries `theme.colors` holds.
793
+ */
794
+ function warnOnceAboutExtraColors(count) {
795
+ if (warnedAboutExtraColors || process.env.NODE_ENV === "production") return;
796
+ warnedAboutExtraColors = true;
797
+ console.warn(`[Charts] theme.colors holds ${count} colors and the palette has 5 slots, so entries past the 5th are ignored. Set a per-series color with \`options.stroke\` instead.`);
798
+ }
774
799
  /**
775
800
  * The variable a `theme` prop override is published as, one layer outside the role itself.
776
801
  *
@@ -784,7 +809,7 @@ ROLE_FOR_FIELD.map(([role]) => role);
784
809
  /**
785
810
  * Whether a value reads the role it is being published for, which would make the catalog entry depend on itself.
786
811
  *
787
- * The dependency runs `<role>: var(<role>-theme, …)`, so a value naming `<role>` closes a cycle through the catalog entry. CSS marks every custom property in a cycle invalid at computed-value time — the role's own fallback is *not* used, so the token resolves to nothing and every chart loses that colour. Verified in Chrome: `--role-theme: var(--role, blue); --role: var(--role-theme, green)` leaves `--role` empty, not `green`.
812
+ * The dependency runs `<role>: var(<role>-theme, …)`, so a value naming `<role>` closes a cycle through the catalog entry. CSS marks every custom property in a cycle invalid at computed-value time — the role's own fallback is *not* used, so the token resolves to nothing and every chart loses that color. Verified in Chrome: `--role-theme: var(--role, blue); --role: var(--role-theme, green)` leaves `--role` empty, not `green`.
788
813
  *
789
814
  * Three things this has to get right, none of which a plain substring test gets:
790
815
  *
@@ -800,10 +825,12 @@ ROLE_FOR_FIELD.map(([role]) => role);
800
825
  */
801
826
  const readsOwnRole = (value, role) => value.trim() === role || new RegExp(`var\\(\\s*${role.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w-])`).test(value);
802
827
  /**
803
- * Maps a sparse consumer theme onto the theme-layer variables its overridden catalog roles read, so CSS-painted and JS-resolved colours read one source.
828
+ * Maps a sparse consumer theme onto the theme-layer variables its overridden catalog roles read, so CSS-painted and JS-resolved colors read one source.
804
829
  *
805
830
  * A value that reads the role it would override is left unpublished — that is the default theme's own pointer surviving `mergeThemes`, and publishing it would invalidate the role. The role is still reported in `roles`: `withCatalogPointers` restores its theme field to the catalog pointer either way, so CSS and visx agree on the catalog default rather than visx painting a literal CSS never sees.
806
831
  *
832
+ * `theme.colors` publishes through the same mechanism, one slot per entry, so a CSS declaration of `--a8c-charts-color-series-N` still beats it and a short array leaves the later slots unset rather than blank.
833
+ *
807
834
  * @param theme - The consumer's `theme` prop, before merging with the default theme.
808
835
  * @return The wrapper's custom properties, and the roles the consumer overrode.
809
836
  */
@@ -812,6 +839,7 @@ const themeOverrideVars = (theme) => {
812
839
  vars: {},
813
840
  roles: []
814
841
  };
842
+ if (Array.isArray(theme.colors) && theme.colors.length > 5) warnOnceAboutExtraColors(theme.colors.length);
815
843
  const vars = {};
816
844
  const roles = [];
817
845
  for (const [role, read] of ROLE_FOR_FIELD) {
@@ -832,15 +860,9 @@ const themeOverrideVars = (theme) => {
832
860
  */
833
861
  const defaultTheme = {
834
862
  backgroundColor: "var(--a8c-charts-color-background, #fff)",
835
- labelBackgroundColor: "transparent",
863
+ labelBackgroundColor: "var(--a8c-charts-color-label-background, transparent)",
836
864
  labelTextColor: "var(--a8c-charts-color-label-on-fill, #FFFFFF)",
837
- colors: [
838
- "#98C8DF",
839
- "#006DAB",
840
- "#A6DC80",
841
- "#1F9828",
842
- "#FF8C8F"
843
- ],
865
+ colors: [...SERIES_PALETTE_POINTERS],
844
866
  gridStyles: {
845
867
  stroke: "var(--a8c-charts-color-grid, #dbdbdb)",
846
868
  strokeWidth: 1
@@ -920,7 +942,23 @@ const defaultTheme = {
920
942
  };
921
943
  //#endregion
922
944
  //#region src/providers/chart-context/private/with-catalog-pointers.ts
945
+ /**
946
+ * The pointer one palette slot is restored to.
947
+ *
948
+ * Unlike the other roles, this keeps the consumer's own color as the pointer's terminal literal instead of the catalog's. The literal is only ever reached where `getComputedStyle` resolves nothing — SSR and jsdom — and there the palette is the one field where falling back to the catalog default would be visible: every series would paint the same seeded blue. In a browser the slot resolves first, so a CSS declaration of it still outranks the consumer's `theme.colors`.
949
+ *
950
+ * @param index - The slot's zero-based index in `colors`.
951
+ * @param value - The merged theme's entry for it.
952
+ * @return The catalog pointer for that slot.
953
+ */
954
+ const seriesPointer = (index, value) => {
955
+ const role = seriesRole(index + 1);
956
+ if (typeof value === "string" && value.startsWith(`var(${role}`)) return value;
957
+ if (typeof value !== "string" || value === "") return SERIES_PALETTE_POINTERS[index];
958
+ return `var(${role}, ${value})`;
959
+ };
923
960
  const CATALOG_RESTORE_FOR_ROLE = {
961
+ ...Object.fromEntries(Array.from({ length: 5 }, (_, index) => [seriesRole(index + 1), (theme) => ({ colors: SERIES_PALETTE_POINTERS.map((_pointer, slot) => seriesPointer(slot, theme.colors?.[slot])) })])),
924
962
  "--a8c-charts-color-background": () => ({ backgroundColor: defaultTheme.backgroundColor }),
925
963
  "--a8c-charts-color-grid": (theme) => ({ gridStyles: {
926
964
  ...theme.gridStyles,
@@ -937,14 +975,16 @@ const CATALOG_RESTORE_FOR_ROLE = {
937
975
  "--a8c-charts-color-label-axis": (theme) => ({ svgLabelSmall: {
938
976
  ...theme.svgLabelSmall,
939
977
  fill: defaultTheme.svgLabelSmall.fill
940
- } })
978
+ } }),
979
+ "--a8c-charts-color-label-background": () => ({ labelBackgroundColor: defaultTheme.labelBackgroundColor }),
980
+ "--a8c-charts-color-label-on-fill": () => ({ labelTextColor: defaultTheme.labelTextColor })
941
981
  };
942
982
  /**
943
983
  * Restores the mapped theme fields of `overriddenRoles` to their catalog pointer, so the theme-layer variable `themeOverrideVars` writes on the provider wrapper is the only carrier for an overridden role — CSS and the JS bridge (`useXYChartTheme`) then resolve it through the same cascade instead of visx reading a baked literal that can disagree with a closer CSS override.
944
984
  *
945
985
  * This covers roles `themeOverrideVars` deliberately left unpublished as well as the ones it published. A value that reads its own role is not publishable, but leaving visx the consumer's literal is what the whole mechanism exists to prevent: `theme={ { gridStyles: { stroke: 'var(--brand, var(--a8c-charts-color-grid, red))' } } }` would have CSS paint the catalog default while visx painted `--brand`.
946
986
  *
947
- * Every field outside the five mapped roles is left exactly as `merged` provided it: those aren't published as theme-layer vars, so rewriting them would erase a consumer's override with no replacement carrier.
987
+ * Every field outside the mapped roles is left exactly as `merged` provided it: those aren't published as theme-layer vars, so rewriting them would erase a consumer's override with no replacement carrier.
948
988
  *
949
989
  * @param merged - The consumer theme merged onto `defaultTheme` (`mergeThemes` output).
950
990
  * @param overriddenRoles - The catalog roles the consumer overrode, from `themeOverrideVars`.
@@ -989,29 +1029,26 @@ const GlobalChartsProvider = ({ children, theme }) => {
989
1029
  const [isColorPaletteResolved, setIsColorPaletteResolved] = (0, react.useState)(false);
990
1030
  (0, react.useLayoutEffect)(() => {
991
1031
  setIsColorPaletteResolved(false);
992
- const { colors } = providerTheme;
993
1032
  const resolvedColors = [];
994
1033
  const hues = [];
995
1034
  const existingHslColors = [];
996
1035
  let minHue = 360;
997
1036
  let maxHue = 0;
998
- if (Array.isArray(colors)) {
999
- for (const color of colors) if (color && typeof color === "string") {
1000
- const normalizedColor = normalizeColorToHex(color, wrapperRef.current, resolveCssVariable);
1001
- if (normalizedColor.startsWith("#")) {
1002
- resolvedColors.push(normalizedColor);
1003
- const hslColor = (0, _visx_vendor_d3_color.hsl)(normalizedColor);
1004
- if (!isNaN(hslColor.h)) {
1005
- const hslTuple = [
1006
- hslColor.h,
1007
- hslColor.s * 100,
1008
- hslColor.l * 100
1009
- ];
1010
- hues.push(hslTuple[0]);
1011
- existingHslColors.push(hslTuple);
1012
- minHue = Math.min(minHue, hslTuple[0]);
1013
- maxHue = Math.max(maxHue, hslTuple[0]);
1014
- }
1037
+ for (const color of providerTheme.colors ?? SERIES_PALETTE_POINTERS) {
1038
+ const normalizedColor = normalizeColorToHex(color, wrapperRef.current, resolveCssVariable);
1039
+ if (normalizedColor.startsWith("#")) {
1040
+ resolvedColors.push(normalizedColor);
1041
+ const hslColor = (0, _visx_vendor_d3_color.hsl)(normalizedColor);
1042
+ if (!isNaN(hslColor.h)) {
1043
+ const hslTuple = [
1044
+ hslColor.h,
1045
+ hslColor.s * 100,
1046
+ hslColor.l * 100
1047
+ ];
1048
+ hues.push(hslTuple[0]);
1049
+ existingHslColors.push(hslTuple);
1050
+ minHue = Math.min(minHue, hslTuple[0]);
1051
+ maxHue = Math.max(maxHue, hslTuple[0]);
1015
1052
  }
1016
1053
  }
1017
1054
  }
@@ -1027,9 +1064,10 @@ const GlobalChartsProvider = ({ children, theme }) => {
1027
1064
  if (colorCache.colors.length > 0) setIsColorPaletteResolved(true);
1028
1065
  }, [colorCache]);
1029
1066
  const [groupToColorMap, setGroupToColorMap] = (0, react.useState)(() => /* @__PURE__ */ new Map());
1067
+ const paletteKey = colorCache.colors.join(",");
1030
1068
  (0, react.useEffect)(() => {
1031
1069
  setGroupToColorMap(/* @__PURE__ */ new Map());
1032
- }, [providerTheme.colors]);
1070
+ }, [paletteKey]);
1033
1071
  const registerChart = (0, react.useCallback)((id, data) => {
1034
1072
  setCharts((prev) => new Map(prev).set(id, data));
1035
1073
  }, []);
@@ -1242,27 +1280,13 @@ const useXYChartTheme = (data) => {
1242
1280
  return (0, react.useMemo)(() => {
1243
1281
  const resolve = createCssVariableResolver(scopeElement);
1244
1282
  const resolveColor = (value) => value ? resolve(value) ?? value : value;
1245
- const seriesColors = JSON.parse(seriesColorKey);
1283
+ const paletteColors = [...JSON.parse(seriesColorKey), ...theme.colors ?? []].map((color) => resolveColor(color)).filter((color) => Boolean(color) && !color.includes("var("));
1284
+ const htmlLabelColor = resolveColor(theme.svgLabelSmall?.fill);
1246
1285
  return (0, _visx_xychart.buildChartTheme)({
1247
1286
  ...theme,
1248
- colors: [...seriesColors, ...theme.colors ?? []],
1287
+ colors: paletteColors,
1249
1288
  backgroundColor: resolveColor(theme.backgroundColor),
1250
- gridStyles: theme.gridStyles && {
1251
- ...theme.gridStyles,
1252
- stroke: resolveColor(theme.gridStyles.stroke)
1253
- },
1254
- xAxisLineStyles: theme.xAxisLineStyles && {
1255
- ...theme.xAxisLineStyles,
1256
- stroke: resolveColor(theme.xAxisLineStyles.stroke)
1257
- },
1258
- xTickLineStyles: theme.xTickLineStyles && {
1259
- ...theme.xTickLineStyles,
1260
- stroke: resolveColor(theme.xTickLineStyles.stroke)
1261
- },
1262
- svgLabelSmall: theme.svgLabelSmall && {
1263
- ...theme.svgLabelSmall,
1264
- fill: resolveColor(theme.svgLabelSmall.fill)
1265
- }
1289
+ htmlLabel: htmlLabelColor ? { color: htmlLabelColor } : void 0
1266
1290
  });
1267
1291
  }, [
1268
1292
  theme,
@@ -1359,11 +1383,12 @@ const useChartMargin = (height, options, data, theme, horizontal = false) => {
1359
1383
  if (options.axis?.y?.tickValues?.length) return options.axis.y.tickValues;
1360
1384
  const minY = Math.min(...allDataPoints.map((d) => d.value));
1361
1385
  const maxY = Math.max(...allDataPoints.map((d) => d.value));
1362
- return (0, _visx_scale.getTicks)((0, _visx_scale.createScale)({
1386
+ const yScale = (0, _visx_scale.createScale)({
1363
1387
  ...options.yScale,
1364
1388
  domain: [minY, maxY],
1365
1389
  range: [height, 0]
1366
- }), options.axis?.y?.numTicks);
1390
+ });
1391
+ return (0, _visx_scale.getTicks)(yScale, options.axis?.y?.numTicks);
1367
1392
  }, [
1368
1393
  options,
1369
1394
  data,
@@ -1488,7 +1513,7 @@ const MIN_PIXEL_SIZE = 3;
1488
1513
  /**
1489
1514
  * Pixel size for zero-value bars (1px less than near-zero to be visually distinguishable).
1490
1515
  */
1491
- const ZERO_PIXEL_SIZE = MIN_PIXEL_SIZE - 1;
1516
+ const ZERO_PIXEL_SIZE = 2;
1492
1517
  const useZeroValueDisplay = (data, options = { enabled: false }) => {
1493
1518
  const { enabled, valueAxisLength } = options;
1494
1519
  return (0, react.useMemo)(() => {
@@ -2104,8 +2129,14 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
2104
2129
  };
2105
2130
  //#endregion
2106
2131
  //#region src/components/tooltip/accessible-tooltip.tsx
2107
- const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", ...props }) => {
2132
+ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", verticalCrosshairStyle, horizontalCrosshairStyle, ...props }) => {
2108
2133
  const tooltipContext = (0, react.useContext)(_visx_xychart.TooltipContext);
2134
+ const scopeElement = useChartScopeElement();
2135
+ const gridStroke = useGlobalChartsTheme().gridStyles?.stroke;
2136
+ const crosshairStroke = (0, react.useMemo)(() => {
2137
+ const stroke = gridStroke ? resolveCssVariable(gridStroke, scopeElement) : null;
2138
+ return stroke ? { stroke } : void 0;
2139
+ }, [gridStroke, scopeElement]);
2109
2140
  const tooltipData = (0, react.useMemo)(() => {
2110
2141
  if (mode !== "individual") return [];
2111
2142
  if (series.length === 0) return [];
@@ -2184,10 +2215,18 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
2184
2215
  ]);
2185
2216
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_xychart.Tooltip, {
2186
2217
  ...props,
2218
+ verticalCrosshairStyle: {
2219
+ ...crosshairStroke,
2220
+ ...verticalCrosshairStyle
2221
+ },
2222
+ horizontalCrosshairStyle: {
2223
+ ...crosshairStroke,
2224
+ ...horizontalCrosshairStyle
2225
+ },
2187
2226
  renderTooltip: focusableRenderTooltip
2188
2227
  });
2189
2228
  };
2190
- const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints }) => {
2229
+ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints, onActivate }) => {
2191
2230
  return {
2192
2231
  tooltipRef: (0, react.useCallback)((element) => {
2193
2232
  if (element && selectedIndex !== void 0) element.focus();
@@ -2228,13 +2267,14 @@ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating,
2228
2267
  setSelectedIndex(void 0);
2229
2268
  setIsNavigating(false);
2230
2269
  chartRef.current?.focus();
2231
- }
2270
+ } else if ((event.key === "Enter" || event.key === " ") && selectedIndex !== void 0) onActivate?.(selectedIndex);
2232
2271
  }, [
2233
2272
  totalPoints,
2234
2273
  selectedIndex,
2235
2274
  setSelectedIndex,
2236
2275
  setIsNavigating,
2237
- chartRef
2276
+ chartRef,
2277
+ onActivate
2238
2278
  ])
2239
2279
  };
2240
2280
  };
@@ -3001,7 +3041,7 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
3001
3041
  style: {
3002
3042
  width: `44px`,
3003
3043
  height: `44px`,
3004
- transform: `translate(${44 / 2}px, 0)`
3044
+ transform: `translate(22px, 0)`
3005
3045
  },
3006
3046
  "aria-label": title || (0, _wordpress_i18n.__)("View details", "jetpack-charts"),
3007
3047
  children: renderLabel({
@@ -3422,7 +3462,7 @@ const LineChartScalesRef = ({ chartRef, width, height, margin }) => {
3422
3462
  ]);
3423
3463
  return null;
3424
3464
  };
3425
- const LineChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, withStartGlyphs = false, withEndGlyphs = false, animation, options = {}, onPointerDown = void 0, onPointerUp = void 0, onPointerMove = void 0, onPointerOut = void 0, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
3465
+ const LineChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, withStartGlyphs = false, withEndGlyphs = false, animation, options = {}, onPointerDown = void 0, onPointerUp = void 0, onPointerMove = void 0, onPointerOut = void 0, onDatumActivate = void 0, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
3426
3466
  const legendInteractive = legend.interactive ?? false;
3427
3467
  const legendCollapseGroups = legend.collapseGroups ?? false;
3428
3468
  const legendShape = legend.shape ?? "line";
@@ -3484,17 +3524,27 @@ const LineChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartI
3484
3524
  }
3485
3525
  return min < max ? [min, max] : void 0;
3486
3526
  }, [rescaleYOnVisibilityChange, dataSorted]);
3527
+ const activateSelectedPoint = (0, react.useCallback)((index) => {
3528
+ const series = dataSorted[0];
3529
+ const datum = series?.data[index];
3530
+ if (series && datum) onDatumActivate?.({
3531
+ datum,
3532
+ index,
3533
+ key: series.label
3534
+ });
3535
+ }, [dataSorted, onDatumActivate]);
3487
3536
  const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
3488
3537
  selectedIndex,
3489
3538
  setSelectedIndex,
3490
3539
  isNavigating,
3491
3540
  setIsNavigating,
3492
3541
  chartRef,
3493
- totalPoints: dataSorted[0]?.data.length || 0
3542
+ totalPoints: dataSorted[0]?.data.length || 0,
3543
+ onActivate: activateSelectedPoint
3494
3544
  });
3495
3545
  const chartOptions = (0, react.useMemo)(() => {
3496
- const { tickResolution, ...xAxisOptions } = options?.axis?.x ?? {};
3497
- const formatter = xAxisOptions.tickFormat || getFormatter(dataSorted, tickResolution);
3546
+ const { tickResolution, tickFormat, ...xAxisOptions } = options?.axis?.x ?? {};
3547
+ const formatter = tickFormat || getFormatter(dataSorted, tickResolution);
3498
3548
  return {
3499
3549
  axis: {
3500
3550
  x: {
@@ -3554,36 +3604,38 @@ const LineChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartI
3554
3604
  const defaultMargin = useChartMargin(height, chartOptions, dataSorted, theme);
3555
3605
  const error = validateData$4(dataSorted);
3556
3606
  const isDataValid = !error;
3607
+ const legendItems = useChartLegendItems(dataSorted, (0, react.useMemo)(() => ({
3608
+ withGlyph: withLegendGlyph,
3609
+ glyphSize: Math.max(0, toNumber(glyphStyle?.radius) ?? 4),
3610
+ collapseGroups: legendCollapseGroups,
3611
+ renderGlyph
3612
+ }), [
3613
+ withLegendGlyph,
3614
+ glyphStyle?.radius,
3615
+ legendCollapseGroups,
3616
+ renderGlyph
3617
+ ]), legendShape);
3618
+ const chartMetadata = (0, react.useMemo)(() => ({
3619
+ withGradientFill,
3620
+ smoothing,
3621
+ curveType,
3622
+ withStartGlyphs,
3623
+ withEndGlyphs,
3624
+ withLegendGlyph
3625
+ }), [
3626
+ withGradientFill,
3627
+ smoothing,
3628
+ curveType,
3629
+ withStartGlyphs,
3630
+ withEndGlyphs,
3631
+ withLegendGlyph
3632
+ ]);
3557
3633
  useChartRegistration({
3558
3634
  chartId,
3559
- legendItems: useChartLegendItems(dataSorted, (0, react.useMemo)(() => ({
3560
- withGlyph: withLegendGlyph,
3561
- glyphSize: Math.max(0, toNumber(glyphStyle?.radius) ?? 4),
3562
- collapseGroups: legendCollapseGroups,
3563
- renderGlyph
3564
- }), [
3565
- withLegendGlyph,
3566
- glyphStyle?.radius,
3567
- legendCollapseGroups,
3568
- renderGlyph
3569
- ]), legendShape),
3635
+ legendItems,
3570
3636
  chartType: "line",
3571
3637
  isDataValid,
3572
- metadata: (0, react.useMemo)(() => ({
3573
- withGradientFill,
3574
- smoothing,
3575
- curveType,
3576
- withStartGlyphs,
3577
- withEndGlyphs,
3578
- withLegendGlyph
3579
- }), [
3580
- withGradientFill,
3581
- smoothing,
3582
- curveType,
3583
- withStartGlyphs,
3584
- withEndGlyphs,
3585
- withLegendGlyph
3586
- ])
3638
+ metadata: chartMetadata
3587
3639
  });
3588
3640
  const prefersReducedMotion = usePrefersReducedMotion();
3589
3641
  const accessors = {
@@ -3960,8 +4012,8 @@ const AreaChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartI
3960
4012
  rescaleYOnVisibility
3961
4013
  ]);
3962
4014
  const chartOptions = (0, react.useMemo)(() => {
3963
- const { tickResolution, ...xAxisOptions } = options?.axis?.x ?? {};
3964
- const formatter = xAxisOptions.tickFormat || getFormatter(dataSorted, tickResolution);
4015
+ const { tickResolution, tickFormat, ...xAxisOptions } = options?.axis?.x ?? {};
4016
+ const formatter = tickFormat || getFormatter(dataSorted, tickResolution);
3965
4017
  return {
3966
4018
  axis: {
3967
4019
  x: {
@@ -4003,26 +4055,28 @@ const AreaChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartI
4003
4055
  const defaultMargin = useChartMargin(height, chartOptions, dataSorted, theme);
4004
4056
  const error = validateData$3(dataSorted);
4005
4057
  const isDataValid = !error;
4058
+ const legendItems = useChartLegendItems(dataSorted, (0, react.useMemo)(() => ({
4059
+ withGlyph: false,
4060
+ glyphSize: 0,
4061
+ collapseGroups: legend.collapseGroups ?? false
4062
+ }), [legend.collapseGroups]), legendShape);
4063
+ const chartMetadata = (0, react.useMemo)(() => ({
4064
+ stacked,
4065
+ stackOffset,
4066
+ smoothing,
4067
+ curveType
4068
+ }), [
4069
+ stacked,
4070
+ stackOffset,
4071
+ smoothing,
4072
+ curveType
4073
+ ]);
4006
4074
  useChartRegistration({
4007
4075
  chartId,
4008
- legendItems: useChartLegendItems(dataSorted, (0, react.useMemo)(() => ({
4009
- withGlyph: false,
4010
- glyphSize: 0,
4011
- collapseGroups: legend.collapseGroups ?? false
4012
- }), [legend.collapseGroups]), legendShape),
4076
+ legendItems,
4013
4077
  chartType: "area",
4014
4078
  isDataValid,
4015
- metadata: (0, react.useMemo)(() => ({
4016
- stacked,
4017
- stackOffset,
4018
- smoothing,
4019
- curveType
4020
- }), [
4021
- stacked,
4022
- stackOffset,
4023
- smoothing,
4024
- curveType
4025
- ])
4079
+ metadata: chartMetadata
4026
4080
  });
4027
4081
  const prefersReducedMotion = usePrefersReducedMotion();
4028
4082
  const animationEnabled = !!animation && !prefersReducedMotion;
@@ -4430,11 +4484,13 @@ const getGroupPadding = (scale) => {
4430
4484
  function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = ALL_RENDERED) {
4431
4485
  const stableOptions = useDeepMemo(options);
4432
4486
  const axisConfig = (0, react.useMemo)(() => {
4433
- const { labelOverflow: xLabelOverflow, tickResolution: xTickResolution, ...xAxisOptions } = stableOptions.axis?.x || {};
4434
- const { labelOverflow: yLabelOverflow, tickResolution: yTickResolution, ...yAxisOptions } = stableOptions.axis?.y || {};
4487
+ const { labelOverflow: xLabelOverflow, tickResolution: xTickResolution, tickFormat: xTickFormat, ...xAxisOptions } = stableOptions.axis?.x || {};
4488
+ const { labelOverflow: yLabelOverflow, tickResolution: yTickResolution, tickFormat: yTickFormat, ...yAxisOptions } = stableOptions.axis?.y || {};
4435
4489
  return {
4436
4490
  xLabelOverflow,
4437
4491
  yLabelOverflow,
4492
+ xTickFormat,
4493
+ yTickFormat,
4438
4494
  xAxisOptions,
4439
4495
  yAxisOptions,
4440
4496
  tickResolution: horizontal ? yTickResolution : xTickResolution
@@ -4494,7 +4550,7 @@ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = A
4494
4550
  isSeriesRendered
4495
4551
  ]);
4496
4552
  return (0, react.useMemo)(() => {
4497
- const { xTickFormat, yTickFormat, tooltipLabelFormatter: defaultTooltipLabelFormatter, xAccessor, yAccessor, gridVisibility, xScale: baseXScale, yScale: baseYScale } = defaultOptions[horizontal ? "horizontal" : "vertical"];
4553
+ const { xTickFormat: defaultXTickFormat, yTickFormat: defaultYTickFormat, tooltipLabelFormatter: defaultTooltipLabelFormatter, xAccessor, yAccessor, gridVisibility, xScale: baseXScale, yScale: baseYScale } = defaultOptions[horizontal ? "horizontal" : "vertical"];
4498
4554
  let valueScaleDomainOverride = {};
4499
4555
  if (data.some((s) => s.options?.type === "comparison")) {
4500
4556
  if (!(!horizontal ? stableOptions.yScale?.domain : stableOptions.xScale?.domain)) {
@@ -4519,11 +4575,11 @@ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = A
4519
4575
  ...stableOptions.yScale || {},
4520
4576
  ...!horizontal ? valueScaleDomainOverride : {}
4521
4577
  };
4522
- const { xLabelOverflow, yLabelOverflow, xAxisOptions, yAxisOptions } = axisConfig;
4523
- const providedToolTipLabelFormatter = horizontal ? yAxisOptions.tickFormat : xAxisOptions.tickFormat;
4578
+ const { xLabelOverflow, yLabelOverflow, xTickFormat, yTickFormat, xAxisOptions, yAxisOptions } = axisConfig;
4579
+ const dateAxisTickFormat = horizontal ? yTickFormat : xTickFormat;
4524
4580
  const { timeAxis } = defaultOptions;
4525
4581
  const dateAxisOptions = horizontal ? yAxisOptions : xAxisOptions;
4526
- const bandTickValues = timeAxis && !dateAxisOptions.tickFormat ? getBandTickValues(timeAxis.domain, timeAxis.tickFormatter, dateAxisOptions.numTicks ?? DEFAULT_NUM_TICKS) : null;
4582
+ const bandTickValues = timeAxis && !dateAxisTickFormat ? getBandTickValues(timeAxis.domain, timeAxis.tickFormatter, dateAxisOptions.numTicks ?? DEFAULT_NUM_TICKS) : null;
4527
4583
  const dateAxisTickValues = bandTickValues ? { tickValues: bandTickValues } : {};
4528
4584
  return {
4529
4585
  gridVisibility,
@@ -4537,7 +4593,7 @@ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = A
4537
4593
  x: {
4538
4594
  orientation: "bottom",
4539
4595
  numTicks: DEFAULT_NUM_TICKS,
4540
- tickFormat: xTickFormat,
4596
+ tickFormat: xTickFormat || defaultXTickFormat,
4541
4597
  ...horizontal ? {} : dateAxisTickValues,
4542
4598
  ...xLabelOverflow === "ellipsis" ? { tickComponent: TruncatedXTickComponent } : {},
4543
4599
  ...xAxisOptions
@@ -4545,14 +4601,14 @@ function useBarChartOptions(data, horizontal, options = {}, isSeriesRendered = A
4545
4601
  y: {
4546
4602
  orientation: "left",
4547
4603
  numTicks: DEFAULT_NUM_TICKS,
4548
- tickFormat: yTickFormat,
4604
+ tickFormat: yTickFormat || defaultYTickFormat,
4549
4605
  ...horizontal ? dateAxisTickValues : {},
4550
4606
  ...yLabelOverflow === "ellipsis" ? { tickComponent: TruncatedYTickComponent } : {},
4551
4607
  ...yAxisOptions
4552
4608
  }
4553
4609
  },
4554
4610
  barGroup: { padding: getGroupPadding(horizontal ? yScale : xScale) },
4555
- tooltip: { labelFormatter: providedToolTipLabelFormatter || defaultTooltipLabelFormatter }
4611
+ tooltip: { labelFormatter: dateAxisTickFormat || defaultTooltipLabelFormatter }
4556
4612
  };
4557
4613
  }, [
4558
4614
  defaultOptions,
@@ -4615,11 +4671,6 @@ function computeComparisonRect(params) {
4615
4671
  };
4616
4672
  }
4617
4673
  /**
4618
- * Fraction of each per-series step left as a gap between bars within a single tick.
4619
- * Larger = more space between adjacent series; the shadow spans `1 - COMPARISON_INNER_GAP` of the step.
4620
- */
4621
- const COMPARISON_INNER_GAP = .1;
4622
- /**
4623
4674
  * Upper clamp on the computed group padding, so bars can never collapse to zero width
4624
4675
  * even at very large `widthFactor` values.
4625
4676
  */
@@ -4707,7 +4758,7 @@ const renderTooltipRow = (label, value) => /* @__PURE__ */ (0, react_jsx_runtime
4707
4758
  className: bar_chart_module_default["bar-chart__tooltip-row"],
4708
4759
  children: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("%1$s: %2$s", "jetpack-charts"), label, value)
4709
4760
  });
4710
- const BarChartInternal = ({ data, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, defaultHiddenSeries, animation, children, gap = "md" }) => {
4761
+ const BarChartInternal = ({ data, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
4711
4762
  const legendInteractive = legend.interactive ?? false;
4712
4763
  const legendCollapseGroups = legend.collapseGroups ?? false;
4713
4764
  const horizontal = orientation === "horizontal";
@@ -4734,14 +4785,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4734
4785
  const [selectedIndex, setSelectedIndex] = (0, react.useState)(void 0);
4735
4786
  const [isNavigating, setIsNavigating] = (0, react.useState)(false);
4736
4787
  const primarySeriesForNav = dataWithVisibleZeros.filter((s) => s.options?.type !== "comparison");
4737
- const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
4738
- selectedIndex,
4739
- setSelectedIndex,
4740
- isNavigating,
4741
- setIsNavigating,
4742
- chartRef,
4743
- totalPoints: Math.max(0, ...primarySeriesForNav.map((s) => s.data?.length || 0)) * primarySeriesForNav.length
4744
- });
4788
+ const totalPoints = Math.max(0, ...primarySeriesForNav.map((s) => s.data?.length || 0)) * primarySeriesForNav.length;
4745
4789
  const seriesWithVisibility = (0, react.useMemo)(() => dataWithVisibleZeros.map((series, index) => ({
4746
4790
  series,
4747
4791
  index,
@@ -4753,6 +4797,27 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4753
4797
  const primaryEntries = (0, react.useMemo)(() => seriesWithVisibility.filter(({ isVisible, series }) => isVisible && series.options?.type !== "comparison"), [seriesWithVisibility]);
4754
4798
  const primaryKeys = (0, react.useMemo)(() => primaryEntries.map(({ series }) => series.label), [primaryEntries]);
4755
4799
  const primarySeries = (0, react.useMemo)(() => primaryEntries.map(({ series }) => series), [primaryEntries]);
4800
+ const activateSelectedBar = (0, react.useCallback)((index) => {
4801
+ const primaryCount = primaryEntries.length;
4802
+ if (!primaryCount) return;
4803
+ const dataPointIndex = Math.floor(index / primaryCount);
4804
+ const series = primaryEntries[index % primaryCount]?.series;
4805
+ const datum = series?.data[dataPointIndex];
4806
+ if (series && datum) onDatumActivate?.({
4807
+ datum,
4808
+ index: dataPointIndex,
4809
+ key: series.label
4810
+ });
4811
+ }, [primaryEntries, onDatumActivate]);
4812
+ const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
4813
+ selectedIndex,
4814
+ setSelectedIndex,
4815
+ isNavigating,
4816
+ setIsNavigating,
4817
+ chartRef,
4818
+ totalPoints,
4819
+ onActivate: activateSelectedBar
4820
+ });
4756
4821
  const comparisonEntries = (0, react.useMemo)(() => {
4757
4822
  const primaryByGroup = new Map(primaryEntries.map(({ series, index }) => [series.group, {
4758
4823
  label: series.label,
@@ -4789,7 +4854,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4789
4854
  const groupPadding = (0, react.useMemo)(() => {
4790
4855
  const basePadding = chartOptions.barGroup.padding;
4791
4856
  if (!comparisonWidthFactor || comparisonWidthFactor <= 1) return basePadding;
4792
- const p = 1 - (1 - COMPARISON_INNER_GAP) / comparisonWidthFactor;
4857
+ const p = 1 - .9 / comparisonWidthFactor;
4793
4858
  return Math.min(Math.max(p, basePadding), MAX_GROUP_PADDING);
4794
4859
  }, [chartOptions.barGroup.padding, comparisonWidthFactor]);
4795
4860
  const { xScale, yScale } = (0, react.useMemo)(() => {
@@ -4927,15 +4992,17 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4927
4992
  chartId
4928
4993
  ]);
4929
4994
  const error = validateData$2(dataSorted);
4995
+ const isDataValid = !error;
4996
+ const chartMetadata = (0, react.useMemo)(() => ({
4997
+ orientation,
4998
+ withPatterns
4999
+ }), [orientation, withPatterns]);
4930
5000
  useChartRegistration({
4931
5001
  chartId,
4932
5002
  legendItems,
4933
5003
  chartType: "bar",
4934
- isDataValid: !error,
4935
- metadata: (0, react.useMemo)(() => ({
4936
- orientation,
4937
- withPatterns
4938
- }), [orientation, withPatterns])
5004
+ isDataValid,
5005
+ metadata: chartMetadata
4939
5006
  });
4940
5007
  const prefersReducedMotion = usePrefersReducedMotion();
4941
5008
  if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -5000,6 +5067,8 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
5000
5067
  xScale,
5001
5068
  yScale,
5002
5069
  horizontal,
5070
+ onPointerDown,
5071
+ onPointerUp,
5003
5072
  pointerEventsDataKey: "nearest",
5004
5073
  children: [
5005
5074
  !allSeriesHidden && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_xychart.Grid, {
@@ -5155,6 +5224,25 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
5155
5224
  bottom: 0,
5156
5225
  top: 0
5157
5226
  }, ...rest }) => {
5227
+ const { getElementStyles } = useGlobalChartsContext();
5228
+ const tintedData = (0, react.useMemo)(() => {
5229
+ if (data.length > 1) return data;
5230
+ return data.map((series, index) => {
5231
+ if (series.options?.stroke) return series;
5232
+ const { color } = getElementStyles({
5233
+ data: series,
5234
+ index
5235
+ });
5236
+ if (!isValidHexColor(color)) return series;
5237
+ return {
5238
+ ...series,
5239
+ options: {
5240
+ ...series.options,
5241
+ stroke: lightenHexColor(color, .6)
5242
+ }
5243
+ };
5244
+ });
5245
+ }, [data, getElementStyles]);
5158
5246
  const chartOptions = (0, react.useMemo)(() => {
5159
5247
  const isMultiSeries = data.length > 1;
5160
5248
  const defaultYScale = {
@@ -5187,7 +5275,7 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
5187
5275
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BarChart, {
5188
5276
  orientation: "horizontal",
5189
5277
  gridVisibility: "none",
5190
- data,
5278
+ data: tintedData,
5191
5279
  width,
5192
5280
  height,
5193
5281
  margin,
@@ -5448,20 +5536,21 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
5448
5536
  })]
5449
5537
  });
5450
5538
  const isDataValid = Boolean(steps && steps.length > 0);
5539
+ const chartMetadata = (0, react.useMemo)(() => ({
5540
+ mainRate,
5541
+ changeIndicator,
5542
+ stepsCount: steps?.length || 0
5543
+ }), [
5544
+ mainRate,
5545
+ changeIndicator,
5546
+ steps?.length
5547
+ ]);
5451
5548
  useChartRegistration({
5452
5549
  chartId,
5453
5550
  legendItems: [],
5454
5551
  chartType: "conversion-funnel",
5455
5552
  isDataValid,
5456
- metadata: (0, react.useMemo)(() => ({
5457
- mainRate,
5458
- changeIndicator,
5459
- stepsCount: steps?.length || 0
5460
- }), [
5461
- mainRate,
5462
- changeIndicator,
5463
- steps?.length
5464
- ])
5553
+ metadata: chartMetadata
5465
5554
  });
5466
5555
  const prefersReducedMotion = usePrefersReducedMotion();
5467
5556
  if (!isDataValid) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_ui.Stack, {
@@ -6065,7 +6154,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
6065
6154
  });
6066
6155
  const chartBackgroundHex = normalizeColorToHex(theme.backgroundColor, scopeElement, resolveCssVariable);
6067
6156
  const primaryHex = normalizeColorToHex(primaryColorHex);
6068
- const cellHasLightText = (intensity) => isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) && prefersLightText(mixHexColors(primaryHex, chartBackgroundHex, 1 - (CELL_MIX_FLOOR + (1 - CELL_MIX_FLOOR) * intensity)));
6157
+ const cellHasLightText = (intensity) => isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) && prefersLightText(mixHexColors(primaryHex, chartBackgroundHex, 1 - (CELL_MIX_FLOOR + .85 * intensity)));
6069
6158
  const extent = (0, react.useMemo)(() => getValueExtent(data), [data]);
6070
6159
  const heatmapContext = (0, react.useMemo)(() => ({
6071
6160
  extent,
@@ -6684,7 +6773,7 @@ var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
6684
6773
  tslib_1.__exportStar(require_dist$1(), exports);
6685
6774
  }));
6686
6775
  //#endregion
6687
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
6776
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
6688
6777
  function useUpdateEffect(effect, deps) {
6689
6778
  const mountedRef = (0, react.useRef)(false);
6690
6779
  (0, react.useEffect)(() => {
@@ -6716,10 +6805,11 @@ var StyleSheet = /*#__PURE__*/ function() {
6716
6805
  var _this = this;
6717
6806
  this._insertTag = function(tag) {
6718
6807
  var before;
6719
- if (_this.tags.length === 0) if (_this.insertionPoint) before = _this.insertionPoint.nextSibling;
6720
- else if (_this.prepend) before = _this.container.firstChild;
6721
- else before = _this.before;
6722
- else before = _this.tags[_this.tags.length - 1].nextSibling;
6808
+ if (_this.tags.length === 0) {
6809
+ if (_this.insertionPoint) before = _this.insertionPoint.nextSibling;
6810
+ else if (_this.prepend) before = _this.container.firstChild;
6811
+ else before = _this.before;
6812
+ } else before = _this.tags[_this.tags.length - 1].nextSibling;
6723
6813
  _this.container.insertBefore(tag, before);
6724
6814
  _this.tags.push(tag);
6725
6815
  };
@@ -7038,9 +7128,7 @@ function delimiter(type) {
7038
7128
  case 40:
7039
7129
  if (type === 41) delimiter(type);
7040
7130
  break;
7041
- case 92:
7042
- next();
7043
- break;
7131
+ case 92: next();
7044
7132
  }
7045
7133
  return position;
7046
7134
  }
@@ -8063,14 +8151,12 @@ function handleInterpolation(mergedProps, registered, interpolation) {
8063
8151
  return serializedStyles.styles + ";";
8064
8152
  }
8065
8153
  return createStringFromObject(mergedProps, registered, interpolation);
8066
- case "function":
8067
- if (mergedProps !== void 0) {
8068
- var previousCursor = cursor;
8069
- var result = interpolation(mergedProps);
8070
- cursor = previousCursor;
8071
- return handleInterpolation(mergedProps, registered, result);
8072
- }
8073
- break;
8154
+ case "function": if (mergedProps !== void 0) {
8155
+ var previousCursor = cursor;
8156
+ var result = interpolation(mergedProps);
8157
+ cursor = previousCursor;
8158
+ return handleInterpolation(mergedProps, registered, result);
8159
+ }
8074
8160
  }
8075
8161
  var asString = interpolation;
8076
8162
  if (registered == null) return asString;
@@ -8325,7 +8411,7 @@ _createEmotion.css;
8325
8411
  _createEmotion.sheet;
8326
8412
  _createEmotion.cache;
8327
8413
  //#endregion
8328
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/hooks/use-cx.mjs
8414
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/utils/hooks/use-cx.mjs
8329
8415
  var isSerializedStyles = (o) => typeof o !== "undefined" && o !== null && ["name", "styles"].every((p) => typeof o[p] !== "undefined");
8330
8416
  var useCx = () => {
8331
8417
  const cache = __unsafe_useEmotionCache();
@@ -8432,7 +8518,7 @@ function memize(fn, options) {
8432
8518
  return memoized;
8433
8519
  }
8434
8520
  //#endregion
8435
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/colors-values.mjs
8521
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/utils/colors-values.mjs
8436
8522
  var white = "#fff";
8437
8523
  var GRAY = {
8438
8524
  900: "#1e1e1e",
@@ -8511,7 +8597,7 @@ var COLORS = Object.freeze({
8511
8597
  ui: UI
8512
8598
  });
8513
8599
  //#endregion
8514
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/config-values.mjs
8600
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/utils/config-values.mjs
8515
8601
  var CONTROL_HEIGHT = "36px";
8516
8602
  var CONTROL_PROPS = {
8517
8603
  controlPaddingX: 12,
@@ -8616,10 +8702,10 @@ var require_es6 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8616
8702
  };
8617
8703
  }));
8618
8704
  //#endregion
8619
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.52.0/node_modules/@wordpress/warning/build-module/utils.mjs
8705
+ //#region ../../../node_modules/.pnpm/@wordpress+warning@3.53.0/node_modules/@wordpress/warning/build-module/utils.mjs
8620
8706
  var logged = /* @__PURE__ */ new Set();
8621
8707
  //#endregion
8622
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.52.0/node_modules/@wordpress/warning/build-module/index.mjs
8708
+ //#region ../../../node_modules/.pnpm/@wordpress+warning@3.53.0/node_modules/@wordpress/warning/build-module/index.mjs
8623
8709
  function isDev() {
8624
8710
  return globalThis.SCRIPT_DEBUG === true;
8625
8711
  }
@@ -8633,7 +8719,7 @@ function warning(message) {
8633
8719
  logged.add(message);
8634
8720
  }
8635
8721
  //#endregion
8636
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
8722
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
8637
8723
  var import_es6 = /* @__PURE__ */ __toESM(require_es6(), 1);
8638
8724
  var ComponentsContext = (0, react.createContext)(
8639
8725
  /** @type {Record<string, any>} */
@@ -8660,19 +8746,19 @@ var BaseContextSystemProvider = ({ children, value }) => {
8660
8746
  };
8661
8747
  (0, react.memo)(BaseContextSystemProvider);
8662
8748
  //#endregion
8663
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/constants.mjs
8749
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/context/constants.mjs
8664
8750
  var COMPONENT_NAMESPACE = "data-wp-component";
8665
8751
  var CONNECTED_NAMESPACE = "data-wp-c16t";
8666
8752
  var CONNECT_STATIC_NAMESPACE = "__contextSystemKey__";
8667
8753
  //#endregion
8668
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/get-styled-class-name-from-key.mjs
8754
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/context/get-styled-class-name-from-key.mjs
8669
8755
  var import_dist = require_dist();
8670
8756
  function getStyledClassName(namespace) {
8671
8757
  return `components-${(0, import_dist.paramCase)(namespace)}`;
8672
8758
  }
8673
8759
  var getStyledClassNameFromKey = memize(getStyledClassName);
8674
8760
  //#endregion
8675
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/context-connect.mjs
8761
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/context/context-connect.mjs
8676
8762
  function contextConnect(Component, namespace) {
8677
8763
  return _contextConnect(Component, namespace, { forwardsRef: true });
8678
8764
  }
@@ -8689,7 +8775,7 @@ function _contextConnect(Component, namespace, options) {
8689
8775
  });
8690
8776
  }
8691
8777
  //#endregion
8692
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/utils.mjs
8778
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/context/utils.mjs
8693
8779
  function getNamespace(componentName) {
8694
8780
  return { [COMPONENT_NAMESPACE]: componentName };
8695
8781
  }
@@ -8697,7 +8783,7 @@ function getConnectedNamespace() {
8697
8783
  return { [CONNECTED_NAMESPACE]: true };
8698
8784
  }
8699
8785
  //#endregion
8700
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/use-context-system.mjs
8786
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/context/use-context-system.mjs
8701
8787
  function useContextSystem(props, namespace) {
8702
8788
  const contextSystemProps = useComponentsContext();
8703
8789
  if (typeof namespace === "undefined") globalThis.SCRIPT_DEBUG === true && warning("useContextSystem: Please provide a namespace");
@@ -8717,7 +8803,7 @@ function useContextSystem(props, namespace) {
8717
8803
  return finalComponentProps;
8718
8804
  }
8719
8805
  //#endregion
8720
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/visually-hidden/styles.mjs
8806
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/visually-hidden/styles.mjs
8721
8807
  var visuallyHidden = {
8722
8808
  border: 0,
8723
8809
  clip: "rect(1px, 1px, 1px, 1px)",
@@ -8733,7 +8819,7 @@ var visuallyHidden = {
8733
8819
  wordBreak: "normal"
8734
8820
  };
8735
8821
  //#endregion
8736
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/polymorphic-element.mjs
8822
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/utils/polymorphic-element.mjs
8737
8823
  var customAttributeRegExp = /^(data|aria|x)-/i;
8738
8824
  var eventHandlerRegExp = /^on[A-Z]/;
8739
8825
  var svgElementNames = new Set(`animate animateMotion animateTransform circle clipPath defs desc ellipse
@@ -8815,14 +8901,15 @@ function filterIntrinsicElementProps(props, element) {
8815
8901
  }
8816
8902
  function UnforwardedPolymorphicElement({ as, ...props }, ref) {
8817
8903
  const Element = as || "div";
8904
+ const forwardedProps = typeof Element === "string" ? filterIntrinsicElementProps(props, Element) : props;
8818
8905
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Element, {
8819
8906
  ref,
8820
- ...typeof Element === "string" ? filterIntrinsicElementProps(props, Element) : props
8907
+ ...forwardedProps
8821
8908
  });
8822
8909
  }
8823
8910
  var PolymorphicElement = (0, react.forwardRef)(UnforwardedPolymorphicElement);
8824
8911
  //#endregion
8825
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/view/component.mjs
8912
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/view/component.mjs
8826
8913
  function UnforwardedView({ css, ...restProps }, ref) {
8827
8914
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PolymorphicElement, {
8828
8915
  ref,
@@ -8831,7 +8918,7 @@ function UnforwardedView({ css, ...restProps }, ref) {
8831
8918
  }
8832
8919
  var component_default$2 = Object.assign((0, react.forwardRef)(UnforwardedView), { selector: ".components-view" });
8833
8920
  //#endregion
8834
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/visually-hidden/component.mjs
8921
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/visually-hidden/component.mjs
8835
8922
  function UnconnectedVisuallyHidden(props, forwardedRef) {
8836
8923
  const { style: styleProp, ...contextProps } = useContextSystem(props, "VisuallyHidden");
8837
8924
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$2, {
@@ -8846,7 +8933,7 @@ function UnconnectedVisuallyHidden(props, forwardedRef) {
8846
8933
  }
8847
8934
  var component_default$1 = contextConnect(UnconnectedVisuallyHidden, "VisuallyHidden");
8848
8935
  //#endregion
8849
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/use-responsive-value.mjs
8936
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/utils/use-responsive-value.mjs
8850
8937
  var breakpoints = [
8851
8938
  "40em",
8852
8939
  "52em",
@@ -8880,7 +8967,7 @@ function useResponsiveValue(values, options = {}) {
8880
8967
  return array[index >= array.length ? array.length - 1 : index];
8881
8968
  }
8882
8969
  //#endregion
8883
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/grid/utils.mjs
8970
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/grid/utils.mjs
8884
8971
  var ALIGNMENTS = {
8885
8972
  bottom: {
8886
8973
  alignItems: "flex-end",
@@ -8928,7 +9015,7 @@ function getAlignmentProps(alignment) {
8928
9015
  return alignment ? ALIGNMENTS[alignment] : {};
8929
9016
  }
8930
9017
  //#endregion
8931
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/grid/hook.mjs
9018
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/grid/hook.mjs
8932
9019
  function useGrid(props) {
8933
9020
  const { align, alignment, className, columnGap, columns = 2, gap = 3, isInline = false, justify, rowGap, rows, templateColumns, templateRows, ...otherProps } = useContextSystem(props, "Grid");
8934
9021
  const column = useResponsiveValue(Array.isArray(columns) ? columns : [columns]);
@@ -8970,10 +9057,11 @@ function useGrid(props) {
8970
9057
  };
8971
9058
  }
8972
9059
  //#endregion
8973
- //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/grid/component.mjs
9060
+ //#region ../../../node_modules/.pnpm/@wordpress+components@37.0.0_@types+react-dom@18.3.7_@types+react@18.3.31__@types+react_e283446b3cbc213906bb0d97b3dd78c5/node_modules/@wordpress/components/build-module/grid/component.mjs
8974
9061
  function UnconnectedGrid(props, forwardedRef) {
9062
+ const gridProps = useGrid(props);
8975
9063
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$2, {
8976
- ...useGrid(props),
9064
+ ...gridProps,
8977
9065
  ref: forwardedRef
8978
9066
  });
8979
9067
  }
@@ -9285,15 +9373,17 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
9285
9373
  withComparison,
9286
9374
  withOverlayLabel
9287
9375
  ]);
9376
+ const isDataValid = Boolean(data && data.length > 0);
9377
+ const chartMetadata = (0, react.useMemo)(() => ({
9378
+ withComparison,
9379
+ withOverlayLabel
9380
+ }), [withComparison, withOverlayLabel]);
9288
9381
  useChartRegistration({
9289
9382
  chartId,
9290
9383
  legendItems,
9291
9384
  chartType: "leaderboard",
9292
- isDataValid: Boolean(data && data.length > 0),
9293
- metadata: (0, react.useMemo)(() => ({
9294
- withComparison,
9295
- withOverlayLabel
9296
- }), [withComparison, withOverlayLabel])
9385
+ isDataValid,
9386
+ metadata: chartMetadata
9297
9387
  });
9298
9388
  const prefersReducedMotion = usePrefersReducedMotion();
9299
9389
  const { contentRef, fittedCount, isMeasurable } = useFittedRowCount(fitRows && !allSeriesHidden, data?.length ?? 0, data);
@@ -9548,8 +9638,9 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
9548
9638
  hideTooltip();
9549
9639
  }, [withTooltips, hideTooltip]);
9550
9640
  const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
9641
+ const dataWithPercentages = useDataWithPercentages(data);
9551
9642
  const { visibleData, allSegmentsHidden, legendData } = useLegendVisibilityData({
9552
- data: useDataWithPercentages(data),
9643
+ data: dataWithPercentages,
9553
9644
  chartId,
9554
9645
  isSeriesVisible
9555
9646
  });
@@ -9559,20 +9650,21 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
9559
9650
  }), [legendValueDisplay]));
9560
9651
  const { isValid, message } = validateData$1(data);
9561
9652
  const { svgChildren, htmlChildren, legendChildren, otherChildren } = useChartChildren(children, "PieChart");
9653
+ const chartMetadata = (0, react.useMemo)(() => ({
9654
+ thickness,
9655
+ gapScale,
9656
+ cornerScale
9657
+ }), [
9658
+ thickness,
9659
+ gapScale,
9660
+ cornerScale
9661
+ ]);
9562
9662
  useChartRegistration({
9563
9663
  chartId,
9564
9664
  legendItems,
9565
9665
  chartType: "pie",
9566
9666
  isDataValid: isValid,
9567
- metadata: (0, react.useMemo)(() => ({
9568
- thickness,
9569
- gapScale,
9570
- cornerScale
9571
- }), [
9572
- thickness,
9573
- gapScale,
9574
- cornerScale
9575
- ])
9667
+ metadata: chartMetadata
9576
9668
  });
9577
9669
  const prefersReducedMotion = usePrefersReducedMotion();
9578
9670
  if (!isValid) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -9701,14 +9793,12 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
9701
9793
  }
9702
9794
  const svgLabelSmall = providerTheme.svgLabelSmall;
9703
9795
  const fontSize = resolveFontSize(svgLabelSmall?.fontSize) ?? 12;
9704
- const estimatedTextWidth = (0, _visx_text.getStringWidth)(arc.data.label, {
9796
+ const backgroundWidth = (0, _visx_text.getStringWidth)(arc.data.label, {
9705
9797
  fontSize,
9706
9798
  fontFamily: svgLabelSmall?.fontFamily,
9707
9799
  fontWeight: svgLabelSmall?.fontWeight
9708
- });
9709
- const labelPadding = 6;
9710
- const backgroundWidth = estimatedTextWidth + labelPadding * 2;
9711
- const backgroundHeight = fontSize + labelPadding * 2;
9800
+ }) + 12;
9801
+ const backgroundHeight = fontSize + 12;
9712
9802
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
9713
9803
  ...groupProps,
9714
9804
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { ...pathProps }), showLabels && hasSpaceForLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [providerTheme.labelBackgroundColor && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
@@ -9840,8 +9930,9 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
9840
9930
  }, [handleMouseMove]);
9841
9931
  const { isValid, message } = validateData(data);
9842
9932
  const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
9933
+ const dataWithPercentages = useDataWithPercentages(data);
9843
9934
  const { visibleData, allSegmentsHidden, legendData } = useLegendVisibilityData({
9844
- data: useDataWithPercentages(data),
9935
+ data: dataWithPercentages,
9845
9936
  chartId,
9846
9937
  isSeriesVisible
9847
9938
  });
@@ -9858,15 +9949,16 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
9858
9949
  legendValueDisplay
9859
9950
  }), [legendValueDisplay]));
9860
9951
  const { svgChildren, htmlChildren, legendChildren, otherChildren } = useChartChildren(children, "PieSemiCircleChart");
9952
+ const chartMetadata = (0, react.useMemo)(() => ({
9953
+ thickness,
9954
+ clockwise
9955
+ }), [thickness, clockwise]);
9861
9956
  useChartRegistration({
9862
9957
  chartId,
9863
9958
  legendItems,
9864
9959
  chartType: "pie-semi-circle",
9865
9960
  isDataValid: isValid,
9866
- metadata: (0, react.useMemo)(() => ({
9867
- thickness,
9868
- clockwise
9869
- }), [thickness, clockwise])
9961
+ metadata: chartMetadata
9870
9962
  });
9871
9963
  const prefersReducedMotion = usePrefersReducedMotion();
9872
9964
  const effectiveWidth = propWidth || DEFAULT_WIDTH$1;
@@ -10057,6 +10149,7 @@ const transformToSeriesData = (data, color, strokeWidth) => {
10057
10149
  };
10058
10150
  const SparklineComponent = (0, react.forwardRef)(({ data, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, color, strokeWidth: strokeWidthProp, withGradientFill = true, gradient, className, chartId, margin: marginProp, animation }, ref) => {
10059
10151
  const theme = useGlobalChartsTheme();
10152
+ const chartsContext = (0, react.useContext)(GlobalChartsContext);
10060
10153
  const themeStrokeWidth = theme.sparkline?.strokeWidth ?? 1.5;
10061
10154
  const strokeWidth = strokeWidthProp ?? themeStrokeWidth;
10062
10155
  const seriesData = (0, react.useMemo)(() => {
@@ -10110,7 +10203,7 @@ const SparklineComponent = (0, react.forwardRef)(({ data, width = DEFAULT_WIDTH,
10110
10203
  if (data.length === 1) {
10111
10204
  const cx = width / 2;
10112
10205
  const cy = height / 2;
10113
- const resolvedColor = color || "#000000";
10206
+ const resolvedColor = color || chartsContext?.getElementStyles({ index: 0 }).color || "#000000";
10114
10207
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10115
10208
  ref,
10116
10209
  className: (0, clsx.default)("sparkline", sparkline_module_default.sparkline, sparkline_module_default["sparkline--single-point"], className),
@@ -10213,8 +10306,9 @@ const Icon = ({ direction }) => {
10213
10306
  */
10214
10307
  function TrendIndicator({ direction, value, className, style, showIcon = true }) {
10215
10308
  const ariaLabel = `${DIRECTION_LABELS[direction]}: ${value}`;
10309
+ const standaloneScopeClass = useStandaloneScopeClass();
10216
10310
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
10217
- className: (0, clsx.default)(useStandaloneScopeClass(), trend_indicator_module_default["trend-indicator"], trend_indicator_module_default[`trend-indicator--${direction}`], className),
10311
+ className: (0, clsx.default)(standaloneScopeClass, trend_indicator_module_default["trend-indicator"], trend_indicator_module_default[`trend-indicator--${direction}`], className),
10218
10312
  style,
10219
10313
  "aria-label": ariaLabel,
10220
10314
  children: [showIcon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { direction }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {