@automattic/charts 0.56.7 → 0.58.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.
- package/AGENTS.md +28 -98
- package/CHANGELOG.md +30 -0
- package/dist/charts/bar-chart/index.cjs +7 -6
- package/dist/charts/bar-chart/index.cjs.map +1 -1
- package/dist/charts/bar-chart/index.css +12 -24
- package/dist/charts/bar-chart/index.css.map +1 -1
- package/dist/charts/bar-chart/index.d.cts +3 -4
- package/dist/charts/bar-chart/index.d.ts +3 -4
- package/dist/charts/bar-chart/index.js +6 -5
- package/dist/charts/bar-list-chart/index.cjs +8 -7
- package/dist/charts/bar-list-chart/index.cjs.map +1 -1
- package/dist/charts/bar-list-chart/index.css +12 -24
- package/dist/charts/bar-list-chart/index.css.map +1 -1
- package/dist/charts/bar-list-chart/index.d.cts +3 -3
- package/dist/charts/bar-list-chart/index.d.ts +3 -3
- package/dist/charts/bar-list-chart/index.js +7 -6
- package/dist/charts/conversion-funnel-chart/index.cjs +5 -6
- package/dist/charts/conversion-funnel-chart/index.cjs.map +1 -1
- package/dist/charts/conversion-funnel-chart/index.css +0 -94
- package/dist/charts/conversion-funnel-chart/index.css.map +1 -1
- package/dist/charts/conversion-funnel-chart/index.d.cts +1 -1
- package/dist/charts/conversion-funnel-chart/index.d.ts +1 -1
- package/dist/charts/conversion-funnel-chart/index.js +4 -5
- package/dist/charts/geo-chart/index.cjs +4 -4
- package/dist/charts/geo-chart/index.css +0 -94
- package/dist/charts/geo-chart/index.css.map +1 -1
- package/dist/charts/geo-chart/index.d.cts +1 -1
- package/dist/charts/geo-chart/index.d.ts +1 -1
- package/dist/charts/geo-chart/index.js +3 -3
- package/dist/charts/leaderboard-chart/index.cjs +7 -6
- package/dist/charts/leaderboard-chart/index.cjs.map +1 -1
- package/dist/charts/leaderboard-chart/index.css +20 -33
- package/dist/charts/leaderboard-chart/index.css.map +1 -1
- package/dist/charts/leaderboard-chart/index.d.cts +3 -3
- package/dist/charts/leaderboard-chart/index.d.ts +3 -3
- package/dist/charts/leaderboard-chart/index.js +6 -5
- package/dist/charts/line-chart/index.cjs +7 -6
- package/dist/charts/line-chart/index.cjs.map +1 -1
- package/dist/charts/line-chart/index.css +12 -24
- package/dist/charts/line-chart/index.css.map +1 -1
- package/dist/charts/line-chart/index.d.cts +3 -4
- package/dist/charts/line-chart/index.d.ts +3 -4
- package/dist/charts/line-chart/index.js +6 -5
- package/dist/charts/pie-chart/index.cjs +7 -7
- package/dist/charts/pie-chart/index.css +12 -24
- package/dist/charts/pie-chart/index.css.map +1 -1
- package/dist/charts/pie-chart/index.d.cts +7 -13
- package/dist/charts/pie-chart/index.d.ts +7 -13
- package/dist/charts/pie-chart/index.js +6 -6
- package/dist/charts/pie-semi-circle-chart/index.cjs +7 -7
- package/dist/charts/pie-semi-circle-chart/index.css +12 -24
- package/dist/charts/pie-semi-circle-chart/index.css.map +1 -1
- package/dist/charts/pie-semi-circle-chart/index.d.cts +7 -13
- package/dist/charts/pie-semi-circle-chart/index.d.ts +7 -13
- package/dist/charts/pie-semi-circle-chart/index.js +6 -6
- package/dist/charts/sparkline/index.cjs +8 -7
- package/dist/charts/sparkline/index.cjs.map +1 -1
- package/dist/charts/sparkline/index.css +12 -24
- package/dist/charts/sparkline/index.css.map +1 -1
- package/dist/charts/sparkline/index.js +7 -6
- package/dist/{chunk-RFSHE3HL.js → chunk-2I67QUIV.js} +84 -431
- package/dist/chunk-2I67QUIV.js.map +1 -0
- package/dist/{chunk-OMS5QIJN.js → chunk-2ICEEQOC.js} +31 -25
- package/dist/chunk-2ICEEQOC.js.map +1 -0
- package/dist/{chunk-GWBS65VC.js → chunk-4B7BL2DD.js} +3 -3
- package/dist/{chunk-7FDQGBY7.js → chunk-4OXMTKAL.js} +24 -24
- package/dist/chunk-4OXMTKAL.js.map +1 -0
- package/dist/{chunk-SSFFCBCF.js → chunk-B6NLZFRW.js} +32 -26
- package/dist/chunk-B6NLZFRW.js.map +1 -0
- package/dist/{chunk-3EXJP67N.cjs → chunk-BBAUQOW6.cjs} +9 -9
- package/dist/{chunk-3EXJP67N.cjs.map → chunk-BBAUQOW6.cjs.map} +1 -1
- package/dist/{chunk-NQJE2CC7.cjs → chunk-CMMHCTBX.cjs} +45 -45
- package/dist/chunk-CMMHCTBX.cjs.map +1 -0
- package/dist/{chunk-O2JIANHK.cjs → chunk-CPPXJATQ.cjs} +51 -45
- package/dist/chunk-CPPXJATQ.cjs.map +1 -0
- package/dist/{chunk-MDRCAGKZ.js → chunk-DKU775VC.js} +3 -3
- package/dist/{chunk-BXFD7JIG.cjs → chunk-GRA7Y2ZG.cjs} +46 -46
- package/dist/chunk-GRA7Y2ZG.cjs.map +1 -0
- package/dist/{chunk-TE63Y5PX.js → chunk-JJIMABHT.js} +10 -3
- package/dist/chunk-JJIMABHT.js.map +1 -0
- package/dist/{chunk-KHQPN77E.js → chunk-KJHWXOCZ.js} +4 -4
- package/dist/{chunk-6CCZL2JJ.js → chunk-KRWGSOJ2.js} +30 -2
- package/dist/chunk-KRWGSOJ2.js.map +1 -0
- package/dist/{chunk-VPAEBI2F.js → chunk-LTFH7SEG.js} +24 -24
- package/dist/chunk-LTFH7SEG.js.map +1 -0
- package/dist/{chunk-E62LCBGD.js → chunk-MUNOKLLE.js} +3 -3
- package/dist/{chunk-ZVGEDXDP.cjs → chunk-MXGLYWVP.cjs} +10 -3
- package/dist/chunk-MXGLYWVP.cjs.map +1 -0
- package/dist/{chunk-55ZCOYDF.cjs → chunk-OYC34VTO.cjs} +252 -827
- package/dist/chunk-OYC34VTO.cjs.map +1 -0
- package/dist/{chunk-CAFJRZPZ.cjs → chunk-PQL5I3F6.cjs} +17 -17
- package/dist/{chunk-CAFJRZPZ.cjs.map → chunk-PQL5I3F6.cjs.map} +1 -1
- package/dist/{chunk-UFRBUT2D.cjs → chunk-REZTQ4PH.cjs} +87 -24
- package/dist/chunk-REZTQ4PH.cjs.map +1 -0
- package/dist/{chunk-RCY6XLGU.cjs → chunk-TZRUHQOH.cjs} +36 -8
- package/dist/chunk-TZRUHQOH.cjs.map +1 -0
- package/dist/{chunk-XD2HV7M5.js → chunk-UTYVIOWZ.js} +226 -801
- package/dist/chunk-UTYVIOWZ.js.map +1 -0
- package/dist/{chunk-YAXY5L7I.cjs → chunk-W2LDIX26.cjs} +5 -5
- package/dist/{chunk-YAXY5L7I.cjs.map → chunk-W2LDIX26.cjs.map} +1 -1
- package/dist/{chunk-K6TGILHX.cjs → chunk-WSG64BVN.cjs} +6 -6
- package/dist/{chunk-K6TGILHX.cjs.map → chunk-WSG64BVN.cjs.map} +1 -1
- package/dist/chunk-WTQYGUNF.js +400 -0
- package/dist/chunk-WTQYGUNF.js.map +1 -0
- package/dist/{chunk-YDVHT7GS.cjs → chunk-WYK7EL5R.cjs} +100 -447
- package/dist/chunk-WYK7EL5R.cjs.map +1 -0
- package/dist/{chunk-X7JL2NYJ.cjs → chunk-XC4KHJYX.cjs} +51 -45
- package/dist/chunk-XC4KHJYX.cjs.map +1 -0
- package/dist/chunk-XVBH5XHE.cjs +400 -0
- package/dist/chunk-XVBH5XHE.cjs.map +1 -0
- package/dist/{chunk-IS5YYLTV.js → chunk-YAFQVVDI.js} +85 -22
- package/dist/chunk-YAFQVVDI.js.map +1 -0
- package/dist/components/legend/index.cjs +4 -3
- package/dist/components/legend/index.cjs.map +1 -1
- package/dist/components/legend/index.css +12 -24
- package/dist/components/legend/index.css.map +1 -1
- package/dist/components/legend/index.d.cts +4 -4
- package/dist/components/legend/index.d.ts +4 -4
- package/dist/components/legend/index.js +3 -2
- package/dist/components/tooltip/index.d.cts +1 -1
- package/dist/components/tooltip/index.d.ts +1 -1
- package/dist/hooks/index.cjs +3 -5
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.css +0 -94
- package/dist/hooks/index.css.map +1 -1
- package/dist/hooks/index.d.cts +9 -13
- package/dist/hooks/index.d.ts +9 -13
- package/dist/hooks/index.js +2 -4
- package/dist/index.cjs +18 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +20 -33
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +17 -16
- package/dist/{leaderboard-chart-COtgamhe.d.cts → leaderboard-chart-BSbg0ufV.d.cts} +3 -11
- package/dist/{leaderboard-chart-BSgEw_Um.d.ts → leaderboard-chart-odEYxxEC.d.ts} +3 -11
- package/dist/{legend-C9ahiwOt.d.cts → legend-DFkosEvC.d.cts} +1 -1
- package/dist/{legend-jjMmhSg3.d.ts → legend-DLswHhOk.d.ts} +1 -1
- package/dist/providers/index.cjs +3 -3
- package/dist/providers/index.css +0 -94
- package/dist/providers/index.css.map +1 -1
- package/dist/providers/index.d.cts +3 -3
- package/dist/providers/index.d.ts +3 -3
- package/dist/providers/index.js +2 -2
- package/dist/{themes-CVR5rmIs.d.cts → themes-D0qc5JaW.d.cts} +2 -2
- package/dist/{themes-DQzmaSze.d.ts → themes-itO4Ht5g.d.ts} +2 -2
- package/dist/{types-BBwg4Evw.d.cts → types-B5f6XQ7Q.d.cts} +1 -1
- package/dist/{types-DQNnq5Fr.d.ts → types-BsHooDbM.d.ts} +1 -1
- package/dist/{types-C05PdDJa.d.cts → types-BuSrRM4p.d.ts} +15 -23
- package/dist/{types-CzdN7rUe.d.cts → types-ChOUI9-N.d.cts} +90 -46
- package/dist/{types-CzdN7rUe.d.ts → types-ChOUI9-N.d.ts} +90 -46
- package/dist/{types-C05PdDJa.d.ts → types-Dfw9VOKI.d.cts} +15 -23
- package/dist/utils/index.cjs +2 -2
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +10 -8
- package/src/charts/bar-chart/bar-chart.tsx +19 -19
- package/src/charts/bar-chart/test/bar-chart.test.tsx +78 -31
- package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +2 -2
- package/src/charts/leaderboard-chart/hooks/use-leaderboard-legend-items.ts +0 -2
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +9 -10
- package/src/charts/leaderboard-chart/leaderboard-chart.tsx +124 -102
- package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +61 -33
- package/src/charts/leaderboard-chart/test/use-leaderboard-legend-items.test.tsx +2 -5
- package/src/charts/leaderboard-chart/types.ts +2 -15
- package/src/charts/line-chart/line-chart.tsx +18 -17
- package/src/charts/line-chart/test/line-chart.test.tsx +49 -27
- package/src/charts/line-chart/types.ts +0 -1
- package/src/charts/pie-chart/pie-chart.tsx +23 -23
- package/src/charts/pie-chart/test/composition-api.test.tsx +41 -0
- package/src/charts/pie-chart/test/pie-chart.test.tsx +9 -9
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +21 -24
- package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +33 -5
- package/src/charts/private/chart-composition/index.ts +2 -0
- package/src/charts/private/chart-composition/render-legend-slot.ts +22 -0
- package/src/charts/private/chart-composition/test/render-legend-slot.test.tsx +60 -0
- package/src/charts/private/chart-composition/test/use-chart-children.test.tsx +91 -0
- package/src/charts/private/chart-composition/use-chart-children.ts +34 -2
- package/src/components/legend/private/base-legend.module.scss +19 -37
- package/src/components/legend/private/base-legend.tsx +32 -24
- package/src/components/legend/test/legend.test.tsx +148 -52
- package/src/components/legend/types.ts +23 -24
- package/src/hooks/index.ts +0 -1
- package/src/hooks/test/use-zero-value-display.test.tsx +206 -0
- package/src/hooks/use-zero-value-display.ts +52 -23
- package/src/providers/chart-context/test/chart-context.test.tsx +12 -6
- package/src/providers/chart-context/themes.ts +6 -4
- package/src/types.ts +93 -44
- package/src/utils/date-parsing.ts +10 -1
- package/src/utils/get-styles.ts +1 -1
- package/src/utils/test/date-parsing.test.ts +12 -0
- package/src/utils/test/get-styles.test.ts +12 -10
- package/src/utils/test/resolve-css-var.test.ts +2 -2
- package/tsup.config.ts +1 -1
- package/dist/chunk-55ZCOYDF.cjs.map +0 -1
- package/dist/chunk-6CCZL2JJ.js.map +0 -1
- package/dist/chunk-7FDQGBY7.js.map +0 -1
- package/dist/chunk-BXFD7JIG.cjs.map +0 -1
- package/dist/chunk-IS5YYLTV.js.map +0 -1
- package/dist/chunk-KNIMXN6Z.js +0 -51
- package/dist/chunk-KNIMXN6Z.js.map +0 -1
- package/dist/chunk-NQJE2CC7.cjs.map +0 -1
- package/dist/chunk-O2JIANHK.cjs.map +0 -1
- package/dist/chunk-OMS5QIJN.js.map +0 -1
- package/dist/chunk-RCY6XLGU.cjs.map +0 -1
- package/dist/chunk-RFSHE3HL.js.map +0 -1
- package/dist/chunk-SSFFCBCF.js.map +0 -1
- package/dist/chunk-SUDERBUA.cjs +0 -51
- package/dist/chunk-SUDERBUA.cjs.map +0 -1
- package/dist/chunk-TE63Y5PX.js.map +0 -1
- package/dist/chunk-UFRBUT2D.cjs.map +0 -1
- package/dist/chunk-VPAEBI2F.js.map +0 -1
- package/dist/chunk-X7JL2NYJ.cjs.map +0 -1
- package/dist/chunk-XD2HV7M5.js.map +0 -1
- package/dist/chunk-YDVHT7GS.cjs.map +0 -1
- package/dist/chunk-ZVGEDXDP.cjs.map +0 -1
- package/src/hooks/use-has-legend-child.ts +0 -22
- /package/dist/{chunk-GWBS65VC.js.map → chunk-4B7BL2DD.js.map} +0 -0
- /package/dist/{chunk-MDRCAGKZ.js.map → chunk-DKU775VC.js.map} +0 -0
- /package/dist/{chunk-KHQPN77E.js.map → chunk-KJHWXOCZ.js.map} +0 -0
- /package/dist/{chunk-E62LCBGD.js.map → chunk-MUNOKLLE.js.map} +0 -0
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
import { LegendOrdinal } from '@visx/legend';
|
|
2
|
+
import { j as LegendPosition, h as LegendItemStyles, i as LegendLabelStyles, k as LegendShapeStyles } from './types-ChOUI9-N.cjs';
|
|
2
3
|
import { GlyphProps, LineStyles } from '@visx/xychart';
|
|
3
4
|
import { ComponentProps, ReactNode, CSSProperties } from 'react';
|
|
4
5
|
|
|
5
|
-
type
|
|
6
|
-
type BaseLegendProps =
|
|
6
|
+
type VisxLegendProps = Pick<ComponentProps<typeof LegendOrdinal>, 'className' | 'shape' | 'fill' | 'size' | 'labelFormat' | 'labelTransform'>;
|
|
7
|
+
type BaseLegendProps = VisxLegendProps & {
|
|
7
8
|
items: BaseLegendItem[];
|
|
8
9
|
orientation?: 'horizontal' | 'vertical';
|
|
9
|
-
|
|
10
|
-
* TODO: Add 'left' | 'right' positioning support in future implementation
|
|
11
|
-
*/
|
|
12
|
-
position?: 'top' | 'bottom';
|
|
10
|
+
position?: LegendPosition;
|
|
13
11
|
alignment?: 'start' | 'center' | 'end';
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
textOverflow?: 'ellipsis' | 'wrap';
|
|
25
|
-
/**
|
|
26
|
-
* Additional CSS class name for legend items.
|
|
27
|
-
* This allows consumers to customize individual legend item styling.
|
|
28
|
-
*/
|
|
29
|
-
legendItemClassName?: string;
|
|
12
|
+
/** Additional CSS class name for legend items. */
|
|
13
|
+
itemClassName?: string;
|
|
14
|
+
/** CSS styles for each legend item (margin, flexDirection). */
|
|
15
|
+
itemStyles?: LegendItemStyles;
|
|
16
|
+
/** Additional CSS class name for legend labels. */
|
|
17
|
+
labelClassName?: string;
|
|
18
|
+
/** CSS styles for legend labels (justifyContent, flex, margin). */
|
|
19
|
+
labelStyles?: LegendLabelStyles;
|
|
20
|
+
/** Styles for legend shapes (width, height, margin). */
|
|
21
|
+
shapeStyles?: LegendShapeStyles;
|
|
30
22
|
/**
|
|
31
23
|
* Function for rendering a custom legend layout.
|
|
32
24
|
*/
|
|
@@ -47,7 +39,7 @@ type LegendProps = Omit<BaseLegendProps, 'items'> & {
|
|
|
47
39
|
};
|
|
48
40
|
type BaseLegendItem = {
|
|
49
41
|
label: string;
|
|
50
|
-
value
|
|
42
|
+
value?: number | string;
|
|
51
43
|
color: string;
|
|
52
44
|
glyphSize?: number;
|
|
53
45
|
renderGlyph?: <Datum extends object>(props: GlyphProps<Datum>) => ReactNode;
|
package/dist/utils/index.cjs
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var _chunkMXGLYWVPcjs = require('../chunk-MXGLYWVP.cjs');
|
|
22
22
|
require('../chunk-EMMSS5I5.cjs');
|
|
23
23
|
|
|
24
24
|
|
|
@@ -40,5 +40,5 @@ require('../chunk-EMMSS5I5.cjs');
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
exports.attachSubComponents =
|
|
43
|
+
exports.attachSubComponents = _chunkMXGLYWVPcjs.attachSubComponents; exports.formatMetricValue = _chunkMXGLYWVPcjs.formatMetricValue; exports.formatPercentage = _chunkMXGLYWVPcjs.formatPercentage; exports.getColorDistance = _chunkMXGLYWVPcjs.getColorDistance; exports.getItemShapeStyles = _chunkMXGLYWVPcjs.getItemShapeStyles; exports.getLongestTickWidth = _chunkMXGLYWVPcjs.getLongestTickWidth; exports.getSeriesLineStyles = _chunkMXGLYWVPcjs.getSeriesLineStyles; exports.getSeriesStroke = _chunkMXGLYWVPcjs.getSeriesStroke; exports.hexToRgba = _chunkMXGLYWVPcjs.hexToRgba; exports.isSafari = _chunkMXGLYWVPcjs.isSafari; exports.isValidHexColor = _chunkMXGLYWVPcjs.isValidHexColor; exports.lightenHexColor = _chunkMXGLYWVPcjs.lightenHexColor; exports.mergeThemes = _chunkMXGLYWVPcjs.mergeThemes; exports.normalizeColorToHex = _chunkMXGLYWVPcjs.normalizeColorToHex; exports.parseAsLocalDate = _chunkMXGLYWVPcjs.parseAsLocalDate; exports.parseHslString = _chunkMXGLYWVPcjs.parseHslString; exports.parseRgbString = _chunkMXGLYWVPcjs.parseRgbString; exports.resolveCssVariable = _chunkMXGLYWVPcjs.resolveCssVariable; exports.validateHexColor = _chunkMXGLYWVPcjs.validateHexColor;
|
|
44
44
|
//# sourceMappingURL=index.cjs.map
|
package/dist/utils/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { M as MetricValueType, f as formatMetricValue } from '../format-metric-value-MXm5DtQ_.cjs';
|
|
2
2
|
import { TickFormatter } from '@visx/axis';
|
|
3
3
|
import { AnyD3Scale, ScaleInput } from '@visx/scale';
|
|
4
|
-
import {
|
|
4
|
+
import { o as SeriesData, b as ChartTheme, c as CompleteChartTheme } from '../types-ChOUI9-N.cjs';
|
|
5
5
|
import { LegendShape } from '@visx/legend/lib/types';
|
|
6
6
|
import { LineStyles } from '@visx/xychart';
|
|
7
7
|
import '@visx/annotation/lib/components/CircleSubject';
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { M as MetricValueType, f as formatMetricValue } from '../format-metric-value-MXm5DtQ_.js';
|
|
2
2
|
import { TickFormatter } from '@visx/axis';
|
|
3
3
|
import { AnyD3Scale, ScaleInput } from '@visx/scale';
|
|
4
|
-
import {
|
|
4
|
+
import { o as SeriesData, b as ChartTheme, c as CompleteChartTheme } from '../types-ChOUI9-N.js';
|
|
5
5
|
import { LegendShape } from '@visx/legend/lib/types';
|
|
6
6
|
import { LineStyles } from '@visx/xychart';
|
|
7
7
|
import '@visx/annotation/lib/components/CircleSubject';
|
package/dist/utils/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/charts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.58.0",
|
|
4
4
|
"description": "Display charts within Automattic products.",
|
|
5
5
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/charts/#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -177,10 +177,10 @@
|
|
|
177
177
|
"storybook": "cd ../storybook && pnpm run storybook:dev",
|
|
178
178
|
"test": "TZ=UTC jest --config=tests/jest.config.cjs",
|
|
179
179
|
"test-coverage": "pnpm run test --coverage",
|
|
180
|
-
"typecheck": "
|
|
180
|
+
"typecheck": "tsgo --noEmit"
|
|
181
181
|
},
|
|
182
182
|
"dependencies": {
|
|
183
|
-
"@automattic/number-formatters": "^1.1.
|
|
183
|
+
"@automattic/number-formatters": "^1.1.2",
|
|
184
184
|
"@babel/runtime": "7.28.6",
|
|
185
185
|
"@react-spring/web": "9.7.5",
|
|
186
186
|
"@visx/annotation": "^3.12.0",
|
|
@@ -200,8 +200,8 @@
|
|
|
200
200
|
"@visx/vendor": "^3.12.0",
|
|
201
201
|
"@visx/xychart": "^3.12.0",
|
|
202
202
|
"@wordpress/i18n": "^6.0.0",
|
|
203
|
-
"@wordpress/theme": "0.
|
|
204
|
-
"@wordpress/ui": "0.
|
|
203
|
+
"@wordpress/theme": "0.8.0",
|
|
204
|
+
"@wordpress/ui": "0.8.0",
|
|
205
205
|
"clsx": "2.1.1",
|
|
206
206
|
"date-fns": "^4.1.0",
|
|
207
207
|
"deepmerge": "4.3.1",
|
|
@@ -224,21 +224,23 @@
|
|
|
224
224
|
"@types/jest": "^30.0.0",
|
|
225
225
|
"@types/react": "18.3.28",
|
|
226
226
|
"@types/react-dom": "18.3.7",
|
|
227
|
+
"@typescript/native-preview": "7.0.0-dev.20260225.1",
|
|
227
228
|
"@visx/glyph": "3.12.0",
|
|
228
|
-
"@wordpress/components": "32.
|
|
229
|
-
"@wordpress/element": "6.
|
|
229
|
+
"@wordpress/components": "32.3.0",
|
|
230
|
+
"@wordpress/element": "6.41.0",
|
|
230
231
|
"babel-jest": "30.2.0",
|
|
231
232
|
"babel-plugin-react-remove-properties": "^0.3.1",
|
|
232
233
|
"esbuild": "0.25.9",
|
|
233
234
|
"esbuild-plugin-babel": "^0.2.3",
|
|
234
235
|
"esbuild-sass-plugin": "^3.1.0",
|
|
236
|
+
"identity-obj-proxy": "^3.0.0",
|
|
235
237
|
"jest": "30.2.0",
|
|
236
238
|
"jest-extended": "7.0.0",
|
|
237
239
|
"postcss": "8.5.6",
|
|
238
240
|
"postcss-modules": "6.0.1",
|
|
239
241
|
"react": "18.3.1",
|
|
240
242
|
"react-dom": "18.3.1",
|
|
241
|
-
"sass-embedded": "1.97.
|
|
243
|
+
"sass-embedded": "1.97.3",
|
|
242
244
|
"storybook": "10.2.11",
|
|
243
245
|
"tsup": "8.5.1",
|
|
244
246
|
"typescript": "5.9.3"
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
useZeroValueDisplay,
|
|
14
14
|
useChartMargin,
|
|
15
15
|
useElementSize,
|
|
16
|
-
useHasLegendChild,
|
|
17
16
|
usePrefersReducedMotion,
|
|
18
17
|
} from '../../hooks';
|
|
19
18
|
import {
|
|
@@ -25,6 +24,7 @@ import {
|
|
|
25
24
|
GlobalChartsContext,
|
|
26
25
|
} from '../../providers';
|
|
27
26
|
import { attachSubComponents } from '../../utils';
|
|
27
|
+
import { useChartChildren, renderLegendSlot } from '../private/chart-composition';
|
|
28
28
|
import { SingleChartContext } from '../private/single-chart-context';
|
|
29
29
|
import { withResponsive } from '../private/with-responsive';
|
|
30
30
|
import styles from './bar-chart.module.scss';
|
|
@@ -39,7 +39,6 @@ export interface BarChartProps extends BaseChartProps< SeriesData[] > {
|
|
|
39
39
|
orientation?: 'horizontal' | 'vertical';
|
|
40
40
|
withPatterns?: boolean;
|
|
41
41
|
showZeroValues?: boolean;
|
|
42
|
-
legendInteractive?: boolean;
|
|
43
42
|
children?: ReactNode;
|
|
44
43
|
}
|
|
45
44
|
|
|
@@ -85,24 +84,18 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
85
84
|
margin,
|
|
86
85
|
withTooltips = false,
|
|
87
86
|
showLegend = false,
|
|
88
|
-
|
|
89
|
-
legendPosition = 'bottom',
|
|
90
|
-
legendAlignment = 'center',
|
|
91
|
-
legendMaxWidth,
|
|
92
|
-
legendTextOverflow = 'wrap',
|
|
93
|
-
legendItemClassName,
|
|
94
|
-
legendShape = 'rect',
|
|
87
|
+
legend = {},
|
|
95
88
|
gridVisibility: gridVisibilityProp,
|
|
96
89
|
renderTooltip,
|
|
97
90
|
options = {},
|
|
98
91
|
orientation = 'vertical',
|
|
99
92
|
withPatterns = false,
|
|
100
93
|
showZeroValues = false,
|
|
101
|
-
legendInteractive = false,
|
|
102
94
|
animation,
|
|
103
95
|
children,
|
|
104
96
|
gap = 'md',
|
|
105
97
|
} ) => {
|
|
98
|
+
const legendInteractive = legend.interactive ?? false;
|
|
106
99
|
const horizontal = orientation === 'horizontal';
|
|
107
100
|
const chartId = useChartId( providedChartId );
|
|
108
101
|
const theme = useXYChartTheme( data );
|
|
@@ -110,8 +103,10 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
110
103
|
const dataSorted = useChartDataTransform( data );
|
|
111
104
|
|
|
112
105
|
// Transform data to add a small value for zero bars to make them visible
|
|
106
|
+
// For vertical bars, height determines bar pixel height; for horizontal bars, width does
|
|
113
107
|
const dataWithVisibleZeros = useZeroValueDisplay( dataSorted, {
|
|
114
108
|
enabled: showZeroValues,
|
|
109
|
+
valueAxisLength: horizontal ? width : height,
|
|
115
110
|
} );
|
|
116
111
|
|
|
117
112
|
// Create legend items using the reusable hook
|
|
@@ -121,8 +116,9 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
121
116
|
const [ svgWrapperRef, , svgWrapperHeight ] = useElementSize< HTMLDivElement >();
|
|
122
117
|
const chartRef = useRef< HTMLDivElement >( null );
|
|
123
118
|
|
|
124
|
-
//
|
|
125
|
-
const
|
|
119
|
+
// Process children for composition API (Legend, etc.)
|
|
120
|
+
const { legendChildren, nonLegendChildren } = useChartChildren( children, 'BarChart' );
|
|
121
|
+
const hasLegendChild = legendChildren.length > 0;
|
|
126
122
|
|
|
127
123
|
// Use the measured SVG wrapper height, falling back to the passed height if provided.
|
|
128
124
|
// When there's a legend (via prop or composition), we must wait for measurement because
|
|
@@ -325,16 +321,18 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
325
321
|
const gridVisibility = gridVisibilityProp ?? chartOptions.gridVisibility;
|
|
326
322
|
const highlightedBarStyle = createKeyboardHighlightStyle();
|
|
327
323
|
|
|
324
|
+
const legendPosition = legend.position ?? 'bottom';
|
|
328
325
|
const legendElement = showLegend && (
|
|
329
326
|
<Legend
|
|
330
|
-
orientation={
|
|
327
|
+
orientation={ legend.orientation ?? 'horizontal' }
|
|
331
328
|
position={ legendPosition }
|
|
332
|
-
alignment={
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
329
|
+
alignment={ legend.alignment ?? 'center' }
|
|
330
|
+
labelStyles={ legend.labelStyles }
|
|
331
|
+
itemClassName={ legend.itemClassName }
|
|
332
|
+
itemStyles={ legend.itemStyles }
|
|
333
|
+
shapeStyles={ legend.shapeStyles }
|
|
336
334
|
className={ styles[ 'bar-chart__legend' ] }
|
|
337
|
-
shape={
|
|
335
|
+
shape={ legend.shape ?? 'rect' }
|
|
338
336
|
chartId={ chartId }
|
|
339
337
|
interactive={ legendInteractive }
|
|
340
338
|
/>
|
|
@@ -369,6 +367,7 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
369
367
|
data-chart-id={ `bar-chart-${ chartId }` }
|
|
370
368
|
>
|
|
371
369
|
{ legendPosition === 'top' && legendElement }
|
|
370
|
+
{ renderLegendSlot( legendChildren, 'top' ) }
|
|
372
371
|
|
|
373
372
|
<div
|
|
374
373
|
className={ styles[ 'bar-chart__svg-wrapper' ] }
|
|
@@ -482,8 +481,9 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
482
481
|
</div>
|
|
483
482
|
|
|
484
483
|
{ legendPosition === 'bottom' && legendElement }
|
|
484
|
+
{ renderLegendSlot( legendChildren, 'bottom' ) }
|
|
485
485
|
|
|
486
|
-
{
|
|
486
|
+
{ nonLegendChildren }
|
|
487
487
|
</Stack>
|
|
488
488
|
</SingleChartContext.Provider>
|
|
489
489
|
);
|
|
@@ -26,10 +26,12 @@ describe( 'BarChart', () => {
|
|
|
26
26
|
],
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const renderWithTheme = ( props = {} ) => {
|
|
29
|
+
const renderWithTheme = ( props = {}, children = undefined ) => {
|
|
30
30
|
return render(
|
|
31
31
|
<GlobalChartsProvider>
|
|
32
|
-
<BarChart { ...defaultProps } { ...props }
|
|
32
|
+
<BarChart { ...defaultProps } { ...props }>
|
|
33
|
+
{ children }
|
|
34
|
+
</BarChart>
|
|
33
35
|
</GlobalChartsProvider>
|
|
34
36
|
);
|
|
35
37
|
};
|
|
@@ -123,39 +125,54 @@ describe( 'BarChart', () => {
|
|
|
123
125
|
} );
|
|
124
126
|
|
|
125
127
|
describe( 'Legend', () => {
|
|
128
|
+
const multiSeriesData = [
|
|
129
|
+
{
|
|
130
|
+
label: 'Series A',
|
|
131
|
+
data: [ { date: new Date( '2024-01-01' ), value: 10, label: 'Jan 1' } ],
|
|
132
|
+
options: {},
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
label: 'Series B',
|
|
136
|
+
data: [ { date: new Date( '2024-01-01' ), value: 20, label: 'Jan 1' } ],
|
|
137
|
+
options: {},
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
|
|
126
141
|
test( 'shows legend when showLegend is true', () => {
|
|
127
|
-
renderWithTheme( {
|
|
128
|
-
showLegend: true,
|
|
129
|
-
data: [
|
|
130
|
-
{
|
|
131
|
-
label: 'Series A',
|
|
132
|
-
data: [ { date: new Date( '2024-01-01' ), value: 10, label: 'Jan 1' } ],
|
|
133
|
-
options: {},
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
label: 'Series B',
|
|
137
|
-
data: [ { date: new Date( '2024-01-01' ), value: 20, label: 'Jan 1' } ],
|
|
138
|
-
options: {},
|
|
139
|
-
},
|
|
140
|
-
],
|
|
141
|
-
} );
|
|
142
|
+
renderWithTheme( { showLegend: true, data: multiSeriesData } );
|
|
142
143
|
expect( screen.getByText( 'Series A' ) ).toBeInTheDocument();
|
|
143
144
|
expect( screen.getByText( 'Series B' ) ).toBeInTheDocument();
|
|
144
145
|
} );
|
|
145
146
|
|
|
146
147
|
test( 'hides legend when showLegend is false', () => {
|
|
147
|
-
renderWithTheme( {
|
|
148
|
-
showLegend: false,
|
|
149
|
-
data: [
|
|
150
|
-
{
|
|
151
|
-
label: 'Series A',
|
|
152
|
-
data: [ { date: new Date( '2024-01-01' ), value: 10, label: 'Jan 1' } ],
|
|
153
|
-
options: {},
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
} );
|
|
148
|
+
renderWithTheme( { showLegend: false, data: multiSeriesData } );
|
|
157
149
|
expect( screen.queryByText( 'Series A' ) ).not.toBeInTheDocument();
|
|
158
150
|
} );
|
|
151
|
+
|
|
152
|
+
test( 'renders composition legend as child component', () => {
|
|
153
|
+
renderWithTheme( { data: multiSeriesData }, <BarChart.Legend /> );
|
|
154
|
+
|
|
155
|
+
expect( screen.getAllByTestId( 'legend-item' ) ).toHaveLength( 2 );
|
|
156
|
+
expect( screen.getByText( 'Series A' ) ).toBeInTheDocument();
|
|
157
|
+
expect( screen.getByText( 'Series B' ) ).toBeInTheDocument();
|
|
158
|
+
} );
|
|
159
|
+
|
|
160
|
+
test( 'renders composition legend regardless of showLegend value', () => {
|
|
161
|
+
renderWithTheme( { data: multiSeriesData, showLegend: false }, <BarChart.Legend /> );
|
|
162
|
+
|
|
163
|
+
expect( screen.getAllByTestId( 'legend-item' ) ).toHaveLength( 2 );
|
|
164
|
+
} );
|
|
165
|
+
|
|
166
|
+
test( 'renders composition legend in top position', () => {
|
|
167
|
+
renderWithTheme( { data: multiSeriesData }, <BarChart.Legend position="top" /> );
|
|
168
|
+
|
|
169
|
+
// Legend should appear before the chart content in DOM order
|
|
170
|
+
expect( screen.getAllByTestId( 'legend-item' ) ).toHaveLength( 2 );
|
|
171
|
+
const html = document.body.innerHTML;
|
|
172
|
+
expect( html.indexOf( 'data-testid="legend-horizontal"' ) ).toBeLessThan(
|
|
173
|
+
html.indexOf( 'role="grid"' )
|
|
174
|
+
);
|
|
175
|
+
} );
|
|
159
176
|
} );
|
|
160
177
|
|
|
161
178
|
describe( 'Grid Visibility', () => {
|
|
@@ -562,6 +579,36 @@ describe( 'BarChart', () => {
|
|
|
562
579
|
expect( width ).toBeGreaterThan( 0 );
|
|
563
580
|
} );
|
|
564
581
|
} );
|
|
582
|
+
|
|
583
|
+
test( 'ensures minimum pixel height for zero values in small charts', () => {
|
|
584
|
+
// With a small chart height (100px) and large data range, zero-value bars
|
|
585
|
+
// should still be visible (at least 3px based on MIN_PIXEL_HEIGHT)
|
|
586
|
+
renderWithTheme( {
|
|
587
|
+
showZeroValues: true,
|
|
588
|
+
height: 100,
|
|
589
|
+
data: [
|
|
590
|
+
{
|
|
591
|
+
label: 'Test Series',
|
|
592
|
+
data: [
|
|
593
|
+
{ label: 'Zero', value: 0 },
|
|
594
|
+
{ label: 'Large', value: 10000 },
|
|
595
|
+
],
|
|
596
|
+
options: {},
|
|
597
|
+
},
|
|
598
|
+
],
|
|
599
|
+
} );
|
|
600
|
+
|
|
601
|
+
const svgElement = screen.getByRole( 'grid', { name: /bar chart/i } ).querySelector( 'svg' );
|
|
602
|
+
const bars = svgElement?.querySelectorAll( '.visx-bar-group rect' );
|
|
603
|
+
|
|
604
|
+
expect( bars?.length ).toBe( 2 );
|
|
605
|
+
|
|
606
|
+
// The zero-value bar (first bar) should have a minimum visible height.
|
|
607
|
+
// We check for >= 2px to allow for rounding in the pixel calculation.
|
|
608
|
+
const zeroBar = bars?.[ 0 ];
|
|
609
|
+
const zeroBarHeight = parseFloat( zeroBar?.getAttribute( 'height' ) || '0' );
|
|
610
|
+
expect( zeroBarHeight ).toBeGreaterThanOrEqual( 2 );
|
|
611
|
+
} );
|
|
565
612
|
} );
|
|
566
613
|
|
|
567
614
|
/* eslint-enable testing-library/no-node-access */
|
|
@@ -713,7 +760,7 @@ describe( 'BarChart', () => {
|
|
|
713
760
|
|
|
714
761
|
renderWithTheme( {
|
|
715
762
|
showLegend: true,
|
|
716
|
-
|
|
763
|
+
legend: { interactive: true },
|
|
717
764
|
chartId: 'test-interactive-bar-chart',
|
|
718
765
|
data: [
|
|
719
766
|
{
|
|
@@ -741,7 +788,7 @@ describe( 'BarChart', () => {
|
|
|
741
788
|
it( 'does not filter series when legendInteractive is false', () => {
|
|
742
789
|
renderWithTheme( {
|
|
743
790
|
showLegend: true,
|
|
744
|
-
|
|
791
|
+
legend: { interactive: false },
|
|
745
792
|
chartId: 'test-non-interactive-bar-chart',
|
|
746
793
|
data: [
|
|
747
794
|
{
|
|
@@ -765,7 +812,7 @@ describe( 'BarChart', () => {
|
|
|
765
812
|
it( 'shows all series when chartId is missing even if legendInteractive is true', () => {
|
|
766
813
|
renderWithTheme( {
|
|
767
814
|
showLegend: true,
|
|
768
|
-
|
|
815
|
+
legend: { interactive: true },
|
|
769
816
|
// No chartId provided
|
|
770
817
|
data: [
|
|
771
818
|
{
|
|
@@ -793,7 +840,7 @@ describe( 'BarChart', () => {
|
|
|
793
840
|
|
|
794
841
|
renderWithTheme( {
|
|
795
842
|
showLegend: true,
|
|
796
|
-
|
|
843
|
+
legend: { interactive: true },
|
|
797
844
|
chartId: 'test-all-hidden-bar-chart',
|
|
798
845
|
data: [
|
|
799
846
|
{
|
|
@@ -372,7 +372,7 @@ describe( 'ConversionFunnelChart', () => {
|
|
|
372
372
|
expect( customRenderMainMetric ).toHaveBeenCalledWith( {
|
|
373
373
|
mainRate: 10.3,
|
|
374
374
|
changeIndicator: undefined,
|
|
375
|
-
className:
|
|
375
|
+
className: 'main-metric',
|
|
376
376
|
changeColor: expect.any( String ),
|
|
377
377
|
} );
|
|
378
378
|
} );
|
|
@@ -427,7 +427,7 @@ describe( 'ConversionFunnelChart', () => {
|
|
|
427
427
|
index: 1,
|
|
428
428
|
top: expect.any( Number ),
|
|
429
429
|
left: expect.any( Number ),
|
|
430
|
-
className:
|
|
430
|
+
className: 'tooltip-wrapper',
|
|
431
431
|
} );
|
|
432
432
|
} );
|
|
433
433
|
|
|
@@ -53,7 +53,6 @@ export function useLeaderboardLegendItems( {
|
|
|
53
53
|
|
|
54
54
|
items.push( {
|
|
55
55
|
label: legendLabels?.primary || __( 'Current period', 'jetpack-charts' ),
|
|
56
|
-
value: '',
|
|
57
56
|
color: resolvedPrimaryColor,
|
|
58
57
|
} );
|
|
59
58
|
|
|
@@ -66,7 +65,6 @@ export function useLeaderboardLegendItems( {
|
|
|
66
65
|
|
|
67
66
|
items.push( {
|
|
68
67
|
label: legendLabels?.comparison || __( 'Previous period', 'jetpack-charts' ),
|
|
69
|
-
value: '',
|
|
70
68
|
color: resolvedSecondaryColor,
|
|
71
69
|
} );
|
|
72
70
|
}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
.leaderboardChart {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
2
|
transition: opacity 0.3s ease-in-out;
|
|
5
3
|
|
|
6
|
-
&--
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
&--with-legend {
|
|
11
|
-
gap: 16px;
|
|
4
|
+
&--responsive {
|
|
5
|
+
height: 100%;
|
|
6
|
+
width: 100%;
|
|
12
7
|
}
|
|
13
8
|
|
|
14
9
|
&--loading {
|
|
15
10
|
opacity: 0.5;
|
|
16
11
|
}
|
|
12
|
+
|
|
13
|
+
&__content {
|
|
14
|
+
flex: 1;
|
|
15
|
+
min-height: 0;
|
|
16
|
+
overflow: auto;
|
|
17
|
+
}
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
.barWithLabelContainer {
|
|
@@ -61,8 +62,6 @@
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
.valueContainer {
|
|
64
|
-
display: flex;
|
|
65
|
-
gap: 4px;
|
|
66
65
|
justify-content: flex-end;
|
|
67
66
|
}
|
|
68
67
|
|