@automattic/charts 4.6.0 → 4.7.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 (57) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/TOKENS.md +12 -10
  3. package/dist/index.cjs +244 -145
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +33 -20
  6. package/dist/index.d.cts +10 -10
  7. package/dist/index.d.ts +10 -10
  8. package/dist/index.js +245 -146
  9. package/dist/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +0 -10
  12. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +4 -2
  13. package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +11 -1
  14. package/src/charts/conversion-funnel-chart/types.ts +3 -0
  15. package/src/charts/heatmap-chart/heatmap-chart.module.scss +10 -3
  16. package/src/charts/heatmap-chart/heatmap-chart.tsx +54 -37
  17. package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +129 -25
  18. package/src/charts/heatmap-chart/types.ts +2 -6
  19. package/src/charts/line-chart/crosshair-style-types.fixture.ts +23 -0
  20. package/src/charts/line-chart/line-chart.module.scss +0 -5
  21. package/src/charts/line-chart/line-chart.tsx +8 -40
  22. package/src/charts/line-chart/test/line-chart.test.tsx +19 -47
  23. package/src/charts/pie-chart/pie-chart.module.scss +9 -0
  24. package/src/charts/pie-chart/pie-chart.tsx +22 -76
  25. package/src/charts/pie-chart/test/pie-chart.test.tsx +21 -8
  26. package/src/charts/private/chart-composition/chart-html.tsx +1 -1
  27. package/src/charts/private/chart-composition/chart-svg.tsx +1 -1
  28. package/src/charts/private/label-text-color.ts +116 -0
  29. package/src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx +2 -0
  30. package/src/charts/private/svg-empty-state/svg-empty-state.tsx +1 -1
  31. package/src/charts/private/test/label-text-color.test.ts +191 -0
  32. package/src/charts/private/with-responsive/test/with-responsive.test.tsx +1 -0
  33. package/src/charts/private/with-responsive/with-responsive.tsx +2 -5
  34. package/src/components/tooltip/accessible-tooltip.tsx +1 -1
  35. package/src/components/tooltip/base-tooltip.module.scss +12 -8
  36. package/src/components/tooltip/base-tooltip.tsx +11 -9
  37. package/src/components/tooltip/private/bounded-tooltip.tsx +27 -8
  38. package/src/components/tooltip/private/tooltip-theme.tsx +37 -0
  39. package/src/components/tooltip/test/bounded-tooltip.test.tsx +82 -1
  40. package/src/components/tooltip/test/tool-tip.test.tsx +5 -0
  41. package/src/components/tooltip/test/tooltip-theme.test.tsx +61 -0
  42. package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +41 -28
  43. package/src/components/tooltip/xy-chart-tooltip.tsx +29 -29
  44. package/src/components/trend-indicator/trend-indicator.tsx +1 -0
  45. package/src/hooks/index.ts +1 -0
  46. package/src/hooks/test/use-xychart-theme.test.tsx +3 -3
  47. package/src/hooks/use-isomorphic-layout-effect.ts +5 -0
  48. package/src/hooks/use-xychart-theme.ts +4 -12
  49. package/src/providers/chart-context/hooks/use-default-hidden-series.ts +2 -4
  50. package/src/providers/chart-context/private/perceptual-color.ts +45 -4
  51. package/src/providers/chart-context/test/perceptual-color.test.ts +31 -0
  52. package/src/styles/chart-scope-class.ts +5 -0
  53. package/src/styles/chart-scope.scss +9 -6
  54. package/src/styles/test/chart-scope.test.ts +3 -3
  55. package/src/utils/color-utils.ts +2 -1
  56. package/src/visx/types.ts +1 -1
  57. package/src/charts/line-chart/test/crosshair-style-types.test.ts +0 -31
