@automattic/charts 3.1.1 → 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 (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/TOKENS.md +51 -12
  3. package/dist/index.cjs +292 -200
  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 +291 -199
  9. package/dist/index.js.map +1 -1
  10. package/package.json +8 -8
  11. package/src/charts/bar-chart/bar-chart.tsx +36 -10
  12. package/src/charts/bar-chart/test/bar-chart-pointer-events.test.tsx +67 -0
  13. package/src/charts/bar-chart/test/bar-chart.test.tsx +79 -0
  14. package/src/charts/bar-list-chart/bar-list-chart.tsx +40 -2
  15. package/src/charts/bar-list-chart/test/bar-list-chart.test.tsx +38 -0
  16. package/src/charts/line-chart/line-chart.tsx +16 -1
  17. package/src/charts/line-chart/test/line-chart.test.tsx +47 -0
  18. package/src/charts/sparkline/sparkline.tsx +9 -3
  19. package/src/charts/sparkline/types.ts +1 -1
  20. package/src/components/tooltip/accessible-tooltip.tsx +32 -2
  21. package/src/components/tooltip/test/accessible-tooltip.test.tsx +68 -0
  22. package/src/hooks/test/use-xychart-theme-provider-override.test.tsx +4 -4
  23. package/src/hooks/test/use-xychart-theme-style-reads.test.tsx +17 -10
  24. package/src/hooks/test/use-xychart-theme.test.tsx +50 -5
  25. package/src/hooks/use-xychart-theme.ts +14 -20
  26. package/src/providers/chart-context/global-charts-provider.tsx +44 -33
  27. package/src/providers/chart-context/private/series-palette.ts +45 -0
  28. package/src/providers/chart-context/private/theme-override-vars.ts +46 -2
  29. package/src/providers/chart-context/private/with-catalog-pointers.ts +45 -2
  30. package/src/providers/chart-context/test/sparse-theme.test.ts +16 -2
  31. package/src/providers/chart-context/test/theme-override-vars.test.ts +65 -0
  32. package/src/providers/chart-context/test/use-global-charts-theme.test.tsx +8 -1
  33. package/src/providers/chart-context/test/with-catalog-pointers.test.ts +57 -0
  34. package/src/providers/chart-context/themes.ts +8 -3
  35. package/src/styles/chart-scope.scss +52 -24
  36. package/src/styles/test/chart-scope.test.ts +22 -9
  37. package/src/types.ts +148 -31
  38. package/src/utils/get-styles.ts +7 -1
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@ var __copyProps = (to, from, except, desc) => {
45
45
  }
46
46
  return to;
47
47
  };
48
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
48
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
49
49
  value: mod,
50
50
  enumerable: true
51
51
  }) : target, mod));
