@automattic/charts 0.57.0 → 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/CHANGELOG.md +16 -2
- package/dist/charts/bar-chart/index.cjs +7 -5
- 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 -4
- package/dist/charts/bar-list-chart/index.cjs +8 -6
- 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 -5
- package/dist/charts/conversion-funnel-chart/index.cjs +5 -5
- 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 -4
- 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 +12 -24
- 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 -5
- 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 -4
- package/dist/charts/pie-chart/index.cjs +7 -6
- package/dist/charts/pie-chart/index.cjs.map +1 -1
- 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 -5
- package/dist/charts/pie-semi-circle-chart/index.cjs +7 -6
- package/dist/charts/pie-semi-circle-chart/index.cjs.map +1 -1
- 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 -5
- package/dist/charts/sparkline/index.cjs +8 -6
- 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 -5
- package/dist/{chunk-32DH6JDF.js → chunk-2I67QUIV.js} +52 -420
- package/dist/chunk-2I67QUIV.js.map +1 -0
- package/dist/{chunk-WLODYNLB.js → chunk-2ICEEQOC.js} +31 -27
- package/dist/chunk-2ICEEQOC.js.map +1 -0
- package/dist/{chunk-IU4DYUAV.js → chunk-4B7BL2DD.js} +3 -3
- package/dist/{chunk-BCX5THDQ.js → chunk-4OXMTKAL.js} +24 -26
- package/dist/chunk-4OXMTKAL.js.map +1 -0
- package/dist/{chunk-4OPFE4RM.js → chunk-B6NLZFRW.js} +30 -27
- package/dist/chunk-B6NLZFRW.js.map +1 -0
- package/dist/{chunk-D2UH4CFE.cjs → chunk-BBAUQOW6.cjs} +9 -9
- package/dist/{chunk-D2UH4CFE.cjs.map → chunk-BBAUQOW6.cjs.map} +1 -1
- package/dist/{chunk-XKRJL2QT.cjs → chunk-CMMHCTBX.cjs} +45 -47
- package/dist/chunk-CMMHCTBX.cjs.map +1 -0
- package/dist/{chunk-YE2T52VZ.cjs → chunk-CPPXJATQ.cjs} +51 -47
- package/dist/chunk-CPPXJATQ.cjs.map +1 -0
- package/dist/{chunk-H2V4JMSA.js → chunk-DKU775VC.js} +3 -3
- package/dist/{chunk-ZH4F5RMG.cjs → chunk-GRA7Y2ZG.cjs} +46 -48
- package/dist/chunk-GRA7Y2ZG.cjs.map +1 -0
- package/dist/{chunk-DAU3HNEG.js → chunk-JJIMABHT.js} +9 -2
- package/dist/chunk-JJIMABHT.js.map +1 -0
- package/dist/{chunk-CZGYJKG6.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-V36ERY7Y.js → chunk-LTFH7SEG.js} +24 -26
- package/dist/chunk-LTFH7SEG.js.map +1 -0
- package/dist/{chunk-PXLEMUGJ.js → chunk-MUNOKLLE.js} +3 -3
- package/dist/{chunk-VTS3PNMS.cjs → chunk-MXGLYWVP.cjs} +9 -2
- package/dist/chunk-MXGLYWVP.cjs.map +1 -0
- package/dist/{chunk-Z45KX47P.cjs → chunk-OYC34VTO.cjs} +154 -94
- package/dist/chunk-OYC34VTO.cjs.map +1 -0
- package/dist/{chunk-77OKCVQN.cjs → chunk-PQL5I3F6.cjs} +17 -17
- package/dist/{chunk-77OKCVQN.cjs.map → chunk-PQL5I3F6.cjs.map} +1 -1
- package/dist/{chunk-I35UYJJR.cjs → chunk-REZTQ4PH.cjs} +41 -21
- 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-2NCY7R4G.js → chunk-UTYVIOWZ.js} +111 -51
- package/dist/chunk-UTYVIOWZ.js.map +1 -0
- package/dist/{chunk-TO3OQBXG.cjs → chunk-W2LDIX26.cjs} +5 -5
- package/dist/{chunk-TO3OQBXG.cjs.map → chunk-W2LDIX26.cjs.map} +1 -1
- package/dist/{chunk-7FQX4ALL.cjs → chunk-WSG64BVN.cjs} +6 -6
- package/dist/{chunk-7FQX4ALL.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-RHHVEJHJ.cjs → chunk-WYK7EL5R.cjs} +68 -436
- package/dist/chunk-WYK7EL5R.cjs.map +1 -0
- package/dist/{chunk-VJM5XCB4.cjs → chunk-XC4KHJYX.cjs} +49 -46
- 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-Z26M4V2M.js → chunk-YAFQVVDI.js} +41 -21
- 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 +3 -11
- package/dist/hooks/index.d.ts +3 -11
- package/dist/hooks/index.js +2 -4
- package/dist/index.cjs +18 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +12 -24
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +17 -15
- package/dist/{leaderboard-chart-DR7CGb0L.d.cts → leaderboard-chart-BSbg0ufV.d.cts} +3 -7
- package/dist/{leaderboard-chart-BKYYXcg2.d.ts → leaderboard-chart-odEYxxEC.d.ts} +3 -7
- package/dist/{legend-C2grwnWk.d.cts → legend-DFkosEvC.d.cts} +1 -1
- package/dist/{legend-Cj0xM5dU.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-CyjKm-P_.d.cts → themes-D0qc5JaW.d.cts} +2 -2
- package/dist/{themes-BmVGrYnF.d.ts → themes-itO4Ht5g.d.ts} +2 -2
- package/dist/{types-KtOPPzPX.d.cts → types-B5f6XQ7Q.d.cts} +1 -1
- package/dist/{types-CuUEszrM.d.ts → types-BsHooDbM.d.ts} +1 -1
- package/dist/{types-I67mddpr.d.cts → types-BuSrRM4p.d.ts} +3 -32
- package/dist/{types-DZordNiO.d.cts → types-ChOUI9-N.d.cts} +80 -40
- package/dist/{types-DZordNiO.d.ts → types-ChOUI9-N.d.ts} +80 -40
- package/dist/{types-I67mddpr.d.ts → types-Dfw9VOKI.d.cts} +3 -32
- 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 +6 -6
- package/src/charts/bar-chart/bar-chart.tsx +17 -18
- package/src/charts/bar-chart/test/bar-chart.test.tsx +48 -31
- package/src/charts/leaderboard-chart/leaderboard-chart.tsx +38 -41
- package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +4 -5
- package/src/charts/leaderboard-chart/types.ts +1 -11
- package/src/charts/line-chart/line-chart.tsx +18 -16
- 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 -22
- 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 -23
- 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/index.ts +1 -8
- package/src/components/legend/private/base-legend.module.scss +19 -37
- package/src/components/legend/private/base-legend.tsx +0 -2
- package/src/components/legend/types.ts +7 -34
- package/src/hooks/index.ts +0 -1
- package/src/index.ts +1 -7
- package/src/types.ts +83 -38
- package/src/utils/date-parsing.ts +10 -1
- package/src/utils/test/date-parsing.test.ts +12 -0
- package/src/utils/test/resolve-css-var.test.ts +2 -2
- package/tsup.config.ts +1 -1
- package/dist/chunk-2NCY7R4G.js.map +0 -1
- package/dist/chunk-32DH6JDF.js.map +0 -1
- package/dist/chunk-4OPFE4RM.js.map +0 -1
- package/dist/chunk-6CCZL2JJ.js.map +0 -1
- package/dist/chunk-BCX5THDQ.js.map +0 -1
- package/dist/chunk-DAU3HNEG.js.map +0 -1
- package/dist/chunk-I35UYJJR.cjs.map +0 -1
- package/dist/chunk-RCY6XLGU.cjs.map +0 -1
- package/dist/chunk-RHHVEJHJ.cjs.map +0 -1
- package/dist/chunk-V36ERY7Y.js.map +0 -1
- package/dist/chunk-VJM5XCB4.cjs.map +0 -1
- package/dist/chunk-VTS3PNMS.cjs.map +0 -1
- package/dist/chunk-WLODYNLB.js.map +0 -1
- package/dist/chunk-XKRJL2QT.cjs.map +0 -1
- package/dist/chunk-YE2T52VZ.cjs.map +0 -1
- package/dist/chunk-Z26M4V2M.js.map +0 -1
- package/dist/chunk-Z45KX47P.cjs.map +0 -1
- package/dist/chunk-ZH4F5RMG.cjs.map +0 -1
- package/src/hooks/use-has-legend-child.ts +0 -22
- /package/dist/{chunk-IU4DYUAV.js.map → chunk-4B7BL2DD.js.map} +0 -0
- /package/dist/{chunk-H2V4JMSA.js.map → chunk-DKU775VC.js.map} +0 -0
- /package/dist/{chunk-CZGYJKG6.js.map → chunk-KJHWXOCZ.js.map} +0 -0
- /package/dist/{chunk-PXLEMUGJ.js.map → chunk-MUNOKLLE.js.map} +0 -0
|
@@ -8,7 +8,7 @@ import { ScaleType, ScaleInput } from '@visx/scale';
|
|
|
8
8
|
import { TextProps } from '@visx/text/lib/Text';
|
|
9
9
|
import { EventHandlerParams, LineStyles, GridStyles, GlyphProps } from '@visx/xychart';
|
|
10
10
|
import { GapSize } from '@wordpress/theme';
|
|
11
|
-
import { PointerEvent,
|
|
11
|
+
import { PointerEvent, CSSProperties, ReactNode } from 'react';
|
|
12
12
|
import { GoogleDataTableColumn, GoogleDataTableRow } from 'react-google-charts';
|
|
13
13
|
|
|
14
14
|
type ValueOf<T> = T[keyof T];
|
|
@@ -322,6 +322,81 @@ type ScaleOptions = {
|
|
|
322
322
|
*/
|
|
323
323
|
paddingOuter?: number;
|
|
324
324
|
};
|
|
325
|
+
type LegendItemStyles = {
|
|
326
|
+
/** Margin around each legend item. */
|
|
327
|
+
margin?: CSSProperties['margin'];
|
|
328
|
+
/** Flex direction for items within each legend entry. */
|
|
329
|
+
flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
330
|
+
};
|
|
331
|
+
type LegendLabelStyles = Pick<CSSProperties, 'justifyContent' | 'flex' | 'margin'> & {
|
|
332
|
+
/**
|
|
333
|
+
* Maximum width for legend label text as a CSS value (e.g. '200px', '50%', '10rem').
|
|
334
|
+
* When set, text overflow behavior is controlled by textOverflow.
|
|
335
|
+
*/
|
|
336
|
+
maxWidth?: string;
|
|
337
|
+
/**
|
|
338
|
+
* Controls how text behaves when it exceeds maxWidth.
|
|
339
|
+
* - 'ellipsis': Truncate with ellipsis (ideal for widgets/small devices)
|
|
340
|
+
* - 'wrap': Wrap text to multiple lines (default, ideal for larger displays)
|
|
341
|
+
*/
|
|
342
|
+
textOverflow?: 'ellipsis' | 'wrap';
|
|
343
|
+
};
|
|
344
|
+
type LegendShapeStyles = {
|
|
345
|
+
/** Width of the legend shape in pixels. */
|
|
346
|
+
width?: number;
|
|
347
|
+
/** Height of the legend shape in pixels. */
|
|
348
|
+
height?: number;
|
|
349
|
+
/** Margin around the legend shape. */
|
|
350
|
+
margin?: CSSProperties['margin'];
|
|
351
|
+
};
|
|
352
|
+
/** Position of the legend relative to chart content. */
|
|
353
|
+
type LegendPosition = 'top' | 'bottom';
|
|
354
|
+
/**
|
|
355
|
+
* Configuration object for chart legend appearance and behavior.
|
|
356
|
+
* Consolidates all legend styling and layout props into a single structured object.
|
|
357
|
+
*/
|
|
358
|
+
type ChartLegendConfig<T = DataPoint | DataPointDate | LeaderboardEntry> = {
|
|
359
|
+
/**
|
|
360
|
+
* Layout direction of legend items.
|
|
361
|
+
*/
|
|
362
|
+
orientation?: 'horizontal' | 'vertical';
|
|
363
|
+
/**
|
|
364
|
+
* Position of the legend relative to the chart.
|
|
365
|
+
* TODO: Add 'left' | 'right' positioning support in future implementation
|
|
366
|
+
*/
|
|
367
|
+
position?: LegendPosition;
|
|
368
|
+
/**
|
|
369
|
+
* Alignment of the legend within its position.
|
|
370
|
+
*/
|
|
371
|
+
alignment?: 'start' | 'center' | 'end';
|
|
372
|
+
/**
|
|
373
|
+
* Shape of the legend marker icon.
|
|
374
|
+
*/
|
|
375
|
+
shape?: LegendShape<T, number>;
|
|
376
|
+
/**
|
|
377
|
+
* Enable interactive legend items that can toggle series visibility.
|
|
378
|
+
* Supported for all chart types that render series.
|
|
379
|
+
* Requires chartId and GlobalChartsProvider.
|
|
380
|
+
* For pie charts, percentages are recalculated so visible segments total 100%.
|
|
381
|
+
*/
|
|
382
|
+
interactive?: boolean;
|
|
383
|
+
/**
|
|
384
|
+
* Additional CSS class name for individual legend items.
|
|
385
|
+
*/
|
|
386
|
+
itemClassName?: string;
|
|
387
|
+
/**
|
|
388
|
+
* CSS styles for each legend item (margin, flexDirection).
|
|
389
|
+
*/
|
|
390
|
+
itemStyles?: LegendItemStyles;
|
|
391
|
+
/**
|
|
392
|
+
* CSS styles for legend labels (maxWidth, textOverflow, justifyContent, flex, margin).
|
|
393
|
+
*/
|
|
394
|
+
labelStyles?: LegendLabelStyles;
|
|
395
|
+
/**
|
|
396
|
+
* Styles for legend shapes (width, height, margin).
|
|
397
|
+
*/
|
|
398
|
+
shapeStyles?: LegendShapeStyles;
|
|
399
|
+
};
|
|
325
400
|
/**
|
|
326
401
|
* Base properties shared across all chart components
|
|
327
402
|
*/
|
|
@@ -386,45 +461,10 @@ type BaseChartProps<T = DataPoint | DataPointDate | LeaderboardEntry> = {
|
|
|
386
461
|
*/
|
|
387
462
|
showLegend?: boolean;
|
|
388
463
|
/**
|
|
389
|
-
* Legend
|
|
390
|
-
|
|
391
|
-
legendOrientation?: 'horizontal' | 'vertical';
|
|
392
|
-
/**
|
|
393
|
-
* Legend shape
|
|
394
|
-
*/
|
|
395
|
-
legendShape?: LegendShape<T, number>;
|
|
396
|
-
/**
|
|
397
|
-
* Legend position (where the legend appears)
|
|
398
|
-
* TODO: Add 'left' | 'right' positioning support in future implementation
|
|
399
|
-
*/
|
|
400
|
-
legendPosition?: 'top' | 'bottom';
|
|
401
|
-
/**
|
|
402
|
-
* Legend alignment within its position
|
|
403
|
-
*/
|
|
404
|
-
legendAlignment?: 'start' | 'center' | 'end';
|
|
405
|
-
/**
|
|
406
|
-
* Maximum width for legend items. When set, text overflow behavior is controlled by legendTextOverflow.
|
|
407
|
-
* Should be a CSS value string (e.g. '200px', '50%', '10rem')
|
|
408
|
-
*/
|
|
409
|
-
legendMaxWidth?: string;
|
|
410
|
-
/**
|
|
411
|
-
* Controls how text behaves when it exceeds legendMaxWidth.
|
|
412
|
-
* - 'ellipsis': Truncate with ellipsis (ideal for widgets/small devices)
|
|
413
|
-
* - 'wrap': Wrap text to multiple lines (default, ideal for larger displays)
|
|
414
|
-
*/
|
|
415
|
-
legendTextOverflow?: 'ellipsis' | 'wrap';
|
|
416
|
-
/**
|
|
417
|
-
* Additional CSS class name for legend items.
|
|
418
|
-
* This allows consumers to customize individual legend item styling.
|
|
419
|
-
*/
|
|
420
|
-
legendItemClassName?: string;
|
|
421
|
-
/**
|
|
422
|
-
* Enable interactive legend items that can toggle series visibility.
|
|
423
|
-
* Supported for all chart types that render series.
|
|
424
|
-
* Requires chartId and GlobalChartsProvider.
|
|
425
|
-
* For pie charts, percentages are recalculated so visible segments total 100%.
|
|
464
|
+
* Legend configuration object for controlling legend appearance and behavior.
|
|
465
|
+
* Includes orientation, position, alignment, shape, styling, and interactivity options.
|
|
426
466
|
*/
|
|
427
|
-
|
|
467
|
+
legend?: ChartLegendConfig<T>;
|
|
428
468
|
/**
|
|
429
469
|
* Grid visibility. x is default when orientation is vertical. y is default when orientation is horizontal.
|
|
430
470
|
*/
|
|
@@ -502,4 +542,4 @@ interface ToggleEvent extends Event {
|
|
|
502
542
|
oldState: 'open' | 'closed';
|
|
503
543
|
}
|
|
504
544
|
|
|
505
|
-
export type { AnnotationStyles as A, BaseChartProps as B,
|
|
545
|
+
export type { AnnotationStyles as A, BaseChartProps as B, ChartLegendConfig as C, DataPoint as D, GeoData as G, LeaderboardEntry as L, MultipleDataPointsDate as M, Optional as O, PopoverButtonAttributes as P, ScaleOptions as S, ToggleEvent as T, ButtonWithPopover as a, ChartTheme as b, CompleteChartTheme as c, DataPointDate as d, DataPointPercentage as e, GradientStop as f, GridProps as g, LegendItemStyles as h, LegendLabelStyles as i, LegendPosition as j, LegendShapeStyles as k, OrientationType as l, PopoverElement as m, PopoverElementAttributes as n, SeriesData as o, SeriesDataOptions as p };
|
|
@@ -8,7 +8,7 @@ import { ScaleType, ScaleInput } from '@visx/scale';
|
|
|
8
8
|
import { TextProps } from '@visx/text/lib/Text';
|
|
9
9
|
import { EventHandlerParams, LineStyles, GridStyles, GlyphProps } from '@visx/xychart';
|
|
10
10
|
import { GapSize } from '@wordpress/theme';
|
|
11
|
-
import { PointerEvent,
|
|
11
|
+
import { PointerEvent, CSSProperties, ReactNode } from 'react';
|
|
12
12
|
import { GoogleDataTableColumn, GoogleDataTableRow } from 'react-google-charts';
|
|
13
13
|
|
|
14
14
|
type ValueOf<T> = T[keyof T];
|
|
@@ -322,6 +322,81 @@ type ScaleOptions = {
|
|
|
322
322
|
*/
|
|
323
323
|
paddingOuter?: number;
|
|
324
324
|
};
|
|
325
|
+
type LegendItemStyles = {
|
|
326
|
+
/** Margin around each legend item. */
|
|
327
|
+
margin?: CSSProperties['margin'];
|
|
328
|
+
/** Flex direction for items within each legend entry. */
|
|
329
|
+
flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
330
|
+
};
|
|
331
|
+
type LegendLabelStyles = Pick<CSSProperties, 'justifyContent' | 'flex' | 'margin'> & {
|
|
332
|
+
/**
|
|
333
|
+
* Maximum width for legend label text as a CSS value (e.g. '200px', '50%', '10rem').
|
|
334
|
+
* When set, text overflow behavior is controlled by textOverflow.
|
|
335
|
+
*/
|
|
336
|
+
maxWidth?: string;
|
|
337
|
+
/**
|
|
338
|
+
* Controls how text behaves when it exceeds maxWidth.
|
|
339
|
+
* - 'ellipsis': Truncate with ellipsis (ideal for widgets/small devices)
|
|
340
|
+
* - 'wrap': Wrap text to multiple lines (default, ideal for larger displays)
|
|
341
|
+
*/
|
|
342
|
+
textOverflow?: 'ellipsis' | 'wrap';
|
|
343
|
+
};
|
|
344
|
+
type LegendShapeStyles = {
|
|
345
|
+
/** Width of the legend shape in pixels. */
|
|
346
|
+
width?: number;
|
|
347
|
+
/** Height of the legend shape in pixels. */
|
|
348
|
+
height?: number;
|
|
349
|
+
/** Margin around the legend shape. */
|
|
350
|
+
margin?: CSSProperties['margin'];
|
|
351
|
+
};
|
|
352
|
+
/** Position of the legend relative to chart content. */
|
|
353
|
+
type LegendPosition = 'top' | 'bottom';
|
|
354
|
+
/**
|
|
355
|
+
* Configuration object for chart legend appearance and behavior.
|
|
356
|
+
* Consolidates all legend styling and layout props into a single structured object.
|
|
357
|
+
*/
|
|
358
|
+
type ChartLegendConfig<T = DataPoint | DataPointDate | LeaderboardEntry> = {
|
|
359
|
+
/**
|
|
360
|
+
* Layout direction of legend items.
|
|
361
|
+
*/
|
|
362
|
+
orientation?: 'horizontal' | 'vertical';
|
|
363
|
+
/**
|
|
364
|
+
* Position of the legend relative to the chart.
|
|
365
|
+
* TODO: Add 'left' | 'right' positioning support in future implementation
|
|
366
|
+
*/
|
|
367
|
+
position?: LegendPosition;
|
|
368
|
+
/**
|
|
369
|
+
* Alignment of the legend within its position.
|
|
370
|
+
*/
|
|
371
|
+
alignment?: 'start' | 'center' | 'end';
|
|
372
|
+
/**
|
|
373
|
+
* Shape of the legend marker icon.
|
|
374
|
+
*/
|
|
375
|
+
shape?: LegendShape<T, number>;
|
|
376
|
+
/**
|
|
377
|
+
* Enable interactive legend items that can toggle series visibility.
|
|
378
|
+
* Supported for all chart types that render series.
|
|
379
|
+
* Requires chartId and GlobalChartsProvider.
|
|
380
|
+
* For pie charts, percentages are recalculated so visible segments total 100%.
|
|
381
|
+
*/
|
|
382
|
+
interactive?: boolean;
|
|
383
|
+
/**
|
|
384
|
+
* Additional CSS class name for individual legend items.
|
|
385
|
+
*/
|
|
386
|
+
itemClassName?: string;
|
|
387
|
+
/**
|
|
388
|
+
* CSS styles for each legend item (margin, flexDirection).
|
|
389
|
+
*/
|
|
390
|
+
itemStyles?: LegendItemStyles;
|
|
391
|
+
/**
|
|
392
|
+
* CSS styles for legend labels (maxWidth, textOverflow, justifyContent, flex, margin).
|
|
393
|
+
*/
|
|
394
|
+
labelStyles?: LegendLabelStyles;
|
|
395
|
+
/**
|
|
396
|
+
* Styles for legend shapes (width, height, margin).
|
|
397
|
+
*/
|
|
398
|
+
shapeStyles?: LegendShapeStyles;
|
|
399
|
+
};
|
|
325
400
|
/**
|
|
326
401
|
* Base properties shared across all chart components
|
|
327
402
|
*/
|
|
@@ -386,45 +461,10 @@ type BaseChartProps<T = DataPoint | DataPointDate | LeaderboardEntry> = {
|
|
|
386
461
|
*/
|
|
387
462
|
showLegend?: boolean;
|
|
388
463
|
/**
|
|
389
|
-
* Legend
|
|
390
|
-
|
|
391
|
-
legendOrientation?: 'horizontal' | 'vertical';
|
|
392
|
-
/**
|
|
393
|
-
* Legend shape
|
|
394
|
-
*/
|
|
395
|
-
legendShape?: LegendShape<T, number>;
|
|
396
|
-
/**
|
|
397
|
-
* Legend position (where the legend appears)
|
|
398
|
-
* TODO: Add 'left' | 'right' positioning support in future implementation
|
|
399
|
-
*/
|
|
400
|
-
legendPosition?: 'top' | 'bottom';
|
|
401
|
-
/**
|
|
402
|
-
* Legend alignment within its position
|
|
403
|
-
*/
|
|
404
|
-
legendAlignment?: 'start' | 'center' | 'end';
|
|
405
|
-
/**
|
|
406
|
-
* Maximum width for legend items. When set, text overflow behavior is controlled by legendTextOverflow.
|
|
407
|
-
* Should be a CSS value string (e.g. '200px', '50%', '10rem')
|
|
408
|
-
*/
|
|
409
|
-
legendMaxWidth?: string;
|
|
410
|
-
/**
|
|
411
|
-
* Controls how text behaves when it exceeds legendMaxWidth.
|
|
412
|
-
* - 'ellipsis': Truncate with ellipsis (ideal for widgets/small devices)
|
|
413
|
-
* - 'wrap': Wrap text to multiple lines (default, ideal for larger displays)
|
|
414
|
-
*/
|
|
415
|
-
legendTextOverflow?: 'ellipsis' | 'wrap';
|
|
416
|
-
/**
|
|
417
|
-
* Additional CSS class name for legend items.
|
|
418
|
-
* This allows consumers to customize individual legend item styling.
|
|
419
|
-
*/
|
|
420
|
-
legendItemClassName?: string;
|
|
421
|
-
/**
|
|
422
|
-
* Enable interactive legend items that can toggle series visibility.
|
|
423
|
-
* Supported for all chart types that render series.
|
|
424
|
-
* Requires chartId and GlobalChartsProvider.
|
|
425
|
-
* For pie charts, percentages are recalculated so visible segments total 100%.
|
|
464
|
+
* Legend configuration object for controlling legend appearance and behavior.
|
|
465
|
+
* Includes orientation, position, alignment, shape, styling, and interactivity options.
|
|
426
466
|
*/
|
|
427
|
-
|
|
467
|
+
legend?: ChartLegendConfig<T>;
|
|
428
468
|
/**
|
|
429
469
|
* Grid visibility. x is default when orientation is vertical. y is default when orientation is horizontal.
|
|
430
470
|
*/
|
|
@@ -502,4 +542,4 @@ interface ToggleEvent extends Event {
|
|
|
502
542
|
oldState: 'open' | 'closed';
|
|
503
543
|
}
|
|
504
544
|
|
|
505
|
-
export type { AnnotationStyles as A, BaseChartProps as B,
|
|
545
|
+
export type { AnnotationStyles as A, BaseChartProps as B, ChartLegendConfig as C, DataPoint as D, GeoData as G, LeaderboardEntry as L, MultipleDataPointsDate as M, Optional as O, PopoverButtonAttributes as P, ScaleOptions as S, ToggleEvent as T, ButtonWithPopover as a, ChartTheme as b, CompleteChartTheme as c, DataPointDate as d, DataPointPercentage as e, GradientStop as f, GridProps as g, LegendItemStyles as h, LegendLabelStyles as i, LegendPosition as j, LegendShapeStyles as k, OrientationType as l, PopoverElement as m, PopoverElementAttributes as n, SeriesData as o, SeriesDataOptions as p };
|
|
@@ -1,42 +1,13 @@
|
|
|
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
6
|
type VisxLegendProps = Pick<ComponentProps<typeof LegendOrdinal>, 'className' | 'shape' | 'fill' | 'size' | 'labelFormat' | 'labelTransform'>;
|
|
6
|
-
type LegendItemStyles = {
|
|
7
|
-
/** Margin around each legend item. */
|
|
8
|
-
margin?: CSSProperties['margin'];
|
|
9
|
-
/** Flex direction for items within each legend entry. */
|
|
10
|
-
flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
11
|
-
};
|
|
12
|
-
type LegendLabelStyles = Pick<CSSProperties, 'justifyContent' | 'flex' | 'margin'> & {
|
|
13
|
-
/**
|
|
14
|
-
* Maximum width for legend label text as a CSS value (e.g. '200px', '50%', '10rem').
|
|
15
|
-
* When set, text overflow behavior is controlled by textOverflow.
|
|
16
|
-
*/
|
|
17
|
-
maxWidth?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Controls how text behaves when it exceeds maxWidth.
|
|
20
|
-
* - 'ellipsis': Truncate with ellipsis (ideal for widgets/small devices)
|
|
21
|
-
* - 'wrap': Wrap text to multiple lines (default, ideal for larger displays)
|
|
22
|
-
*/
|
|
23
|
-
textOverflow?: 'ellipsis' | 'wrap';
|
|
24
|
-
};
|
|
25
|
-
type LegendShapeStyles = {
|
|
26
|
-
/** Width of the legend shape in pixels. */
|
|
27
|
-
width?: number;
|
|
28
|
-
/** Height of the legend shape in pixels. */
|
|
29
|
-
height?: number;
|
|
30
|
-
/** Margin around the legend shape. */
|
|
31
|
-
margin?: CSSProperties['margin'];
|
|
32
|
-
};
|
|
33
7
|
type BaseLegendProps = VisxLegendProps & {
|
|
34
8
|
items: BaseLegendItem[];
|
|
35
9
|
orientation?: 'horizontal' | 'vertical';
|
|
36
|
-
|
|
37
|
-
* TODO: Add 'left' | 'right' positioning support in future implementation
|
|
38
|
-
*/
|
|
39
|
-
position?: 'top' | 'bottom';
|
|
10
|
+
position?: LegendPosition;
|
|
40
11
|
alignment?: 'start' | 'center' | 'end';
|
|
41
12
|
/** Additional CSS class name for legend items. */
|
|
42
13
|
itemClassName?: string;
|
|
@@ -75,4 +46,4 @@ type BaseLegendItem = {
|
|
|
75
46
|
shapeStyle?: CSSProperties & LineStyles;
|
|
76
47
|
};
|
|
77
48
|
|
|
78
|
-
export type { BaseLegendItem as B,
|
|
49
|
+
export type { BaseLegendItem as B, LegendProps as L, BaseLegendProps as a };
|
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": {
|
|
@@ -180,7 +180,7 @@
|
|
|
180
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",
|
|
@@ -226,8 +226,8 @@
|
|
|
226
226
|
"@types/react-dom": "18.3.7",
|
|
227
227
|
"@typescript/native-preview": "7.0.0-dev.20260225.1",
|
|
228
228
|
"@visx/glyph": "3.12.0",
|
|
229
|
-
"@wordpress/components": "32.
|
|
230
|
-
"@wordpress/element": "6.
|
|
229
|
+
"@wordpress/components": "32.3.0",
|
|
230
|
+
"@wordpress/element": "6.41.0",
|
|
231
231
|
"babel-jest": "30.2.0",
|
|
232
232
|
"babel-plugin-react-remove-properties": "^0.3.1",
|
|
233
233
|
"esbuild": "0.25.9",
|
|
@@ -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 );
|
|
@@ -123,8 +116,9 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
123
116
|
const [ svgWrapperRef, , svgWrapperHeight ] = useElementSize< HTMLDivElement >();
|
|
124
117
|
const chartRef = useRef< HTMLDivElement >( null );
|
|
125
118
|
|
|
126
|
-
//
|
|
127
|
-
const
|
|
119
|
+
// Process children for composition API (Legend, etc.)
|
|
120
|
+
const { legendChildren, nonLegendChildren } = useChartChildren( children, 'BarChart' );
|
|
121
|
+
const hasLegendChild = legendChildren.length > 0;
|
|
128
122
|
|
|
129
123
|
// Use the measured SVG wrapper height, falling back to the passed height if provided.
|
|
130
124
|
// When there's a legend (via prop or composition), we must wait for measurement because
|
|
@@ -327,15 +321,18 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
327
321
|
const gridVisibility = gridVisibilityProp ?? chartOptions.gridVisibility;
|
|
328
322
|
const highlightedBarStyle = createKeyboardHighlightStyle();
|
|
329
323
|
|
|
324
|
+
const legendPosition = legend.position ?? 'bottom';
|
|
330
325
|
const legendElement = showLegend && (
|
|
331
326
|
<Legend
|
|
332
|
-
orientation={
|
|
327
|
+
orientation={ legend.orientation ?? 'horizontal' }
|
|
333
328
|
position={ legendPosition }
|
|
334
|
-
alignment={
|
|
335
|
-
labelStyles={
|
|
336
|
-
itemClassName={
|
|
329
|
+
alignment={ legend.alignment ?? 'center' }
|
|
330
|
+
labelStyles={ legend.labelStyles }
|
|
331
|
+
itemClassName={ legend.itemClassName }
|
|
332
|
+
itemStyles={ legend.itemStyles }
|
|
333
|
+
shapeStyles={ legend.shapeStyles }
|
|
337
334
|
className={ styles[ 'bar-chart__legend' ] }
|
|
338
|
-
shape={
|
|
335
|
+
shape={ legend.shape ?? 'rect' }
|
|
339
336
|
chartId={ chartId }
|
|
340
337
|
interactive={ legendInteractive }
|
|
341
338
|
/>
|
|
@@ -370,6 +367,7 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
370
367
|
data-chart-id={ `bar-chart-${ chartId }` }
|
|
371
368
|
>
|
|
372
369
|
{ legendPosition === 'top' && legendElement }
|
|
370
|
+
{ renderLegendSlot( legendChildren, 'top' ) }
|
|
373
371
|
|
|
374
372
|
<div
|
|
375
373
|
className={ styles[ 'bar-chart__svg-wrapper' ] }
|
|
@@ -483,8 +481,9 @@ const BarChartInternal: FC< BarChartProps > = ( {
|
|
|
483
481
|
</div>
|
|
484
482
|
|
|
485
483
|
{ legendPosition === 'bottom' && legendElement }
|
|
484
|
+
{ renderLegendSlot( legendChildren, 'bottom' ) }
|
|
486
485
|
|
|
487
|
-
{
|
|
486
|
+
{ nonLegendChildren }
|
|
488
487
|
</Stack>
|
|
489
488
|
</SingleChartContext.Provider>
|
|
490
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', () => {
|
|
@@ -743,7 +760,7 @@ describe( 'BarChart', () => {
|
|
|
743
760
|
|
|
744
761
|
renderWithTheme( {
|
|
745
762
|
showLegend: true,
|
|
746
|
-
|
|
763
|
+
legend: { interactive: true },
|
|
747
764
|
chartId: 'test-interactive-bar-chart',
|
|
748
765
|
data: [
|
|
749
766
|
{
|
|
@@ -771,7 +788,7 @@ describe( 'BarChart', () => {
|
|
|
771
788
|
it( 'does not filter series when legendInteractive is false', () => {
|
|
772
789
|
renderWithTheme( {
|
|
773
790
|
showLegend: true,
|
|
774
|
-
|
|
791
|
+
legend: { interactive: false },
|
|
775
792
|
chartId: 'test-non-interactive-bar-chart',
|
|
776
793
|
data: [
|
|
777
794
|
{
|
|
@@ -795,7 +812,7 @@ describe( 'BarChart', () => {
|
|
|
795
812
|
it( 'shows all series when chartId is missing even if legendInteractive is true', () => {
|
|
796
813
|
renderWithTheme( {
|
|
797
814
|
showLegend: true,
|
|
798
|
-
|
|
815
|
+
legend: { interactive: true },
|
|
799
816
|
// No chartId provided
|
|
800
817
|
data: [
|
|
801
818
|
{
|
|
@@ -823,7 +840,7 @@ describe( 'BarChart', () => {
|
|
|
823
840
|
|
|
824
841
|
renderWithTheme( {
|
|
825
842
|
showLegend: true,
|
|
826
|
-
|
|
843
|
+
legend: { interactive: true },
|
|
827
844
|
chartId: 'test-all-hidden-bar-chart',
|
|
828
845
|
data: [
|
|
829
846
|
{
|