package/dist/index.css CHANGED
@@ -1,4 +1,4 @@
1
- :where(.a8c-charts-scope) {
1
+ :where(.a8c-charts-scope, .a8c-charts-tooltip-scope) {
2
2
  --a8c-charts-color-series-1: var(--wp-admin-theme-color, var(--wpds-color-foreground-interactive-brand, var(--wp-admin-theme-color, #3858e9)));
3
3
  --a8c-charts-color-grid: var(--wpds-color-stroke-surface-neutral, #dbdbdb);
4
4
  --a8c-charts-color-axis-x: var(--wpds-color-stroke-surface-neutral, #dbdbdb);
@@ -18,7 +18,7 @@
18
18
  --a8c-charts-color-surface: var(--wpds-color-background-surface-neutral-strong, #fff);
19
19
  --a8c-charts-color-surface-secondary: var(--wpds-color-background-surface-neutral-weak, #f4f4f4);
20
20
  --a8c-charts-color-track: var(--wpds-color-background-track-neutral-weak, #f0f0f0);
21
- --a8c-charts-color-tooltip-surface: #000000d9;
21
+ --a8c-charts-color-tooltip-surface: #1e1e1e;
22
22
  --a8c-charts-color-zoom-selection: var(--wpds-color-background-interactive-brand-strong, var(--wp-admin-theme-color, #3858e9));
23
23
  --a8c-charts-color-zoom-selection-stroke: var(--wpds-color-stroke-interactive-brand, var(--wp-admin-theme-color, #3858e9));
24
24
  --a8c-charts-elevation-xs: 0 1px 1px 0 #00000008,
@@ -39,7 +39,7 @@
39
39
  }
40
40
 
41
41
  @media (forced-colors: active) {
42
- :where(.a8c-charts-scope) {
42
+ :where(.a8c-charts-scope, .a8c-charts-tooltip-scope) {
43
43
  --a8c-charts-color-label-axis: CanvasText;
44
44
  --a8c-charts-color-grid: GrayText;
45
45
  --a8c-charts-color-axis-x: GrayText;
@@ -105,13 +105,21 @@
105
105
  flex-shrink: 0;
106
106
  }
107
107
  .a8ccharts--zY0xG-surface, .a8ccharts--zY0xG-tooltip {
108
- padding: var(--wpds-dimension-padding-sm, 8px);
109
- background-color: var(--a8c-charts-color-tooltip-surface, #000000d9);
110
- color: #fff;
108
+ padding: var(--wpds-dimension-padding-xs, 4px) var(--wpds-dimension-padding-sm, 8px);
109
+ background-color: var(--a8c-charts-color-surface);
110
+ color: var(--a8c-charts-color-label);
111
111
  border-radius: var(--wpds-border-radius-md, 4px);
112
- font-size: var(--wpds-typography-font-size-md, 13px);
112
+ font-family: var(--wpds-typography-font-family-body, -apple-system, system-ui, "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif);
113
+ font-size: var(--wpds-typography-font-size-sm, 12px);
113
114
  box-shadow: var(--a8c-charts-elevation-sm, 0 1px 2px 0 #0000000d, 0 2px 3px 0 #0000000a, 0 6px 6px 0 #00000008, 0 8px 8px 0 #00000005);
114
115
  pointer-events: none;
116
+ line-height: 1.4;
117
+ }
118
+
119
+ @media (forced-colors: active) {
120
+ .a8ccharts--zY0xG-surface, .a8ccharts--zY0xG-tooltip {
121
+ border: var(--wpds-border-width-xs, 1px) solid CanvasText;
122
+ }
115
123
  }
116
124
 
117
125
  .a8ccharts--zY0xG-tooltip {
@@ -191,7 +199,7 @@
191
199
  overflow: visible;
192
200
  }
193
201
 
194
- .a8ccharts-inuQka-line-chart__tooltip, .a8ccharts-inuQka-line-chart__annotation-label-popover {
202
+ .a8ccharts-inuQka-line-chart__annotation-label-popover {
195
203
  background: var(--a8c-charts-color-surface);
196
204
  color: var(--a8c-charts-color-label);
197
205
  padding: var(--wpds-dimension-padding-sm, 8px);
@@ -202,10 +210,6 @@
202
210
  padding-bottom: var(--wpds-dimension-padding-md, 12px);
203
211
  }
204
212
 
205
- .a8ccharts-inuQka-line-chart__tooltip-row {
206
- padding: var(--wpds-dimension-padding-xs, 4px) 0;
207
- }
208
-
209
213
  .a8ccharts-inuQka-line-chart__tooltip-label {
210
214
  font-weight: var(--wpds-typography-font-weight-emphasis, 600);
211
215
  padding-right: var(--wpds-dimension-padding-lg, 16px);
@@ -445,13 +449,6 @@
445
449
  }
446
450
  }
447
451
 
448
- .a8ccharts-mGEVca-tooltip-wrapper {
449
- background: var(--a8c-charts-color-surface);
450
- border-radius: var(--wpds-border-radius-md, 4px) !important;
451
- padding: var(--wpds-dimension-padding-md, 12px) !important;
452
- box-shadow: var(--a8c-charts-elevation-sm, 0 1px 2px 0 #0000000d, 0 2px 3px 0 #0000000a, 0 6px 6px 0 #00000008, 0 8px 8px 0 #00000005) !important;
453
- }
454
-
455
452
  .a8ccharts-mGEVca-tooltip-title {
456
453
  color: var(--a8c-charts-color-label);
457
454
  font-size: var(--wpds-typography-font-size-sm, 12px);
@@ -618,10 +615,18 @@
618
615
  font-size: var(--wpds-typography-font-size-md, 13px);
619
616
  }
620
617
 
621
- .a8ccharts-O3YMOW-heatmap-chart__cell--strong .a8ccharts-O3YMOW-heatmap-chart__cell-value {
618
+ .a8ccharts-O3YMOW-heatmap-chart__cell-value--inverse {
622
619
  color: var(--a8c-charts-color-label-inverse);
623
620
  }
624
621
 
622
+ .a8ccharts-O3YMOW-heatmap-chart__cell-value--black {
623
+ color: #000;
624
+ }
625
+
626
+ .a8ccharts-O3YMOW-heatmap-chart__cell-value--white {
627
+ color: #fff;
628
+ }
629
+
625
630
  .a8ccharts-O3YMOW-heatmap-chart__legend-label {
626
631
  color: var(--a8c-charts-color-label);
627
632
  }
@@ -854,6 +859,14 @@
854
859
  .a8ccharts-gnszbG-pie-chart__label-text--on-light {
855
860
  fill: var(--a8c-charts-color-label, #1e1e1e);
856
861
  }
862
+
863
+ .a8ccharts-gnszbG-pie-chart__label-text--black {
864
+ fill: #000;
865
+ }
866
+
867
+ .a8ccharts-gnszbG-pie-chart__label-text--white {
868
+ fill: #fff;
869
+ }
857
870
  .a8ccharts-YtTOxW-pie-semi-circle-chart__plot {
858
871
  position: relative;
859
872
  }
package/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@ import { AxisRendererProps, AxisScale, Orientation, TickFormatter } from "@visx/
4
4
  import { PickD3Scale, ScaleInput, ScaleType } from "@visx/scale";
5
5
  import { TextProps } from "@visx/text";
6
6
  import { EventHandlerParams, EventHandlerParams as EventHandlerParams$1, GlyphProps, GridStyles, GridStyles as GridStyles$1, LineStyles, LineStyles as LineStyles$1, TooltipContextType } from "@visx/xychart";
7
- import { CSSProperties, ComponentClass, ComponentProps, ComponentType, FC, MouseEvent, PointerEvent, PropsWithChildren, ReactElement, ReactNode, SVGProps } from "react";
7
+ import { CSSProperties, ComponentClass, ComponentProps, ComponentType, FC, JSX, MouseEvent, PointerEvent, PropsWithChildren, ReactElement, ReactNode, SVGProps } from "react";
8
8
  import { TooltipProps as TooltipProps$1, UseTooltipPortalOptions } from "@visx/tooltip";
9
9
  import { PieProvidedProps } from "@visx/shape";
10
10
  //#region src/types.d.ts
@@ -829,7 +829,7 @@ type XyChartTooltipProps<Datum extends object> = {
829
829
  tooltipPlacement?: TooltipPlacement;
830
830
  /** Override the tooltip top anchor in SVG coordinates, including negative offsets. */
831
831
  tooltipAnchorTop?: number;
832
- /** Merge overrides with the default box styles; use `unstyled` to strip the box styling. */
832
+ /** Inline overrides on the tooltip surface; `unstyled` drops both. */
833
833
  style?: TooltipProps$1['style'];
834
834
  snapTooltipToDatumX?: boolean;
835
835
  snapTooltipToDatumY?: boolean;
@@ -1209,6 +1209,7 @@ interface TooltipRenderProps {
1209
1209
  index: number;
1210
1210
  top: number;
1211
1211
  left: number;
1212
+ /** @deprecated The tooltip box draws the package surface; this is no longer set. */
1212
1213
  className?: string;
1213
1214
  }
1214
1215
  /**
@@ -1235,6 +1236,8 @@ interface ConversionFunnelChartProps extends Pick<BaseChartProps, 'className' |
1235
1236
  renderMainMetric?: (props: MainMetricRenderProps) => React.ReactNode;
1236
1237
  /** Custom render function for tooltip content */
1237
1238
  renderTooltip?: (props: TooltipRenderProps) => React.ReactNode;
1239
+ /** Inline styles merged over the tooltip box defaults. */
1240
+ tooltipStyle?: React.CSSProperties;
1238
1241
  }
1239
1242
  //#endregion
1240
1243
  //#region src/charts/conversion-funnel-chart/conversion-funnel-chart.d.ts
@@ -1424,13 +1427,9 @@ interface HeatmapChartProps extends Omit<BaseChartProps<HeatmapColumn[]>, 'showL
1424
1427
  */
1425
1428
  primaryColor?: string;
1426
1429
  renderTooltip?: (data: HeatmapTooltipData) => ReactNode;
1427
- /**
1428
- * The tooltip box: `light` is the plain white box, `dark` the package's
1429
- * tooltip surface, themed through `--a8c-charts-color-tooltip-surface`.
1430
- * Default `light`.
1431
- */
1430
+ /** @deprecated Every tooltip draws on the package tooltip surface; this prop has no effect. */
1432
1431
  tooltipVariant?: 'light' | 'dark';
1433
- /** Inline styles merged onto the tooltip box, over the variant's own. */
1432
+ /** Inline styles merged onto the tooltip box, over the surface's own. */
1434
1433
  tooltipStyle?: CSSProperties;
1435
1434
  children?: ReactNode;
1436
1435
  }
@@ -1788,7 +1787,8 @@ declare const relativeLuminance: (hex: string) => number;
1788
1787
  * Whether light text reads better than dark text on the given background, using the W3C
1789
1788
  * luminance threshold (0.179) that maximizes contrast against black vs white.
1790
1789
  *
1791
- * @param backgroundHex - Hex background color
1790
+ * @deprecated Assumes black and white text, so it ignores label role overrides and cannot guarantee AA; charts no longer use it, and it will be removed in a future major version.
1791
+ * @param backgroundHex - Hex background color
1792
1792
  * @return true if light text should be used; false (dark text) for malformed colors
1793
1793
  */
1794
1794
  declare const prefersLightText: (backgroundHex: string) => boolean;
@@ -2232,7 +2232,7 @@ type TrendIndicatorProps = {
2232
2232
  * @param {TrendIndicatorProps} props - Component props
2233
2233
  * @return {JSX.Element} The rendered trend indicator
2234
2234
  */
2235
- declare function TrendIndicator({ direction, value, className, style, showIcon }: TrendIndicatorProps): import("react").JSX.Element;
2235
+ declare function TrendIndicator({ direction, value, className, style, showIcon }: TrendIndicatorProps): JSX.Element;
2236
2236
  //#endregion
2237
2237
  //#region src/providers/chart-context/types.d.ts
2238
2238
  interface ChartRegistration {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EventHandlerParams, EventHandlerParams as EventHandlerParams$1, GlyphProps, GridStyles, GridStyles as GridStyles$1, LineStyles, LineStyles as LineStyles$1, TooltipContextType } from "@visx/xychart";
2
- import { CSSProperties, ComponentClass, ComponentProps, ComponentType, FC, MouseEvent, PointerEvent, PropsWithChildren, ReactElement, ReactNode, SVGProps } from "react";
2
+ import { CSSProperties, ComponentClass, ComponentProps, ComponentType, FC, JSX, MouseEvent, PointerEvent, PropsWithChildren, ReactElement, ReactNode, SVGProps } from "react";
3
3
  import { TextProps } from "@visx/text";
4
4
  import { TooltipProps as TooltipProps$1, UseTooltipPortalOptions } from "@visx/tooltip";
5
5
  import { PickD3Scale, ScaleInput, ScaleType } from "@visx/scale";
@@ -829,7 +829,7 @@ type XyChartTooltipProps<Datum extends object> = {
829
829
  tooltipPlacement?: TooltipPlacement;
830
830
  /** Override the tooltip top anchor in SVG coordinates, including negative offsets. */
831
831
  tooltipAnchorTop?: number;
832
- /** Merge overrides with the default box styles; use `unstyled` to strip the box styling. */
832
+ /** Inline overrides on the tooltip surface; `unstyled` drops both. */
833
833
  style?: TooltipProps$1['style'];
834
834
  snapTooltipToDatumX?: boolean;
835
835
  snapTooltipToDatumY?: boolean;
@@ -1209,6 +1209,7 @@ interface TooltipRenderProps {
1209
1209
  index: number;
1210
1210
  top: number;
1211
1211
  left: number;
1212
+ /** @deprecated The tooltip box draws the package surface; this is no longer set. */
1212
1213
  className?: string;
1213
1214
  }
1214
1215
  /**
@@ -1235,6 +1236,8 @@ interface ConversionFunnelChartProps extends Pick<BaseChartProps, 'className' |
1235
1236
  renderMainMetric?: (props: MainMetricRenderProps) => React.ReactNode;
1236
1237
  /** Custom render function for tooltip content */
1237
1238
  renderTooltip?: (props: TooltipRenderProps) => React.ReactNode;
1239
+ /** Inline styles merged over the tooltip box defaults. */
1240
+ tooltipStyle?: React.CSSProperties;
1238
1241
  }
1239
1242
  //#endregion
1240
1243
  //#region src/charts/conversion-funnel-chart/conversion-funnel-chart.d.ts
@@ -1424,13 +1427,9 @@ interface HeatmapChartProps extends Omit<BaseChartProps<HeatmapColumn[]>, 'showL
1424
1427
  */
1425
1428
  primaryColor?: string;
1426
1429
  renderTooltip?: (data: HeatmapTooltipData) => ReactNode;
1427
- /**
1428
- * The tooltip box: `light` is the plain white box, `dark` the package's
1429
- * tooltip surface, themed through `--a8c-charts-color-tooltip-surface`.
1430
- * Default `light`.
1431
- */
1430
+ /** @deprecated Every tooltip draws on the package tooltip surface; this prop has no effect. */
1432
1431
  tooltipVariant?: 'light' | 'dark';
1433
- /** Inline styles merged onto the tooltip box, over the variant's own. */
1432
+ /** Inline styles merged onto the tooltip box, over the surface's own. */
1434
1433
  tooltipStyle?: CSSProperties;
1435
1434
  children?: ReactNode;
1436
1435
  }
@@ -1788,7 +1787,8 @@ declare const relativeLuminance: (hex: string) => number;
1788
1787
  * Whether light text reads better than dark text on the given background, using the W3C
1789
1788
  * luminance threshold (0.179) that maximizes contrast against black vs white.
1790
1789
  *
1791
- * @param backgroundHex - Hex background color
1790
+ * @deprecated Assumes black and white text, so it ignores label role overrides and cannot guarantee AA; charts no longer use it, and it will be removed in a future major version.
1791
+ * @param backgroundHex - Hex background color
1792
1792
  * @return true if light text should be used; false (dark text) for malformed colors
1793
1793
  */
1794
1794
  declare const prefersLightText: (backgroundHex: string) => boolean;
@@ -2232,7 +2232,7 @@ type TrendIndicatorProps = {
2232
2232
  * @param {TrendIndicatorProps} props - Component props
2233
2233
  * @return {JSX.Element} The rendered trend indicator
2234
2234
  */
2235
- declare function TrendIndicator({ direction, value, className, style, showIcon }: TrendIndicatorProps): import("react").JSX.Element;
2235
+ declare function TrendIndicator({ direction, value, className, style, showIcon }: TrendIndicatorProps): JSX.Element;
2236
2236
  //#endregion
2237
2237
  //#region src/providers/chart-context/types.d.ts
2238
2238
  interface ChartRegistration {