@@ -250,7 +250,8 @@ const formatPercentage = (value) => {
250
250
  */
251
251
  const getLongestTickWidth = (ticks, formatTick, labelStyle) => {
252
252
  const formattedTicks = ticks.map((tick) => formatTick(tick, 0, []));
253
- return getStringWidth(formattedTicks.reduce((longest, current) => longest.length >= current.length ? longest : current, formattedTicks[0]), labelStyle);
253
+ const longestTick = formattedTicks.reduce((longest, current) => longest.length >= current.length ? longest : current, formattedTicks[0]);
254
+ return getStringWidth(longestTick, labelStyle);
254
255
  };
255
256
  //#endregion
256
257
  //#region src/utils/get-styles.ts
@@ -760,6 +761,16 @@ const getChartColor = (index, colorCache) => {
760
761
  const fallbackLightness = BASE_LIGHTNESS + index % LIGHTNESS_VARIATION_STEPS * LIGHTNESS_INCREMENT;
761
762
  return hsl(Math.round(fallbackHue), fallbackSaturation / 100, fallbackLightness / 100).formatHex();
762
763
  };
764
+ /**
765
+ * The catalog role holding one series-palette slot.
766
+ *
767
+ * @param slot - The one-based slot number.
768
+ * @return The role name.
769
+ */
770
+ const seriesRole = (slot) => `--a8c-charts-color-series-${slot}`;
771
+ const SERIES_SLOT_1_FALLBACK = "#3858e9";
772
+ /** The catalog pointer for every slot, in slot order. */
773
+ const SERIES_PALETTE_POINTERS = Array.from({ length: 5 }, (_, index) => index === 0 ? `var(${seriesRole(1)}, ${SERIES_SLOT_1_FALLBACK})` : `var(${seriesRole(index + 1)})`);
763
774
  //#endregion
764
775
  //#region src/providers/chart-context/private/theme-override-vars.ts
765
776
  const ROLE_FOR_FIELD = [
@@ -767,8 +778,22 @@ const ROLE_FOR_FIELD = [
767
778
  ["--a8c-charts-color-grid", (theme) => theme.gridStyles?.stroke],
768
779
  ["--a8c-charts-color-axis", (theme) => theme.xAxisLineStyles?.stroke],
769
780
  ["--a8c-charts-color-tick", (theme) => theme.xTickLineStyles?.stroke],
770
- ["--a8c-charts-color-label-axis", (theme) => theme.svgLabelSmall?.fill]
781
+ ["--a8c-charts-color-label-axis", (theme) => theme.svgLabelSmall?.fill],
782
+ ["--a8c-charts-color-label-background", (theme) => theme.labelBackgroundColor],
783
+ ["--a8c-charts-color-label-on-fill", (theme) => theme.labelTextColor],
784
+ ...Array.from({ length: 5 }, (_, index) => [seriesRole(index + 1), (theme) => theme.colors?.[index]])
771
785
  ];
786
+ let warnedAboutExtraColors = false;
787
+ /**
788
+ * Warns once when a consumer passes more colors than there are slots to publish them into.
789
+ *
790
+ * @param count - How many entries `theme.colors` holds.
791
+ */
792
+ function warnOnceAboutExtraColors(count) {
793
+ if (warnedAboutExtraColors || process.env.NODE_ENV === "production") return;
794
+ warnedAboutExtraColors = true;
795
+ 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.`);
796
+ }
772
797
  /**
773
798
  * The variable a `theme` prop override is published as, one layer outside the role itself.
774
799
  *
@@ -782,7 +807,7 @@ ROLE_FOR_FIELD.map(([role]) => role);
782
807
  /**
783
808
  * Whether a value reads the role it is being published for, which would make the catalog entry depend on itself.
784
809
  *
785
- * 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`.
810
+ * 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`.
786
811
  *
787
812
  * Three things this has to get right, none of which a plain substring test gets:
788
813
  *
@@ -798,10 +823,12 @@ ROLE_FOR_FIELD.map(([role]) => role);
798
823
  */
799
824
  const readsOwnRole = (value, role) => value.trim() === role || new RegExp(`var\\(\\s*${role.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w-])`).test(value);
800
825
  /**
801
- * 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.
826
+ * 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.
802
827
  *
803
828
  * 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.
804
829
  *
830
+ * `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.
831
+ *
805
832
  * @param theme - The consumer's `theme` prop, before merging with the default theme.
806
833
  * @return The wrapper's custom properties, and the roles the consumer overrode.
807
834
  */
@@ -810,6 +837,7 @@ const themeOverrideVars = (theme) => {
810
837
  vars: {},
811
838
  roles: []
812
839
  };
840
+ if (Array.isArray(theme.colors) && theme.colors.length > 5) warnOnceAboutExtraColors(theme.colors.length);
813
841
  const vars = {};
814
842
  const roles = [];
815
843
  for (const [role, read] of ROLE_FOR_FIELD) {
@@ -830,15 +858,9 @@ const themeOverrideVars = (theme) => {
830
858
  */
831
859
  const defaultTheme = {
832
860
  backgroundColor: "var(--a8c-charts-color-background, #fff)",
833
- labelBackgroundColor: "transparent",
861
+ labelBackgroundColor: "var(--a8c-charts-color-label-background, transparent)",
834
862
  labelTextColor: "var(--a8c-charts-color-label-on-fill, #FFFFFF)",
835
- colors: [
836
- "#98C8DF",
837
- "#006DAB",
838
- "#A6DC80",
839
- "#1F9828",
840
- "#FF8C8F"
841
- ],
863
+ colors: [...SERIES_PALETTE_POINTERS],
842
864
  gridStyles: {
843
865
  stroke: "var(--a8c-charts-color-grid, #dbdbdb)",
844
866
  strokeWidth: 1
@@ -918,7 +940,23 @@ const defaultTheme = {
918
940
  };
919
941
  //#endregion
920
942
  //#region src/providers/chart-context/private/with-catalog-pointers.ts
943
+ /**
944
+ * The pointer one palette slot is restored to.
945
+ *
946
+ * 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`.
947
+ *
948
+ * @param index - The slot's zero-based index in `colors`.
949
+ * @param value - The merged theme's entry for it.
950
+ * @return The catalog pointer for that slot.
951
+ */
952
+ const seriesPointer = (index, value) => {
953
+ const role = seriesRole(index + 1);
954
+ if (typeof value === "string" && value.startsWith(`var(${role}`)) return value;
955
+ if (typeof value !== "string" || value === "") return SERIES_PALETTE_POINTERS[index];
956
+ return `var(${role}, ${value})`;
957
+ };
921
958
  const CATALOG_RESTORE_FOR_ROLE = {
959
+ ...Object.fromEntries(Array.from({ length: 5 }, (_, index) => [seriesRole(index + 1), (theme) => ({ colors: SERIES_PALETTE_POINTERS.map((_pointer, slot) => seriesPointer(slot, theme.colors?.[slot])) })])),
922
960
  "--a8c-charts-color-background": () => ({ backgroundColor: defaultTheme.backgroundColor }),
923
961
  "--a8c-charts-color-grid": (theme) => ({ gridStyles: {
924
962
  ...theme.gridStyles,
@@ -935,14 +973,16 @@ const CATALOG_RESTORE_FOR_ROLE = {
935
973
  "--a8c-charts-color-label-axis": (theme) => ({ svgLabelSmall: {
936
974
  ...theme.svgLabelSmall,
937
975
  fill: defaultTheme.svgLabelSmall.fill
938
- } })
976
+ } }),
977
+ "--a8c-charts-color-label-background": () => ({ labelBackgroundColor: defaultTheme.labelBackgroundColor }),
978
+ "--a8c-charts-color-label-on-fill": () => ({ labelTextColor: defaultTheme.labelTextColor })
939
979
  };
940
980
  /**
941
981
  * 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.
942
982
  *
943
983
  * 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`.
944
984
  *
945
- * 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.
985
+ * 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.
946
986
  *
947
987
  * @param merged - The consumer theme merged onto `defaultTheme` (`mergeThemes` output).
948
988
  * @param overriddenRoles - The catalog roles the consumer overrode, from `themeOverrideVars`.
@@ -987,29 +1027,26 @@ const GlobalChartsProvider = ({ children, theme }) => {
987
1027
  const [isColorPaletteResolved, setIsColorPaletteResolved] = useState(false);
988
1028
  useLayoutEffect(() => {
989
1029
  setIsColorPaletteResolved(false);
990
- const { colors } = providerTheme;
991
1030
  const resolvedColors = [];
992
1031
  const hues = [];
993
1032
  const existingHslColors = [];
994
1033
  let minHue = 360;
995
1034
  let maxHue = 0;
996
- if (Array.isArray(colors)) {
997
- for (const color of colors) if (color && typeof color === "string") {
998
- const normalizedColor = normalizeColorToHex(color, wrapperRef.current, resolveCssVariable);
999
- if (normalizedColor.startsWith("#")) {
1000
- resolvedColors.push(normalizedColor);
1001
- const hslColor = hsl(normalizedColor);
1002
- if (!isNaN(hslColor.h)) {
1003
- const hslTuple = [
1004
- hslColor.h,
1005
- hslColor.s * 100,
1006
- hslColor.l * 100
1007
- ];
1008
- hues.push(hslTuple[0]);
1009
- existingHslColors.push(hslTuple);
1010
- minHue = Math.min(minHue, hslTuple[0]);
1011
- maxHue = Math.max(maxHue, hslTuple[0]);
1012
- }
1035
+ for (const color of providerTheme.colors ?? SERIES_PALETTE_POINTERS) {
1036
+ const normalizedColor = normalizeColorToHex(color, wrapperRef.current, resolveCssVariable);
1037
+ if (normalizedColor.startsWith("#")) {
1038
+ resolvedColors.push(normalizedColor);
1039
+ const hslColor = hsl(normalizedColor);
1040
+ if (!isNaN(hslColor.h)) {
1041
+ const hslTuple = [
1042
+ hslColor.h,
1043
+ hslColor.s * 100,
1044
+ hslColor.l * 100
1045
+ ];
1046
+ hues.push(hslTuple[0]);
1047
+ existingHslColors.push(hslTuple);
1048
+ minHue = Math.min(minHue, hslTuple[0]);
1049
+ maxHue = Math.max(maxHue, hslTuple[0]);
1013
1050
  }
1014
1051
  }
1015
1052
  }
@@ -1025,9 +1062,10 @@ const GlobalChartsProvider = ({ children, theme }) => {
1025
1062
  if (colorCache.colors.length > 0) setIsColorPaletteResolved(true);
1026
1063
  }, [colorCache]);
1027
1064
  const [groupToColorMap, setGroupToColorMap] = useState(() => /* @__PURE__ */ new Map());
1065
+ const paletteKey = colorCache.colors.join(",");
1028
1066
  useEffect(() => {
1029
1067
  setGroupToColorMap(/* @__PURE__ */ new Map());
1030
- }, [providerTheme.colors]);
1068
+ }, [paletteKey]);
1031
1069
  const registerChart = useCallback((id, data) => {
1032
1070
  setCharts((prev) => new Map(prev).set(id, data));
1033
1071
  }, []);
@@ -1240,27 +1278,13 @@ const useXYChartTheme = (data) => {
1240
1278
  return useMemo(() => {
1241
1279
  const resolve = createCssVariableResolver(scopeElement);
1242
1280
  const resolveColor = (value) => value ? resolve(value) ?? value : value;
1243
- const seriesColors = JSON.parse(seriesColorKey);
1281
+ const paletteColors = [...JSON.parse(seriesColorKey), ...theme.colors ?? []].map((color) => resolveColor(color)).filter((color) => Boolean(color) && !color.includes("var("));
1282
+ const htmlLabelColor = resolveColor(theme.svgLabelSmall?.fill);
1244
1283
  return buildChartTheme({
1245
1284
  ...theme,
1246
- colors: [...seriesColors, ...theme.colors ?? []],
1285
+ colors: paletteColors,
1247
1286
  backgroundColor: resolveColor(theme.backgroundColor),
1248
- gridStyles: theme.gridStyles && {
1249
- ...theme.gridStyles,
1250
- stroke: resolveColor(theme.gridStyles.stroke)
1251
- },
1252
- xAxisLineStyles: theme.xAxisLineStyles && {
1253
- ...theme.xAxisLineStyles,
1254
- stroke: resolveColor(theme.xAxisLineStyles.stroke)
1255
- },
1256
- xTickLineStyles: theme.xTickLineStyles && {
1257
- ...theme.xTickLineStyles,
1258
- stroke: resolveColor(theme.xTickLineStyles.stroke)
1259
- },
1260
- svgLabelSmall: theme.svgLabelSmall && {
1261
- ...theme.svgLabelSmall,
1262
- fill: resolveColor(theme.svgLabelSmall.fill)
1263
- }
1287
+ htmlLabel: htmlLabelColor ? { color: htmlLabelColor } : void 0
1264
1288
  });
1265
1289
  }, [
1266
1290
  theme,
@@ -1357,11 +1381,12 @@ const useChartMargin = (height, options, data, theme, horizontal = false) => {
1357
1381
  if (options.axis?.y?.tickValues?.length) return options.axis.y.tickValues;
1358
1382
  const minY = Math.min(...allDataPoints.map((d) => d.value));
1359
1383
  const maxY = Math.max(...allDataPoints.map((d) => d.value));
1360
- return getTicks(createScale({
1384
+ const yScale = createScale({
1361
1385
  ...options.yScale,
1362
1386
  domain: [minY, maxY],
1363
1387
  range: [height, 0]
1364
- }), options.axis?.y?.numTicks);
1388
+ });
1389
+ return getTicks(yScale, options.axis?.y?.numTicks);
1365
1390
  }, [
1366
1391
  options,
1367
1392
  data,
@@ -1486,7 +1511,7 @@ const MIN_PIXEL_SIZE = 3;
1486
1511
  /**
1487
1512
  * Pixel size for zero-value bars (1px less than near-zero to be visually distinguishable).
1488
1513
  */
1489
- const ZERO_PIXEL_SIZE = MIN_PIXEL_SIZE - 1;
1514
+ const ZERO_PIXEL_SIZE = 2;
1490
1515
  const useZeroValueDisplay = (data, options = { enabled: false }) => {
1491
1516
  const { enabled, valueAxisLength } = options;
1492
1517
  return useMemo(() => {
@@ -2102,8 +2127,14 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
2102
2127
  };
2103
2128
  //#endregion
2104
2129
  //#region src/components/tooltip/accessible-tooltip.tsx
2105
- const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", ...props }) => {
2130
+ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocusedClassName, series = [], mode = "group", verticalCrosshairStyle, horizontalCrosshairStyle, ...props }) => {
2106
2131
  const tooltipContext = useContext(TooltipContext);
2132
+ const scopeElement = useChartScopeElement();
2133
+ const gridStroke = useGlobalChartsTheme().gridStyles?.stroke;
2134
+ const crosshairStroke = useMemo(() => {
2135
+ const stroke = gridStroke ? resolveCssVariable(gridStroke, scopeElement) : null;
2136
+ return stroke ? { stroke } : void 0;
2137
+ }, [gridStroke, scopeElement]);
2107
2138
  const tooltipData = useMemo(() => {
2108
2139
  if (mode !== "individual") return [];
2109
2140
  if (series.length === 0) return [];
@@ -2182,10 +2213,18 @@ const AccessibleTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardF
2182
2213
  ]);
2183
2214
  return /* @__PURE__ */ jsx(Tooltip, {
2184
2215
  ...props,
2216
+ verticalCrosshairStyle: {
2217
+ ...crosshairStroke,
2218
+ ...verticalCrosshairStyle
2219
+ },
2220
+ horizontalCrosshairStyle: {
2221
+ ...crosshairStroke,
2222
+ ...horizontalCrosshairStyle
2223
+ },
2185
2224
  renderTooltip: focusableRenderTooltip
2186
2225
  });
2187
2226
  };
2188
- const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints }) => {
2227
+ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints, onActivate }) => {
2189
2228
  return {
2190
2229
  tooltipRef: useCallback((element) => {
2191
2230
  if (element && selectedIndex !== void 0) element.focus();
@@ -2226,13 +2265,14 @@ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating,
2226
2265
  setSelectedIndex(void 0);
2227
2266
  setIsNavigating(false);
2228
2267
  chartRef.current?.focus();
2229
- }
2268
+ } else if ((event.key === "Enter" || event.key === " ") && selectedIndex !== void 0) onActivate?.(selectedIndex);
2230
2269
  }, [
2231
2270
  totalPoints,
2232
2271
  selectedIndex,
2233
2272
  setSelectedIndex,
2234
2273
  setIsNavigating,
2235
- chartRef
2274
+ chartRef,
2275
+ onActivate
2236
2276
  ])
2237
2277
  };
2238
2278
  };
@@ -2999,7 +3039,7 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
2999
3039
  style: {
3000
3040
  width: `44px`,
3001
3041
  height: `44px`,
3002
- transform: `translate(${44 / 2}px, 0)`
3042
+ transform: `translate(22px, 0)`
3003
3043
  },
3004
3044
  "aria-label": title || __("View details", "jetpack-charts"),
3005
3045
  children: renderLabel({
@@ -3420,7 +3460,7 @@ const LineChartScalesRef = ({ chartRef, width, height, margin }) => {
3420
3460
  ]);
3421
3461
  return null;
3422
3462
  };
3423
- const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, 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) => {
3463
+ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, 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) => {
3424
3464
  const legendInteractive = legend.interactive ?? false;
3425
3465
  const legendCollapseGroups = legend.collapseGroups ?? false;
3426
3466
  const legendShape = legend.shape ?? "line";
@@ -3482,13 +3522,23 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
3482
3522
  }
3483
3523
  return min < max ? [min, max] : void 0;
3484
3524
  }, [rescaleYOnVisibilityChange, dataSorted]);
3525
+ const activateSelectedPoint = useCallback((index) => {
3526
+ const series = dataSorted[0];
3527
+ const datum = series?.data[index];
3528
+ if (series && datum) onDatumActivate?.({
3529
+ datum,
3530
+ index,
3531
+ key: series.label
3532
+ });
3533
+ }, [dataSorted, onDatumActivate]);
3485
3534
  const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
3486
3535
  selectedIndex,
3487
3536
  setSelectedIndex,
3488
3537
  isNavigating,
3489
3538
  setIsNavigating,
3490
3539
  chartRef,
3491
- totalPoints: dataSorted[0]?.data.length || 0
3540
+ totalPoints: dataSorted[0]?.data.length || 0,
3541
+ onActivate: activateSelectedPoint
3492
3542
  });
