@react-magma/charts 13.0.4-next.0 → 14.0.0-next.1
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/dist/charts.js +447 -27
- package/dist/charts.js.map +1 -1
- package/dist/charts.modern.module.js +443 -30
- package/dist/charts.modern.module.js.map +1 -1
- package/dist/charts.umd.js +1303 -153
- package/dist/charts.umd.js.map +1 -1
- package/dist/components/CarbonChart/CarbonChart.d.ts +41 -0
- package/dist/components/ChartTable/ChartDataTable.d.ts +19 -0
- package/dist/components/ChartTable/ChartFullscreenButton.d.ts +26 -0
- package/dist/components/ChartTable/ChartMoreOptionsButton.d.ts +18 -0
- package/dist/components/ChartTable/ChartTable.stories.d.ts +116 -0
- package/dist/components/ChartTable/ChartTable.test.d.ts +1 -0
- package/dist/components/ChartTable/ChartTableButton.d.ts +24 -0
- package/dist/components/ChartTable/ChartTableModal.d.ts +44 -0
- package/dist/components/ChartTable/ChartToolbar.d.ts +19 -0
- package/dist/components/ChartTable/chartToolbarI18n.d.ts +16 -0
- package/dist/components/ChartTable/index.d.ts +14 -0
- package/dist/components/LineChart/DataTable.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +5 -5
- package/src/components/CarbonChart/CarbonChart.test.js +143 -2
- package/src/components/CarbonChart/CarbonChart.tsx +603 -15
- package/src/components/ChartTable/ChartDataTable.tsx +72 -0
- package/src/components/ChartTable/ChartFullscreenButton.tsx +59 -0
- package/src/components/ChartTable/ChartMoreOptionsButton.tsx +47 -0
- package/src/components/ChartTable/ChartTable.stories.tsx +152 -0
- package/src/components/ChartTable/ChartTable.test.tsx +444 -0
- package/src/components/ChartTable/ChartTableButton.tsx +55 -0
- package/src/components/ChartTable/ChartTableModal.tsx +135 -0
- package/src/components/ChartTable/ChartToolbar.tsx +50 -0
- package/src/components/ChartTable/chartToolbarI18n.ts +55 -0
- package/src/components/ChartTable/index.ts +23 -0
- package/src/components/LineChart/DataTable.tsx +3 -3
- package/src/components/LineChart/LineChart.tsx +1 -1
- package/src/index.ts +1 -0
|
@@ -2,6 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { ChartOptions } from '@carbon/charts-react';
|
|
3
3
|
import { ThemeInterface } from 'react-magma-dom';
|
|
4
4
|
import './carbon-charts.css';
|
|
5
|
+
import type { ChartDataTableColumn } from '../ChartTable';
|
|
5
6
|
export declare enum CarbonChartType {
|
|
6
7
|
area = "area",
|
|
7
8
|
areaStacked = "areaStacked",
|
|
@@ -22,6 +23,40 @@ export declare enum CarbonChartType {
|
|
|
22
23
|
scatter = "scatter",
|
|
23
24
|
combo = "combo"
|
|
24
25
|
}
|
|
26
|
+
export interface ChartToolbarConfig {
|
|
27
|
+
/**
|
|
28
|
+
* When true, renders a "Show as table" button that opens a Magma Modal
|
|
29
|
+
* with the chart data in an accessible table.
|
|
30
|
+
* @default true
|
|
31
|
+
*/
|
|
32
|
+
showAsTable?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* When true, renders a fullscreen toggle button.
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
fullscreen?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Additional menu items rendered inside a "More options" dropdown,
|
|
40
|
+
* below the built-in "Download as CSV", "Download as PNG", and "Download as JPG" items.
|
|
41
|
+
* Pass DropdownMenuItem elements.
|
|
42
|
+
*/
|
|
43
|
+
moreOptions?: React.ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* Custom column definitions for the table modal.
|
|
46
|
+
* If omitted, columns are auto-derived from the dataset object keys.
|
|
47
|
+
*/
|
|
48
|
+
tableColumns?: ChartDataTableColumn[];
|
|
49
|
+
/**
|
|
50
|
+
* First line of the modal heading.
|
|
51
|
+
* @default "Tabular representation"
|
|
52
|
+
*/
|
|
53
|
+
tableHeaderLabel?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Heading level for the modal header.
|
|
56
|
+
* @default 2
|
|
57
|
+
*/
|
|
58
|
+
tableHeaderLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
59
|
+
}
|
|
25
60
|
export interface CarbonChartProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
26
61
|
dataSet: Array<Object>;
|
|
27
62
|
isInverse?: boolean;
|
|
@@ -42,5 +77,11 @@ export interface CarbonChartProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
42
77
|
* Text for the aria-label attribute for main SVG container, if provided
|
|
43
78
|
*/
|
|
44
79
|
ariaLabel?: string;
|
|
80
|
+
/**
|
|
81
|
+
* When provided, renders an accessible Magma toolbar above the chart with
|
|
82
|
+
* "Show as table", fullscreen, and "More options" buttons. Carbon's built-in
|
|
83
|
+
* toolbar is automatically disabled.
|
|
84
|
+
*/
|
|
85
|
+
chartToolbar?: ChartToolbarConfig;
|
|
45
86
|
}
|
|
46
87
|
export declare const CarbonChart: React.ForwardRefExoticComponent<CarbonChartProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface ChartDataTableColumn {
|
|
3
|
+
/** Header text for this column */
|
|
4
|
+
header: string;
|
|
5
|
+
/** Key to read from each row object */
|
|
6
|
+
key: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ChartDataTableProps {
|
|
9
|
+
/** Column definitions (header + key). If omitted, columns are auto-derived from the dataset object keys with the first character capitalized (e.g. "group" → "Group"). */
|
|
10
|
+
columns?: ChartDataTableColumn[];
|
|
11
|
+
/** Array of data objects. Each object should have keys matching the column `key` values. */
|
|
12
|
+
dataSet: Array<Record<string, React.ReactNode>>;
|
|
13
|
+
/**
|
|
14
|
+
* If true, the table uses inverse (dark) styling.
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
isInverse?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function ChartDataTable({ columns, dataSet, isInverse, }: ChartDataTableProps): React.JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface ChartFullscreenButtonProps {
|
|
3
|
+
/** Accessible label for the button, e.g. "View Overall Performance in full screen" */
|
|
4
|
+
ariaLabel: string;
|
|
5
|
+
/** Icon rendered when not in fullscreen mode */
|
|
6
|
+
icon: React.ReactElement;
|
|
7
|
+
/** Icon rendered when in fullscreen mode. Falls back to `icon` if omitted. */
|
|
8
|
+
exitIcon?: React.ReactElement;
|
|
9
|
+
/**
|
|
10
|
+
* If true, the button uses inverse (dark) styling.
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
isInverse?: boolean;
|
|
14
|
+
/** Whether the chart is currently in fullscreen mode */
|
|
15
|
+
isFullscreen: boolean;
|
|
16
|
+
/** Click handler – should toggle fullscreen */
|
|
17
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
18
|
+
/** Optional ref forwarded to the underlying IconButton */
|
|
19
|
+
buttonRef?: React.Ref<HTMLButtonElement>;
|
|
20
|
+
/**
|
|
21
|
+
* Tooltip text shown on hover.
|
|
22
|
+
* @default "Make full screen" / "Exit full screen" based on state (i18n overridable)
|
|
23
|
+
*/
|
|
24
|
+
tooltipContent?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function ChartFullscreenButton({ ariaLabel, buttonRef, exitIcon, icon, isInverse, isFullscreen, onClick, tooltipContent, }: ChartFullscreenButtonProps): React.JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface ChartMoreOptionsButtonProps {
|
|
3
|
+
/**
|
|
4
|
+
* Accessible label for the trigger button.
|
|
5
|
+
* @default "More options" (i18n overridable)
|
|
6
|
+
*/
|
|
7
|
+
ariaLabel?: string;
|
|
8
|
+
/** Menu items rendered inside the dropdown (DropdownMenuItem, DropdownDivider, etc.) */
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
/** Icon element rendered inside the trigger button */
|
|
11
|
+
icon: React.ReactElement;
|
|
12
|
+
/**
|
|
13
|
+
* If true, the dropdown uses inverse (dark) styling.
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
isInverse?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function ChartMoreOptionsButton({ ariaLabel, children, icon, isInverse, }: ChartMoreOptionsButtonProps): React.JSX.Element;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { CarbonChartProps, CarbonChartType } from '../CarbonChart';
|
|
2
|
+
declare const _default: import("@storybook/csf").ComponentAnnotations<import("@storybook/react/types-6-0").ReactFramework, import("@storybook/react/types-6-0").Args>;
|
|
3
|
+
export default _default;
|
|
4
|
+
export declare const DonutWithToolbar: {
|
|
5
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps>;
|
|
6
|
+
args: {
|
|
7
|
+
isInverse: boolean;
|
|
8
|
+
type: CarbonChartType;
|
|
9
|
+
dataSet: {
|
|
10
|
+
group: string;
|
|
11
|
+
value: number;
|
|
12
|
+
}[];
|
|
13
|
+
options: {
|
|
14
|
+
title: string;
|
|
15
|
+
resizable: boolean;
|
|
16
|
+
height: string;
|
|
17
|
+
donut: {
|
|
18
|
+
center: {
|
|
19
|
+
label: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
legend: {
|
|
23
|
+
truncation: {
|
|
24
|
+
type: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
chartToolbar: {};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export declare const BarWithToolbar: {
|
|
32
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps>;
|
|
33
|
+
args: {
|
|
34
|
+
isInverse: boolean;
|
|
35
|
+
type: CarbonChartType;
|
|
36
|
+
dataSet: {
|
|
37
|
+
group: string;
|
|
38
|
+
value: number;
|
|
39
|
+
}[];
|
|
40
|
+
options: {
|
|
41
|
+
title: string;
|
|
42
|
+
axes: {
|
|
43
|
+
left: {
|
|
44
|
+
mapsTo: string;
|
|
45
|
+
};
|
|
46
|
+
bottom: {
|
|
47
|
+
mapsTo: string;
|
|
48
|
+
scaleType: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
height: string;
|
|
52
|
+
};
|
|
53
|
+
chartToolbar: {
|
|
54
|
+
tableColumns: {
|
|
55
|
+
header: string;
|
|
56
|
+
key: string;
|
|
57
|
+
}[];
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export declare const InverseTheme: {
|
|
62
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps>;
|
|
63
|
+
args: {
|
|
64
|
+
isInverse: boolean;
|
|
65
|
+
type: CarbonChartType;
|
|
66
|
+
dataSet: {
|
|
67
|
+
group: string;
|
|
68
|
+
value: number;
|
|
69
|
+
}[];
|
|
70
|
+
options: {
|
|
71
|
+
title: string;
|
|
72
|
+
resizable: boolean;
|
|
73
|
+
height: string;
|
|
74
|
+
donut: {
|
|
75
|
+
center: {
|
|
76
|
+
label: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
legend: {
|
|
80
|
+
truncation: {
|
|
81
|
+
type: string;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
chartToolbar: {};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
export declare const TableOnly: {
|
|
89
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps>;
|
|
90
|
+
args: {
|
|
91
|
+
isInverse: boolean;
|
|
92
|
+
type: CarbonChartType;
|
|
93
|
+
dataSet: {
|
|
94
|
+
group: string;
|
|
95
|
+
value: number;
|
|
96
|
+
}[];
|
|
97
|
+
options: {
|
|
98
|
+
title: string;
|
|
99
|
+
resizable: boolean;
|
|
100
|
+
height: string;
|
|
101
|
+
donut: {
|
|
102
|
+
center: {
|
|
103
|
+
label: string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
legend: {
|
|
107
|
+
truncation: {
|
|
108
|
+
type: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
chartToolbar: {
|
|
113
|
+
fullscreen: boolean;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface ChartTableButtonProps {
|
|
3
|
+
/** Accessible label for the button – should describe the chart, e.g. "Overall Performance" */
|
|
4
|
+
ariaLabel: string;
|
|
5
|
+
/** Icon element rendered inside the button */
|
|
6
|
+
icon: React.ReactElement;
|
|
7
|
+
/**
|
|
8
|
+
* If true, the button uses inverse (dark) styling.
|
|
9
|
+
* @default false
|
|
10
|
+
*/
|
|
11
|
+
isInverse?: boolean;
|
|
12
|
+
/** Whether the associated modal is currently open */
|
|
13
|
+
isTableOpen: boolean;
|
|
14
|
+
/** Click handler – should open the modal */
|
|
15
|
+
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
16
|
+
/** Optional ref forwarded to the underlying IconButton */
|
|
17
|
+
buttonRef?: React.Ref<HTMLButtonElement>;
|
|
18
|
+
/**
|
|
19
|
+
* Tooltip text shown on hover.
|
|
20
|
+
* @default "Show as table" (i18n overridable)
|
|
21
|
+
*/
|
|
22
|
+
tooltipContent?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function ChartTableButton({ ariaLabel, buttonRef, icon, isInverse, isTableOpen, onClick, tooltipContent, }: ChartTableButtonProps): React.JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ModalSize } from 'react-magma-dom';
|
|
3
|
+
import { ChartDataTableColumn } from './ChartDataTable';
|
|
4
|
+
export interface ChartTableModalProps {
|
|
5
|
+
/** The chart's data passed to ChartDataTable */
|
|
6
|
+
dataSet: Array<Record<string, React.ReactNode>>;
|
|
7
|
+
/** Column definitions forwarded to ChartDataTable */
|
|
8
|
+
columns?: ChartDataTableColumn[];
|
|
9
|
+
/**
|
|
10
|
+
* DOM element to portal the modal into. Defaults to `document.body`.
|
|
11
|
+
* When the chart is in fullscreen, pass the fullscreen element so the
|
|
12
|
+
* modal renders inside it and is visible to the browser.
|
|
13
|
+
*/
|
|
14
|
+
portalContainer?: HTMLElement | null;
|
|
15
|
+
/**
|
|
16
|
+
* If true, the modal uses inverse (dark) styling.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
isInverse?: boolean;
|
|
20
|
+
/** Whether the modal is open */
|
|
21
|
+
isOpen: boolean;
|
|
22
|
+
/** Called when the modal requests to close */
|
|
23
|
+
onClose: () => void;
|
|
24
|
+
/** Called when the "Download as CSV" footer button is clicked */
|
|
25
|
+
onDownloadCsv?: () => void;
|
|
26
|
+
/** Chart title – displayed as a second line in the modal heading */
|
|
27
|
+
title: string;
|
|
28
|
+
/**
|
|
29
|
+
* Heading level for the modal header (1–6).
|
|
30
|
+
* @default 2
|
|
31
|
+
*/
|
|
32
|
+
headerLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
33
|
+
/**
|
|
34
|
+
* First line of the modal heading.
|
|
35
|
+
* @default "Tabular representation" (i18n overridable)
|
|
36
|
+
*/
|
|
37
|
+
headerLabel?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Magma Modal size.
|
|
40
|
+
* @default ModalSize.large
|
|
41
|
+
*/
|
|
42
|
+
size?: ModalSize;
|
|
43
|
+
}
|
|
44
|
+
export declare function ChartTableModal({ columns, portalContainer, dataSet, headerLabel, headerLevel, isInverse, isOpen, onClose, onDownloadCsv, size, title, }: ChartTableModalProps): React.JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TypographyVisualStyle } from 'react-magma-dom';
|
|
3
|
+
export interface ChartToolbarProps {
|
|
4
|
+
/** Toolbar action buttons (ChartTableButton, ChartFullscreenButton, ChartMoreOptionsButton, etc.) */
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
/**
|
|
7
|
+
* Heading level for the chart title.
|
|
8
|
+
* @default 3
|
|
9
|
+
*/
|
|
10
|
+
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
11
|
+
/**
|
|
12
|
+
* Visual style for the heading.
|
|
13
|
+
* @default TypographyVisualStyle.headingSmall
|
|
14
|
+
*/
|
|
15
|
+
headingVisualStyle?: TypographyVisualStyle;
|
|
16
|
+
/** Chart title text */
|
|
17
|
+
title: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function ChartToolbar({ children, headingLevel, headingVisualStyle, title, }: ChartToolbarProps): React.JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ChartToolbarI18n {
|
|
2
|
+
defaultTitle: string;
|
|
3
|
+
downloadAsCsv: string;
|
|
4
|
+
downloadAsJpg: string;
|
|
5
|
+
downloadAsPng: string;
|
|
6
|
+
exitFullScreen: string;
|
|
7
|
+
makeFullScreen: string;
|
|
8
|
+
moreOptionsAriaLabel: string;
|
|
9
|
+
showAsTableTooltip: string;
|
|
10
|
+
tabularRepresentationLabel: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Reads chart toolbar i18n strings from the I18nContext if available,
|
|
14
|
+
* falling back to English defaults.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useChartToolbarI18n(): ChartToolbarI18n;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { ChartDataTable } from './ChartDataTable';
|
|
2
|
+
export type { ChartDataTableProps, ChartDataTableColumn, } from './ChartDataTable';
|
|
3
|
+
export { ChartFullscreenButton } from './ChartFullscreenButton';
|
|
4
|
+
export type { ChartFullscreenButtonProps } from './ChartFullscreenButton';
|
|
5
|
+
export { ChartMoreOptionsButton } from './ChartMoreOptionsButton';
|
|
6
|
+
export type { ChartMoreOptionsButtonProps } from './ChartMoreOptionsButton';
|
|
7
|
+
export { ChartTableButton } from './ChartTableButton';
|
|
8
|
+
export type { ChartTableButtonProps } from './ChartTableButton';
|
|
9
|
+
export { ChartTableModal } from './ChartTableModal';
|
|
10
|
+
export type { ChartTableModalProps } from './ChartTableModal';
|
|
11
|
+
export { ChartToolbar } from './ChartToolbar';
|
|
12
|
+
export type { ChartToolbarProps } from './ChartToolbar';
|
|
13
|
+
export { useChartToolbarI18n } from './chartToolbarI18n';
|
|
14
|
+
export type { ChartToolbarI18n } from './chartToolbarI18n';
|
package/dist/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-magma/charts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0-next.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"identity-obj-proxy": "^3.0.0",
|
|
48
48
|
"react": "^17.0.2",
|
|
49
49
|
"react-dom": "^17.0.2",
|
|
50
|
-
"react-magma-dom": "^4.
|
|
51
|
-
"react-magma-icons": "^3.2.
|
|
50
|
+
"react-magma-dom": "^4.13.0-next.2",
|
|
51
|
+
"react-magma-icons": "^3.2.5",
|
|
52
52
|
"rollup": "^4.52.4",
|
|
53
53
|
"rollup-plugin-postcss": "^4.0.2"
|
|
54
54
|
},
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"@emotion/styled": "^11.13.0",
|
|
58
58
|
"react": "^17.0.2",
|
|
59
59
|
"react-dom": "^17.0.2",
|
|
60
|
-
"react-magma-dom": "^4.
|
|
61
|
-
"react-magma-icons": "^3.2.
|
|
60
|
+
"react-magma-dom": "^4.13.0-next.2",
|
|
61
|
+
"react-magma-icons": "^3.2.5"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22.14.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { act, render } from '@testing-library/react';
|
|
4
|
-
import { ThemeContext, magma } from 'react-magma-dom';
|
|
3
|
+
import { act, render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
+
import { ThemeContext, magma, DropdownMenuItem } from 'react-magma-dom';
|
|
5
5
|
|
|
6
6
|
import { CarbonChart, CarbonChartType } from '.';
|
|
7
7
|
|
|
@@ -754,4 +754,145 @@ describe('CarbonChart', () => {
|
|
|
754
754
|
expect(document.activeElement).toBe(closeButton);
|
|
755
755
|
});
|
|
756
756
|
});
|
|
757
|
+
|
|
758
|
+
describe('chartToolbar prop', () => {
|
|
759
|
+
const toolbarProps = {
|
|
760
|
+
dataSet,
|
|
761
|
+
options: chartOptions,
|
|
762
|
+
type: CarbonChartType.bar,
|
|
763
|
+
chartToolbar: {},
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
it('should render the show-as-table button with aria-haspopup="dialog"', () => {
|
|
767
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
768
|
+
|
|
769
|
+
const button = screen.getByRole('button', {
|
|
770
|
+
name: chartOptions.title,
|
|
771
|
+
});
|
|
772
|
+
expect(button).toHaveAttribute('aria-haspopup', 'dialog');
|
|
773
|
+
expect(button).toHaveAttribute('aria-expanded', 'false');
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
it('should render the fullscreen button without aria-haspopup', () => {
|
|
777
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
778
|
+
|
|
779
|
+
const button = screen.getByRole('button', {
|
|
780
|
+
name: `View ${chartOptions.title} full screen`,
|
|
781
|
+
});
|
|
782
|
+
expect(button).not.toHaveAttribute('aria-haspopup');
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
it('should open the table modal when show-as-table button is clicked', () => {
|
|
786
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
787
|
+
|
|
788
|
+
fireEvent.click(screen.getByRole('button', { name: chartOptions.title }));
|
|
789
|
+
|
|
790
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
791
|
+
expect(
|
|
792
|
+
screen.getByRole('heading', {
|
|
793
|
+
level: 2,
|
|
794
|
+
name: `Tabular representation ${chartOptions.title}`,
|
|
795
|
+
})
|
|
796
|
+
).toBeInTheDocument();
|
|
797
|
+
expect(
|
|
798
|
+
screen.getByRole('columnheader', { name: 'Group' })
|
|
799
|
+
).toBeInTheDocument();
|
|
800
|
+
expect(
|
|
801
|
+
screen.getByRole('columnheader', { name: 'Value' })
|
|
802
|
+
).toBeInTheDocument();
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
it('should render chart data in the table modal', () => {
|
|
806
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
807
|
+
|
|
808
|
+
fireEvent.click(screen.getByRole('button', { name: chartOptions.title }));
|
|
809
|
+
|
|
810
|
+
expect(screen.getByRole('cell', { name: 'Qty' })).toBeInTheDocument();
|
|
811
|
+
expect(screen.getByRole('cell', { name: '65000' })).toBeInTheDocument();
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
it('should set aria-expanded to true when modal is open', () => {
|
|
815
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
816
|
+
|
|
817
|
+
const tableButton = screen.getByRole('button', {
|
|
818
|
+
name: chartOptions.title,
|
|
819
|
+
});
|
|
820
|
+
fireEvent.click(tableButton);
|
|
821
|
+
|
|
822
|
+
expect(tableButton).toHaveAttribute('aria-expanded', 'true');
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
it('should not render the table button when showAsTable is false', () => {
|
|
826
|
+
render(
|
|
827
|
+
<CarbonChart {...toolbarProps} chartToolbar={{ showAsTable: false }} />
|
|
828
|
+
);
|
|
829
|
+
|
|
830
|
+
expect(
|
|
831
|
+
screen.queryByRole('button', { name: chartOptions.title })
|
|
832
|
+
).not.toBeInTheDocument();
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it('should not render the fullscreen button when fullscreen is false', () => {
|
|
836
|
+
render(
|
|
837
|
+
<CarbonChart {...toolbarProps} chartToolbar={{ fullscreen: false }} />
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
expect(
|
|
841
|
+
screen.queryByRole('button', { name: /full screen/i })
|
|
842
|
+
).not.toBeInTheDocument();
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
it('should always render the more options dropdown with built-in download items', () => {
|
|
846
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
847
|
+
|
|
848
|
+
const moreBtn = screen.getByRole('button', { name: 'More options' });
|
|
849
|
+
expect(moreBtn).toBeInTheDocument();
|
|
850
|
+
|
|
851
|
+
fireEvent.click(moreBtn);
|
|
852
|
+
expect(screen.getByText('Download as CSV')).toBeVisible();
|
|
853
|
+
expect(screen.getByText('Download as PNG')).toBeVisible();
|
|
854
|
+
expect(screen.getByText('Download as JPG')).toBeVisible();
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
it('should render additional moreOptions items below built-in downloads', () => {
|
|
858
|
+
render(
|
|
859
|
+
<CarbonChart
|
|
860
|
+
{...toolbarProps}
|
|
861
|
+
chartToolbar={{
|
|
862
|
+
moreOptions: <DropdownMenuItem>Custom Action</DropdownMenuItem>,
|
|
863
|
+
}}
|
|
864
|
+
/>
|
|
865
|
+
);
|
|
866
|
+
|
|
867
|
+
const moreBtn = screen.getByRole('button', { name: 'More options' });
|
|
868
|
+
fireEvent.click(moreBtn);
|
|
869
|
+
expect(screen.getByText('Download as CSV')).toBeVisible();
|
|
870
|
+
expect(screen.getByText('Download as PNG')).toBeVisible();
|
|
871
|
+
expect(screen.getByText('Download as JPG')).toBeVisible();
|
|
872
|
+
expect(screen.getByText('Custom Action')).toBeVisible();
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
it('should support custom table columns', () => {
|
|
876
|
+
render(
|
|
877
|
+
<CarbonChart
|
|
878
|
+
{...toolbarProps}
|
|
879
|
+
chartToolbar={{
|
|
880
|
+
tableColumns: [
|
|
881
|
+
{ header: 'Category', key: 'group' },
|
|
882
|
+
{ header: 'Count', key: 'value' },
|
|
883
|
+
],
|
|
884
|
+
}}
|
|
885
|
+
/>
|
|
886
|
+
);
|
|
887
|
+
|
|
888
|
+
fireEvent.click(screen.getByRole('button', { name: chartOptions.title }));
|
|
889
|
+
|
|
890
|
+
expect(
|
|
891
|
+
screen.getByRole('columnheader', { name: 'Category' })
|
|
892
|
+
).toBeInTheDocument();
|
|
893
|
+
expect(
|
|
894
|
+
screen.getByRole('columnheader', { name: 'Count' })
|
|
895
|
+
).toBeInTheDocument();
|
|
896
|
+
});
|
|
897
|
+
});
|
|
757
898
|
});
|