3493
3543
  const chartOptions = useMemo(() => {
3494
3544
  const { tickResolution, tickFormat, ...xAxisOptions } = options?.axis?.x ?? {};
@@ -3552,36 +3602,38 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
3552
3602
  const defaultMargin = useChartMargin(height, chartOptions, dataSorted, theme);
3553
3603
  const error = validateData$4(dataSorted);
3554
3604
  const isDataValid = !error;
3605
+ const legendItems = useChartLegendItems(dataSorted, useMemo(() => ({
3606
+ withGlyph: withLegendGlyph,
3607
+ glyphSize: Math.max(0, toNumber(glyphStyle?.radius) ?? 4),
3608
+ collapseGroups: legendCollapseGroups,
3609
+ renderGlyph
3610
+ }), [
3611
+ withLegendGlyph,
3612
+ glyphStyle?.radius,
3613
+ legendCollapseGroups,
3614
+ renderGlyph
3615
+ ]), legendShape);
3616
+ const chartMetadata = useMemo(() => ({
3617
+ withGradientFill,
3618
+ smoothing,
3619
+ curveType,
3620
+ withStartGlyphs,
3621
+ withEndGlyphs,
3622
+ withLegendGlyph
3623
+ }), [
3624
+ withGradientFill,
3625
+ smoothing,
3626
+ curveType,
3627
+ withStartGlyphs,
3628
+ withEndGlyphs,
3629
+ withLegendGlyph
3630
+ ]);
3555
3631
  useChartRegistration({
3556
3632
  chartId,
3557
- legendItems: useChartLegendItems(dataSorted, useMemo(() => ({
3558
- withGlyph: withLegendGlyph,
3559
- glyphSize: Math.max(0, toNumber(glyphStyle?.radius) ?? 4),
3560
- collapseGroups: legendCollapseGroups,
3561
- renderGlyph
3562
- }), [
3563
- withLegendGlyph,
3564
- glyphStyle?.radius,
3565
- legendCollapseGroups,
3566
- renderGlyph
3567
- ]), legendShape),
3633
+ legendItems,
3568
3634
  chartType: "line",
3569
3635
  isDataValid,
3570
- metadata: useMemo(() => ({
3571
- withGradientFill,
3572
- smoothing,
3573
- curveType,
3574
- withStartGlyphs,
3575
- withEndGlyphs,
3576
- withLegendGlyph
3577
- }), [
3578
- withGradientFill,
3579
- smoothing,
3580
- curveType,
3581
- withStartGlyphs,
3582
- withEndGlyphs,
3583
- withLegendGlyph
3584
- ])
3636
+ metadata: chartMetadata
3585
3637
  });
3586
3638
  const prefersReducedMotion = usePrefersReducedMotion();
3587
3639
  const accessors = {
@@ -4001,26 +4053,28 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
4001
4053
  const defaultMargin = useChartMargin(height, chartOptions, dataSorted, theme);
4002
4054
  const error = validateData$3(dataSorted);
4003
4055
  const isDataValid = !error;
4056
+ const legendItems = useChartLegendItems(dataSorted, useMemo(() => ({
4057
+ withGlyph: false,
4058
+ glyphSize: 0,
4059
+ collapseGroups: legend.collapseGroups ?? false
4060
+ }), [legend.collapseGroups]), legendShape);
4061
+ const chartMetadata = useMemo(() => ({
4062
+ stacked,
4063
+ stackOffset,
4064
+ smoothing,
4065
+ curveType
4066
+ }), [
4067
+ stacked,
4068
+ stackOffset,
4069
+ smoothing,
4070
+ curveType
4071
+ ]);
4004
4072
  useChartRegistration({
4005
4073
  chartId,
4006
- legendItems: useChartLegendItems(dataSorted, useMemo(() => ({
4007
- withGlyph: false,
4008
- glyphSize: 0,
4009
- collapseGroups: legend.collapseGroups ?? false
4010
- }), [legend.collapseGroups]), legendShape),
4074
+ legendItems,
4011
4075
  chartType: "area",
4012
4076
  isDataValid,
4013
- metadata: useMemo(() => ({
4014
- stacked,
4015
- stackOffset,
4016
- smoothing,
4017
- curveType
4018
- }), [
4019
- stacked,
4020
- stackOffset,
4021
- smoothing,
4022
- curveType
4023
- ])
4077
+ metadata: chartMetadata
4024
4078
  });
4025
4079
  const prefersReducedMotion = usePrefersReducedMotion();
4026
4080
  const animationEnabled = !!animation && !prefersReducedMotion;
@@ -4615,11 +4669,6 @@ function computeComparisonRect(params) {
4615
4669
  };
4616
4670
  }
4617
4671
  /**
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
4672
  * Upper clamp on the computed group padding, so bars can never collapse to zero width
4624
4673
  * even at very large `widthFactor` values.
4625
4674
  */
@@ -4707,7 +4756,7 @@ const renderTooltipRow = (label, value) => /* @__PURE__ */ jsx("div", {
4707
4756
  className: bar_chart_module_default["bar-chart__tooltip-row"],
4708
4757
  children: sprintf(__("%1$s: %2$s", "jetpack-charts"), label, value)
4709
4758
  });
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" }) => {
4759
+ 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
4760
  const legendInteractive = legend.interactive ?? false;
4712
4761
  const legendCollapseGroups = legend.collapseGroups ?? false;
4713
4762
  const horizontal = orientation === "horizontal";
@@ -4734,14 +4783,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4734
4783
  const [selectedIndex, setSelectedIndex] = useState(void 0);
4735
4784
  const [isNavigating, setIsNavigating] = useState(false);
4736
4785
  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
- });
4786
+ const totalPoints = Math.max(0, ...primarySeriesForNav.map((s) => s.data?.length || 0)) * primarySeriesForNav.length;
4745
4787
  const seriesWithVisibility = useMemo(() => dataWithVisibleZeros.map((series, index) => ({
4746
4788
  series,
4747
4789
  index,
@@ -4753,6 +4795,27 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4753
4795
  const primaryEntries = useMemo(() => seriesWithVisibility.filter(({ isVisible, series }) => isVisible && series.options?.type !== "comparison"), [seriesWithVisibility]);
4754
4796
  const primaryKeys = useMemo(() => primaryEntries.map(({ series }) => series.label), [primaryEntries]);
4755
4797
  const primarySeries = useMemo(() => primaryEntries.map(({ series }) => series), [primaryEntries]);
4798
+ const activateSelectedBar = useCallback((index) => {
4799
+ const primaryCount = primaryEntries.length;
4800
+ if (!primaryCount) return;
4801
+ const dataPointIndex = Math.floor(index / primaryCount);
4802
+ const series = primaryEntries[index % primaryCount]?.series;
4803
+ const datum = series?.data[dataPointIndex];
4804
+ if (series && datum) onDatumActivate?.({
4805
+ datum,
4806
+ index: dataPointIndex,
4807
+ key: series.label
4808
+ });
4809
+ }, [primaryEntries, onDatumActivate]);
4810
+ const { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation({
4811
+ selectedIndex,
4812
+ setSelectedIndex,
4813
+ isNavigating,
4814
+ setIsNavigating,
4815
+ chartRef,
4816
+ totalPoints,
4817
+ onActivate: activateSelectedBar
4818
+ });
4756
4819
  const comparisonEntries = useMemo(() => {
4757
4820
  const primaryByGroup = new Map(primaryEntries.map(({ series, index }) => [series.group, {
4758
4821
  label: series.label,
@@ -4789,7 +4852,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4789
4852
  const groupPadding = useMemo(() => {
4790
4853
  const basePadding = chartOptions.barGroup.padding;
4791
4854
  if (!comparisonWidthFactor || comparisonWidthFactor <= 1) return basePadding;
4792
- const p = 1 - (1 - COMPARISON_INNER_GAP) / comparisonWidthFactor;
4855
+ const p = 1 - .9 / comparisonWidthFactor;
4793
4856
  return Math.min(Math.max(p, basePadding), MAX_GROUP_PADDING);
4794
4857
  }, [chartOptions.barGroup.padding, comparisonWidthFactor]);
4795
4858
  const { xScale, yScale } = useMemo(() => {
@@ -4927,15 +4990,17 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
4927
4990
  chartId
4928
4991
  ]);
4929
4992
  const error = validateData$2(dataSorted);
4993
+ const isDataValid = !error;
4994
+ const chartMetadata = useMemo(() => ({
4995
+ orientation,
4996
+ withPatterns
4997
+ }), [orientation, withPatterns]);
4930
4998
  useChartRegistration({
4931
4999
  chartId,
4932
5000
  legendItems,
4933
5001
  chartType: "bar",
4934
- isDataValid: !error,
4935
- metadata: useMemo(() => ({
4936
- orientation,
4937
- withPatterns
4938
- }), [orientation, withPatterns])
5002
+ isDataValid,
5003
+ metadata: chartMetadata
4939
5004
  });
4940
5005
  const prefersReducedMotion = usePrefersReducedMotion();
4941
5006
  if (error) return /* @__PURE__ */ jsx("div", {
@@ -5000,6 +5065,8 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
5000
5065
  xScale,
5001
5066
  yScale,
5002
5067
  horizontal,
5068
+ onPointerDown,
5069
+ onPointerUp,
5003
5070
  pointerEventsDataKey: "nearest",
5004
5071
  children: [
5005
5072
  !allSeriesHidden && /* @__PURE__ */ jsx(Grid, {
@@ -5155,6 +5222,25 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
5155
5222
  bottom: 0,
5156
5223
  top: 0
5157
5224
  }, ...rest }) => {
5225
+ const { getElementStyles } = useGlobalChartsContext();
5226
+ const tintedData = useMemo(() => {
5227
+ if (data.length > 1) return data;
5228
+ return data.map((series, index) => {
5229
+ if (series.options?.stroke) return series;
5230
+ const { color } = getElementStyles({
5231
+ data: series,
5232
+ index
5233
+ });
5234
+ if (!isValidHexColor(color)) return series;
5235
+ return {
5236
+ ...series,
5237
+ options: {
5238
+ ...series.options,
5239
+ stroke: lightenHexColor(color, .6)
5240
+ }
5241
+ };
5242
+ });
5243
+ }, [data, getElementStyles]);
5158
5244
  const chartOptions = useMemo(() => {
5159
5245
  const isMultiSeries = data.length > 1;
5160
5246
  const defaultYScale = {
@@ -5187,7 +5273,7 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
5187
5273
  return /* @__PURE__ */ jsx(BarChart, {
5188
5274
  orientation: "horizontal",
5189
5275
  gridVisibility: "none",
5190
- data,
5276
+ data: tintedData,
5191
5277
  width,
5192
5278
  height,
5193
5279
  margin,
@@ -5448,20 +5534,21 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
5448
5534
  })]
5449
5535
  });
5450
5536
  const isDataValid = Boolean(steps && steps.length > 0);
5537
+ const chartMetadata = useMemo(() => ({
5538
+ mainRate,
5539
+ changeIndicator,
5540
+ stepsCount: steps?.length || 0
5541
+ }), [
5542
+ mainRate,
5543
+ changeIndicator,
5544
+ steps?.length
5545
+ ]);
5451
5546
  useChartRegistration({
5452
5547
  chartId,
5453
5548
  legendItems: [],
5454
5549
  chartType: "conversion-funnel",
5455
5550
  isDataValid,
5456
- metadata: useMemo(() => ({
5457
- mainRate,
5458
- changeIndicator,
5459
- stepsCount: steps?.length || 0
5460
- }), [
5461
- mainRate,
5462
- changeIndicator,
5463
- steps?.length
5464
- ])
5551
+ metadata: chartMetadata
5465
5552
  });
5466
5553
  const prefersReducedMotion = usePrefersReducedMotion();
5467
5554
  if (!isDataValid) return /* @__PURE__ */ jsx(Stack, {
@@ -6065,7 +6152,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
6065
6152
  });
6066
6153
  const chartBackgroundHex = normalizeColorToHex(theme.backgroundColor, scopeElement, resolveCssVariable);
6067
6154
  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)));
6155
+ const cellHasLightText = (intensity) => isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) && prefersLightText(mixHexColors(primaryHex, chartBackgroundHex, 1 - (CELL_MIX_FLOOR + .85 * intensity)));
6069
6156
  const extent = useMemo(() => getValueExtent(data), [data]);
6070
6157
  const heatmapContext = useMemo(() => ({
6071
6158
  extent,
@@ -6388,7 +6475,7 @@ function paramCase(input, options) {
6388
6475
  return dotCase(input, __assign({ delimiter: "-" }, options));
6389
6476
  }
6390
6477
  //#endregion
6391
- //#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
6478
+ //#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
6392
6479
  function useUpdateEffect(effect, deps) {
6393
6480
  const mountedRef = useRef$1(false);
6394
6481
  useEffect$1(() => {
@@ -6420,10 +6507,11 @@ var StyleSheet = /*#__PURE__*/ function() {
6420
6507
  var _this = this;
6421
6508
  this._insertTag = function(tag) {
6422
6509
  var before;
6423
- if (_this.tags.length === 0) if (_this.insertionPoint) before = _this.insertionPoint.nextSibling;
6424
- else if (_this.prepend) before = _this.container.firstChild;
6425
- else before = _this.before;
6426
- else before = _this.tags[_this.tags.length - 1].nextSibling;
6510
+ if (_this.tags.length === 0) {
6511
+ if (_this.insertionPoint) before = _this.insertionPoint.nextSibling;
6512
+ else if (_this.prepend) before = _this.container.firstChild;
6513
+ else before = _this.before;
6514
+ } else before = _this.tags[_this.tags.length - 1].nextSibling;
6427
6515
  _this.container.insertBefore(tag, before);
6428
6516
  _this.tags.push(tag);
6429
6517
  };
@@ -6742,9 +6830,7 @@ function delimiter(type) {
6742
6830
  case 40:
6743
6831
  if (type === 41) delimiter(type);
6744
6832
  break;
6745
- case 92:
6746
- next();
6747
- break;
6833
+ case 92: next();
6748
6834
  }
6749
6835
  return position;
6750
6836
  }
@@ -7720,14 +7806,12 @@ function handleInterpolation(mergedProps, registered, interpolation) {
7720
7806
  return serializedStyles.styles + ";";
7721
7807
  }
7722
7808
  return createStringFromObject(mergedProps, registered, interpolation);
7723
- case "function":
7724
- if (mergedProps !== void 0) {
7725
- var previousCursor = cursor;
7726
- var result = interpolation(mergedProps);
7727
- cursor = previousCursor;
7728
- return handleInterpolation(mergedProps, registered, result);
7729
- }
7730
- break;
7809
+ case "function": if (mergedProps !== void 0) {
7810
+ var previousCursor = cursor;
7811
+ var result = interpolation(mergedProps);
7812
+ cursor = previousCursor;
7813
+ return handleInterpolation(mergedProps, registered, result);
7814
+ }
7731
7815
  }
7732
7816
  var asString = interpolation;
7733
7817
  if (registered == null) return asString;
@@ -7961,7 +8045,7 @@ _createEmotion.css;
7961
8045
  _createEmotion.sheet;
7962
8046
  _createEmotion.cache;
7963
8047
  //#endregion
7964
- //#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
8048
+ //#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
7965
8049
  var isSerializedStyles = (o) => typeof o !== "undefined" && o !== null && ["name", "styles"].every((p) => typeof o[p] !== "undefined");
7966
8050
  var useCx = () => {
7967
8051
  const cache = __unsafe_useEmotionCache();
@@ -8068,7 +8152,7 @@ function memize(fn, options) {
8068
8152
  return memoized;
8069
8153
  }
8070
8154
  //#endregion
8071
- //#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
8155
+ //#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
8072
8156
  var white = "#fff";
8073
8157
  var GRAY = {
8074
8158
  900: "#1e1e1e",
@@ -8147,7 +8231,7 @@ var COLORS = Object.freeze({
8147
8231
  ui: UI
8148
8232
  });
8149
8233
  //#endregion
8150
- //#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
8234
+ //#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
8151
8235
  var CONTROL_HEIGHT = "36px";
8152
8236
  var CONTROL_PROPS = {
8153
8237
  controlPaddingX: 12,
@@ -8252,10 +8336,10 @@ var require_es6 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8252
8336
  };
8253
8337
  }));
8254
8338
  //#endregion
8255
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.52.0/node_modules/@wordpress/warning/build-module/utils.mjs
8339
+ //#region ../../../node_modules/.pnpm/@wordpress+warning@3.53.0/node_modules/@wordpress/warning/build-module/utils.mjs
8256
8340
  var logged = /* @__PURE__ */ new Set();
8257
8341
  //#endregion
8258
- //#region ../../../node_modules/.pnpm/@wordpress+warning@3.52.0/node_modules/@wordpress/warning/build-module/index.mjs
8342
+ //#region ../../../node_modules/.pnpm/@wordpress+warning@3.53.0/node_modules/@wordpress/warning/build-module/index.mjs
8259
8343
  function isDev() {
8260
8344
  return globalThis.SCRIPT_DEBUG === true;
8261
8345
  }
@@ -8269,7 +8353,7 @@ function warning(message) {
8269
8353
  logged.add(message);
8270
8354
  }
8271
8355
  //#endregion
8272
- //#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
8356
+ //#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
8273
8357
  var import_es6 = /* @__PURE__ */ __toESM(require_es6(), 1);
8274
8358
  var ComponentsContext = createContext$1(
8275
8359
  /** @type {Record<string, any>} */
@@ -8296,18 +8380,18 @@ var BaseContextSystemProvider = ({ children, value }) => {
8296
8380
  };
8297
8381
  memo(BaseContextSystemProvider);
8298
8382
  //#endregion
8299
- //#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
8383
+ //#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
8300
8384
  var COMPONENT_NAMESPACE = "data-wp-component";
8301
8385
  var CONNECTED_NAMESPACE = "data-wp-c16t";
8302
8386
  var CONNECT_STATIC_NAMESPACE = "__contextSystemKey__";
8303
8387
  //#endregion
8304
- //#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
8388
+ //#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
8305
8389
  function getStyledClassName(namespace) {
8306
8390
  return `components-${paramCase(namespace)}`;
8307
8391
  }
8308
8392
  var getStyledClassNameFromKey = memize(getStyledClassName);
8309
8393
  //#endregion
8310
- //#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
8394
+ //#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
8311
8395
  function contextConnect(Component, namespace) {
8312
8396
  return _contextConnect(Component, namespace, { forwardsRef: true });
8313
8397
  }
@@ -8324,7 +8408,7 @@ function _contextConnect(Component, namespace, options) {
8324
8408
  });
8325
8409
  }
8326
8410
  //#endregion
8327
- //#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
8411
+ //#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
8328
8412
  function getNamespace(componentName) {
8329
8413
  return { [COMPONENT_NAMESPACE]: componentName };
8330
8414
  }
@@ -8332,7 +8416,7 @@ function getConnectedNamespace() {
8332
8416
  return { [CONNECTED_NAMESPACE]: true };
8333
8417
  }
8334
8418
  //#endregion
8335
- //#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
8419
+ //#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
8336
8420
  function useContextSystem(props, namespace) {
8337
8421
  const contextSystemProps = useComponentsContext();
8338
8422
  if (typeof namespace === "undefined") globalThis.SCRIPT_DEBUG === true && warning("useContextSystem: Please provide a namespace");
@@ -8352,7 +8436,7 @@ function useContextSystem(props, namespace) {
8352
8436
  return finalComponentProps;
8353
8437
  }
8354
8438
  //#endregion
8355
- //#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
8439
+ //#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
8356
8440
  var visuallyHidden = {
8357
8441
  border: 0,
8358
8442
  clip: "rect(1px, 1px, 1px, 1px)",
@@ -8368,7 +8452,7 @@ var visuallyHidden = {
8368
8452
  wordBreak: "normal"
8369
8453
  };
8370
8454
  //#endregion
8371
- //#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
8455
+ //#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
8372
8456
  var customAttributeRegExp = /^(data|aria|x)-/i;
8373
8457
  var eventHandlerRegExp = /^on[A-Z]/;
8374
8458
  var svgElementNames = new Set(`animate animateMotion animateTransform circle clipPath defs desc ellipse
@@ -8450,14 +8534,15 @@ function filterIntrinsicElementProps(props, element) {
8450
8534
  }
8451
8535
  function UnforwardedPolymorphicElement({ as, ...props }, ref) {
8452
8536
  const Element = as || "div";
8537
+ const forwardedProps = typeof Element === "string" ? filterIntrinsicElementProps(props, Element) : props;
8453
8538
  return /* @__PURE__ */ jsx(Element, {
8454
8539
  ref,
8455
- ...typeof Element === "string" ? filterIntrinsicElementProps(props, Element) : props
8540
+ ...forwardedProps
8456
8541
  });
8457
8542
  }
8458
8543
  var PolymorphicElement = forwardRef$1(UnforwardedPolymorphicElement);
8459
8544
  //#endregion
8460
- //#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
8545
+ //#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
8461
8546
  function UnforwardedView({ css, ...restProps }, ref) {
8462
8547
  return /* @__PURE__ */ jsx(PolymorphicElement, {
8463
8548
  ref,
@@ -8466,7 +8551,7 @@ function UnforwardedView({ css, ...restProps }, ref) {
8466
8551
  }
8467
8552
  var component_default$2 = Object.assign(forwardRef$1(UnforwardedView), { selector: ".components-view" });
8468
8553
  //#endregion
8469
- //#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
8554
+ //#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
8470
8555
  function UnconnectedVisuallyHidden(props, forwardedRef) {
8471
8556
  const { style: styleProp, ...contextProps } = useContextSystem(props, "VisuallyHidden");
8472
8557
  return /* @__PURE__ */ jsx(component_default$2, {
@@ -8481,7 +8566,7 @@ function UnconnectedVisuallyHidden(props, forwardedRef) {
8481
8566
  }
8482
8567
  var component_default$1 = contextConnect(UnconnectedVisuallyHidden, "VisuallyHidden");
8483
8568
  //#endregion
8484
- //#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
8569
+ //#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
8485
8570
  var breakpoints = [
8486
8571
  "40em",
8487
8572
  "52em",
@@ -8515,7 +8600,7 @@ function useResponsiveValue(values, options = {}) {
8515
8600
  return array[index >= array.length ? array.length - 1 : index];
8516
8601
  }
8517
8602
  //#endregion
8518
- //#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
8603
+ //#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
8519
8604
  var ALIGNMENTS = {
8520
8605
  bottom: {
8521
8606
  alignItems: "flex-end",
@@ -8563,7 +8648,7 @@ function getAlignmentProps(alignment) {
8563
8648
  return alignment ? ALIGNMENTS[alignment] : {};
8564
8649
  }
8565
8650
  //#endregion
8566
- //#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
8651
+ //#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
8567
8652
  function useGrid(props) {
8568
8653
  const { align, alignment, className, columnGap, columns = 2, gap = 3, isInline = false, justify, rowGap, rows, templateColumns, templateRows, ...otherProps } = useContextSystem(props, "Grid");
8569
8654
  const column = useResponsiveValue(Array.isArray(columns) ? columns : [columns]);
@@ -8605,10 +8690,11 @@ function useGrid(props) {
8605
8690
  };
8606
8691
  }
8607
8692
  //#endregion
8608
- //#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
8693
+ //#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
8609
8694
  function UnconnectedGrid(props, forwardedRef) {
8695
+ const gridProps = useGrid(props);
8610
8696
  return /* @__PURE__ */ jsx(component_default$2, {
8611
- ...useGrid(props),
8697
+ ...gridProps,
8612
8698
  ref: forwardedRef
8613
8699
  });
8614
8700
  }
@@ -8920,15 +9006,17 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
8920
9006
  withComparison,
8921
9007
  withOverlayLabel
8922
9008
  ]);
9009
+ const isDataValid = Boolean(data && data.length > 0);
9010
+ const chartMetadata = useMemo(() => ({
9011
+ withComparison,
9012
+ withOverlayLabel
9013
+ }), [withComparison, withOverlayLabel]);
8923
9014
  useChartRegistration({
8924
9015
  chartId,
8925
9016
  legendItems,
8926
9017
  chartType: "leaderboard",
8927
- isDataValid: Boolean(data && data.length > 0),
8928
- metadata: useMemo(() => ({
8929
- withComparison,
8930
- withOverlayLabel
8931
- }), [withComparison, withOverlayLabel])
9018
+ isDataValid,
9019
+ metadata: chartMetadata
8932
9020
  });
8933
9021
  const prefersReducedMotion = usePrefersReducedMotion();
8934
9022
  const { contentRef, fittedCount, isMeasurable } = useFittedRowCount(fitRows && !allSeriesHidden, data?.length ?? 0, data);
@@ -9183,8 +9271,9 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
9183
9271
  hideTooltip();
9184
9272
  }, [withTooltips, hideTooltip]);
9185
9273
  const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
9274
+ const dataWithPercentages = useDataWithPercentages(data);
9186
9275
  const { visibleData, allSegmentsHidden, legendData } = useLegendVisibilityData({
9187
- data: useDataWithPercentages(data),
9276
+ data: dataWithPercentages,
9188
9277
  chartId,
9189
9278
  isSeriesVisible
9190
9279
  });
@@ -9194,20 +9283,21 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
9194
9283
  }), [legendValueDisplay]));
9195
9284
  const { isValid, message } = validateData$1(data);
9196
9285
  const { svgChildren, htmlChildren, legendChildren, otherChildren } = useChartChildren(children, "PieChart");
9286
+ const chartMetadata = useMemo(() => ({
9287
+ thickness,
9288
+ gapScale,
9289
+ cornerScale
9290
+ }), [
9291
+ thickness,
9292
+ gapScale,
9293
+ cornerScale
9294
+ ]);
9197
9295
  useChartRegistration({
9198
9296
  chartId,
9199
9297
  legendItems,
9200
9298
  chartType: "pie",
9201
9299
  isDataValid: isValid,
9202
- metadata: useMemo(() => ({
9203
- thickness,
9204
- gapScale,
9205
- cornerScale
9206
- }), [
9207
- thickness,
9208
- gapScale,
9209
- cornerScale
9210
- ])
9300
+ metadata: chartMetadata
9211
9301
  });
9212
9302
  const prefersReducedMotion = usePrefersReducedMotion();
9213
9303
  if (!isValid) return /* @__PURE__ */ jsx("div", {
@@ -9336,14 +9426,12 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
9336
9426
  }
9337
9427
  const svgLabelSmall = providerTheme.svgLabelSmall;
9338
9428
  const fontSize = resolveFontSize(svgLabelSmall?.fontSize) ?? 12;
9339
- const estimatedTextWidth = getStringWidth$1(arc.data.label, {
9429
+ const backgroundWidth = getStringWidth$1(arc.data.label, {
9340
9430
  fontSize,
9341
9431
  fontFamily: svgLabelSmall?.fontFamily,
9342
9432
  fontWeight: svgLabelSmall?.fontWeight
9343
- });
9344
- const labelPadding = 6;
9345
- const backgroundWidth = estimatedTextWidth + labelPadding * 2;
9346
- const backgroundHeight = fontSize + labelPadding * 2;
9433
+ }) + 12;
9434
+ const backgroundHeight = fontSize + 12;
9347
9435
  return /* @__PURE__ */ jsxs("g", {
9348
9436
  ...groupProps,
9349
9437
  children: [/* @__PURE__ */ jsx("path", { ...pathProps }), showLabels && hasSpaceForLabel && /* @__PURE__ */ jsxs("g", { children: [providerTheme.labelBackgroundColor && /* @__PURE__ */ jsx("rect", {
@@ -9475,8 +9563,9 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
9475
9563
  }, [handleMouseMove]);
9476
9564
  const { isValid, message } = validateData(data);
9477
9565
  const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
9566
+ const dataWithPercentages = useDataWithPercentages(data);
9478
9567
  const { visibleData, allSegmentsHidden, legendData } = useLegendVisibilityData({
9479
- data: useDataWithPercentages(data),
9568
+ data: dataWithPercentages,
9480
9569
  chartId,
9481
9570
  isSeriesVisible
9482
9571
  });
@@ -9493,15 +9582,16 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
9493
9582
  legendValueDisplay
9494
9583
  }), [legendValueDisplay]));
9495
9584
  const { svgChildren, htmlChildren, legendChildren, otherChildren } = useChartChildren(children, "PieSemiCircleChart");
9585
+ const chartMetadata = useMemo(() => ({
9586
+ thickness,
9587
+ clockwise
9588
+ }), [thickness, clockwise]);
9496
9589
  useChartRegistration({
9497
9590
  chartId,
9498
9591
  legendItems,
9499
9592
  chartType: "pie-semi-circle",
9500
9593
  isDataValid: isValid,
9501
- metadata: useMemo(() => ({
9502
- thickness,
9503
- clockwise
9504
- }), [thickness, clockwise])
9594
+ metadata: chartMetadata
9505
9595
  });
9506
9596
  const prefersReducedMotion = usePrefersReducedMotion();
9507
9597
  const effectiveWidth = propWidth || DEFAULT_WIDTH$1;
@@ -9692,6 +9782,7 @@ const transformToSeriesData = (data, color, strokeWidth) => {
9692
9782
  };
9693
9783
  const SparklineComponent = forwardRef(({ data, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT, color, strokeWidth: strokeWidthProp, withGradientFill = true, gradient, className, chartId, margin: marginProp, animation }, ref) => {
9694
9784
  const theme = useGlobalChartsTheme();
9785
+ const chartsContext = useContext(GlobalChartsContext);
9695
9786
  const themeStrokeWidth = theme.sparkline?.strokeWidth ?? 1.5;
9696
9787
  const strokeWidth = strokeWidthProp ?? themeStrokeWidth;
9697
9788
  const seriesData = useMemo(() => {
@@ -9745,7 +9836,7 @@ const SparklineComponent = forwardRef(({ data, width = DEFAULT_WIDTH, height = D
9745
9836
  if (data.length === 1) {
9746
9837
  const cx = width / 2;
9747
9838
  const cy = height / 2;
9748
- const resolvedColor = color || "#000000";
9839
+ const resolvedColor = color || chartsContext?.getElementStyles({ index: 0 }).color || "#000000";
9749
9840
  return /* @__PURE__ */ jsx("div", {
9750
9841
  ref,
9751
9842
  className: clsx("sparkline", sparkline_module_default.sparkline, sparkline_module_default["sparkline--single-point"], className),
@@ -9848,8 +9939,9 @@ const Icon$1 = ({ direction }) => {
9848
9939
  */
9849
9940
  function TrendIndicator({ direction, value, className, style, showIcon = true }) {
9850
9941
  const ariaLabel = `${DIRECTION_LABELS[direction]}: ${value}`;
9942
+ const standaloneScopeClass = useStandaloneScopeClass();
9851
9943
  return /* @__PURE__ */ jsxs("span", {
9852
- className: clsx(useStandaloneScopeClass(), trend_indicator_module_default["trend-indicator"], trend_indicator_module_default[`trend-indicator--${direction}`], className),
9944
+ className: clsx(standaloneScopeClass, trend_indicator_module_default["trend-indicator"], trend_indicator_module_default[`trend-indicator--${direction}`], className),
9853
9945
  style,
9854
9946
  "aria-label": ariaLabel,
9855
9947
  children: [showIcon && /* @__PURE__ */ jsx(Icon$1, { direction }), /* @__PURE__ */ jsx("span", {