@react-magma/charts 13.1.1-next.0 → 13.2.0-next.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/dist/charts.js +224 -115
- package/dist/charts.js.map +1 -1
- package/dist/charts.modern.module.js +224 -115
- package/dist/charts.modern.module.js.map +1 -1
- package/dist/charts.umd.js +574 -293
- package/dist/charts.umd.js.map +1 -1
- package/dist/components/CarbonChart/CarbonChart.d.ts +5 -0
- package/dist/components/CarbonChart/CarbonChartBar.stories.d.ts +27 -9
- package/package.json +3 -3
- package/src/components/CarbonChart/CarbonChart.test.js +185 -0
- package/src/components/CarbonChart/CarbonChart.tsx +262 -120
- package/src/components/CarbonChart/CarbonChartArea.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartAreaStacked.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartBar.stories.tsx +9 -2
- package/src/components/CarbonChart/CarbonChartBarFloating.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartBarGrouped.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartBarStacked.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartBoxplot.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartBubble.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartBullet.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartCombo.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartDonut.stories.tsx +3 -1
- package/src/components/CarbonChart/CarbonChartGauge.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartHistogram.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartLine.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartLollipop.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartMeter.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartPie.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartRadar.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartScatter.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartSparkline.stories.tsx +1 -1
- package/src/components/CarbonChart/CarbonChartStep.stories.tsx +1 -1
- package/src/components/ChartTable/ChartMoreOptionsButton.tsx +1 -0
- package/dist/components/ChartTable/ChartTable.test.d.ts +0 -1
- /package/src/components/ChartTable/{ChartTable.test.tsx → ChartTable.test.js} +0 -0
|
@@ -56,6 +56,11 @@ export interface ChartToolbarConfig {
|
|
|
56
56
|
* @default 2
|
|
57
57
|
*/
|
|
58
58
|
tableHeaderLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
59
|
+
/**
|
|
60
|
+
* Heading level for the chart title.
|
|
61
|
+
* @default 2
|
|
62
|
+
*/
|
|
63
|
+
titleLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
59
64
|
}
|
|
60
65
|
export interface CarbonChartProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
61
66
|
dataSet: Array<Object>;
|
|
@@ -2,7 +2,9 @@ import { CarbonChartProps, CarbonChartType } from '.';
|
|
|
2
2
|
declare const _default: import("@storybook/csf").ComponentAnnotations<import("@storybook/react/types-6-0").ReactFramework, import("@storybook/react/types-6-0").Args>;
|
|
3
3
|
export default _default;
|
|
4
4
|
export declare const VerticalSimpleBarDiscrete: {
|
|
5
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
5
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
6
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
7
|
+
}>;
|
|
6
8
|
args: {
|
|
7
9
|
isInverse: boolean;
|
|
8
10
|
type: CarbonChartType;
|
|
@@ -30,7 +32,9 @@ export declare const VerticalSimpleBarDiscrete: {
|
|
|
30
32
|
};
|
|
31
33
|
};
|
|
32
34
|
export declare const VerticalSimpleBarTimeSeries: {
|
|
33
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
35
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
36
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
37
|
+
}>;
|
|
34
38
|
args: {
|
|
35
39
|
isInverse: boolean;
|
|
36
40
|
type: CarbonChartType;
|
|
@@ -55,7 +59,9 @@ export declare const VerticalSimpleBarTimeSeries: {
|
|
|
55
59
|
};
|
|
56
60
|
};
|
|
57
61
|
export declare const VerticalSimpleBarTimeSeriesDenseDataTurkish: {
|
|
58
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
62
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
63
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
64
|
+
}>;
|
|
59
65
|
args: {
|
|
60
66
|
isInverse: boolean;
|
|
61
67
|
type: CarbonChartType;
|
|
@@ -86,7 +92,9 @@ export declare const VerticalSimpleBarTimeSeriesDenseDataTurkish: {
|
|
|
86
92
|
};
|
|
87
93
|
};
|
|
88
94
|
export declare const VerticalSimpleBarEmptyState: {
|
|
89
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
95
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
96
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
97
|
+
}>;
|
|
90
98
|
args: {
|
|
91
99
|
isInverse: boolean;
|
|
92
100
|
type: CarbonChartType;
|
|
@@ -104,7 +112,9 @@ export declare const VerticalSimpleBarEmptyState: {
|
|
|
104
112
|
};
|
|
105
113
|
};
|
|
106
114
|
export declare const VerticalSimpleBarSkeleton: {
|
|
107
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
115
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
116
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
117
|
+
}>;
|
|
108
118
|
args: {
|
|
109
119
|
isInverse: boolean;
|
|
110
120
|
type: CarbonChartType;
|
|
@@ -125,7 +135,9 @@ export declare const VerticalSimpleBarSkeleton: {
|
|
|
125
135
|
};
|
|
126
136
|
};
|
|
127
137
|
export declare const HorizontalSimpleBarTimeSeries: {
|
|
128
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
138
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
139
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
140
|
+
}>;
|
|
129
141
|
args: {
|
|
130
142
|
isInverse: boolean;
|
|
131
143
|
type: CarbonChartType;
|
|
@@ -150,7 +162,9 @@ export declare const HorizontalSimpleBarTimeSeries: {
|
|
|
150
162
|
};
|
|
151
163
|
};
|
|
152
164
|
export declare const HorizontalSimpleBarDiscrete: {
|
|
153
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
165
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
166
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
167
|
+
}>;
|
|
154
168
|
args: {
|
|
155
169
|
isInverse: boolean;
|
|
156
170
|
type: CarbonChartType;
|
|
@@ -174,7 +188,9 @@ export declare const HorizontalSimpleBarDiscrete: {
|
|
|
174
188
|
};
|
|
175
189
|
};
|
|
176
190
|
export declare const HorizontalSimpleBarSkeleton: {
|
|
177
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
191
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
192
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
193
|
+
}>;
|
|
178
194
|
args: {
|
|
179
195
|
isInverse: boolean;
|
|
180
196
|
type: CarbonChartType;
|
|
@@ -195,7 +211,9 @@ export declare const HorizontalSimpleBarSkeleton: {
|
|
|
195
211
|
};
|
|
196
212
|
};
|
|
197
213
|
export declare const HorizontalSimpleBarEmptyState: {
|
|
198
|
-
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps
|
|
214
|
+
render: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react/types-6-0").ReactFramework, CarbonChartProps & {
|
|
215
|
+
titleLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined;
|
|
216
|
+
}>;
|
|
199
217
|
args: {
|
|
200
218
|
isInverse: boolean;
|
|
201
219
|
type: CarbonChartType;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-magma/charts",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.2.0-next.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,7 +47,7 @@
|
|
|
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.
|
|
50
|
+
"react-magma-dom": "^4.14.0",
|
|
51
51
|
"react-magma-icons": "^3.2.5",
|
|
52
52
|
"rollup": "^4.52.4",
|
|
53
53
|
"rollup-plugin-postcss": "^4.0.2"
|
|
@@ -57,7 +57,7 @@
|
|
|
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.
|
|
60
|
+
"react-magma-dom": "^4.14.0",
|
|
61
61
|
"react-magma-icons": "^3.2.5"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { act, render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
4
5
|
import { ThemeContext, magma, DropdownMenuItem } from 'react-magma-dom';
|
|
5
6
|
|
|
6
7
|
import { CarbonChart, CarbonChartType } from '.';
|
|
@@ -588,6 +589,32 @@ describe('CarbonChart', () => {
|
|
|
588
589
|
}
|
|
589
590
|
);
|
|
590
591
|
});
|
|
592
|
+
|
|
593
|
+
it('should move focus back after closing the More options dropdown and chart toolbar', () => {
|
|
594
|
+
const testId = 'modal-footer-border-test';
|
|
595
|
+
const { getByTestId, getByText } = render(
|
|
596
|
+
<ThemeContext.Provider value={magma}>
|
|
597
|
+
<CarbonChart
|
|
598
|
+
testId={testId}
|
|
599
|
+
dataSet={dataSet}
|
|
600
|
+
options={chartOptions}
|
|
601
|
+
type={CarbonChartType.bar}
|
|
602
|
+
isInverse={false}
|
|
603
|
+
chartToolbar={{}}
|
|
604
|
+
/>
|
|
605
|
+
</ThemeContext.Provider>
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
const moreOptionsButton = getByTestId('chart-more-options-button');
|
|
609
|
+
userEvent.click(moreOptionsButton);
|
|
610
|
+
|
|
611
|
+
expect(getByText('Download as CSV')).toBeVisible();
|
|
612
|
+
expect(getByText('Download as PNG')).toBeVisible();
|
|
613
|
+
expect(getByText('Download as JPG')).toBeVisible();
|
|
614
|
+
|
|
615
|
+
userEvent.keyboard('{esc}');
|
|
616
|
+
expect(moreOptionsButton).toHaveFocus();
|
|
617
|
+
});
|
|
591
618
|
});
|
|
592
619
|
|
|
593
620
|
describe('Modal Focus Management', () => {
|
|
@@ -842,6 +869,27 @@ describe('CarbonChart', () => {
|
|
|
842
869
|
).not.toBeInTheDocument();
|
|
843
870
|
});
|
|
844
871
|
|
|
872
|
+
it('should render the chart title as h2 by default', () => {
|
|
873
|
+
render(<CarbonChart {...toolbarProps} />);
|
|
874
|
+
|
|
875
|
+
expect(
|
|
876
|
+
screen.getByRole('heading', { level: 2, name: chartOptions.title })
|
|
877
|
+
).toBeInTheDocument();
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
it('should render the chart title at the level set by titleLevel', () => {
|
|
881
|
+
render(
|
|
882
|
+
<CarbonChart {...toolbarProps} chartToolbar={{ titleLevel: 3 }} />
|
|
883
|
+
);
|
|
884
|
+
|
|
885
|
+
expect(
|
|
886
|
+
screen.getByRole('heading', { level: 3, name: chartOptions.title })
|
|
887
|
+
).toBeInTheDocument();
|
|
888
|
+
expect(
|
|
889
|
+
screen.queryByRole('heading', { level: 2, name: chartOptions.title })
|
|
890
|
+
).not.toBeInTheDocument();
|
|
891
|
+
});
|
|
892
|
+
|
|
845
893
|
it('should always render the more options dropdown with built-in download items', () => {
|
|
846
894
|
render(<CarbonChart {...toolbarProps} />);
|
|
847
895
|
|
|
@@ -895,4 +943,141 @@ describe('CarbonChart', () => {
|
|
|
895
943
|
).toBeInTheDocument();
|
|
896
944
|
});
|
|
897
945
|
});
|
|
946
|
+
|
|
947
|
+
describe('dot keyboard accessibility', () => {
|
|
948
|
+
let rafCallbacks;
|
|
949
|
+
|
|
950
|
+
beforeEach(() => {
|
|
951
|
+
rafCallbacks = [];
|
|
952
|
+
jest.spyOn(window, 'requestAnimationFrame').mockImplementation(cb => {
|
|
953
|
+
rafCallbacks.push(cb);
|
|
954
|
+
return rafCallbacks.length - 1;
|
|
955
|
+
});
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
afterEach(() => {
|
|
959
|
+
window.requestAnimationFrame.mockRestore();
|
|
960
|
+
rafCallbacks = [];
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
function renderChart() {
|
|
964
|
+
const { getByTestId } = render(
|
|
965
|
+
<CarbonChart
|
|
966
|
+
testId="dot-tab-test"
|
|
967
|
+
dataSet={dataSet}
|
|
968
|
+
options={chartOptions}
|
|
969
|
+
type={CarbonChartType.scatter}
|
|
970
|
+
/>
|
|
971
|
+
);
|
|
972
|
+
return getByTestId('dot-tab-test');
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
function addDot(wrapper) {
|
|
976
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
977
|
+
const dot = document.createElementNS(
|
|
978
|
+
'http://www.w3.org/2000/svg',
|
|
979
|
+
'circle'
|
|
980
|
+
);
|
|
981
|
+
dot.classList.add('dot');
|
|
982
|
+
svg.appendChild(dot);
|
|
983
|
+
wrapper.appendChild(svg);
|
|
984
|
+
return dot;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
describe('tabbing', () => {
|
|
988
|
+
it('should stamp tabindex="0" on circle.dot elements so they are reachable by Tab', () => {
|
|
989
|
+
const wrapper = renderChart();
|
|
990
|
+
const dot = addDot(wrapper);
|
|
991
|
+
|
|
992
|
+
// The last captured RAF is the dots-stamping callback (no ariaLabel provided)
|
|
993
|
+
act(() => rafCallbacks[rafCallbacks.length - 1](0));
|
|
994
|
+
|
|
995
|
+
expect(dot).toHaveAttribute('tabindex', '0');
|
|
996
|
+
});
|
|
997
|
+
|
|
998
|
+
it('should not overwrite an existing tabindex on circle.dot', () => {
|
|
999
|
+
const wrapper = renderChart();
|
|
1000
|
+
const dot = addDot(wrapper);
|
|
1001
|
+
dot.setAttribute('tabindex', '-1');
|
|
1002
|
+
|
|
1003
|
+
act(() => rafCallbacks[rafCallbacks.length - 1](0));
|
|
1004
|
+
|
|
1005
|
+
expect(dot).toHaveAttribute('tabindex', '-1');
|
|
1006
|
+
});
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
describe('focus on dot content', () => {
|
|
1010
|
+
it('should set opacity to 1 when a dot receives focus', () => {
|
|
1011
|
+
const wrapper = renderChart();
|
|
1012
|
+
const dot = addDot(wrapper);
|
|
1013
|
+
|
|
1014
|
+
fireEvent.focusIn(dot);
|
|
1015
|
+
|
|
1016
|
+
expect(dot.style.opacity).toBe('1');
|
|
1017
|
+
});
|
|
1018
|
+
|
|
1019
|
+
it('should dispatch mouseover on dot focusin to reveal tooltip data', () => {
|
|
1020
|
+
const wrapper = renderChart();
|
|
1021
|
+
const dot = addDot(wrapper);
|
|
1022
|
+
|
|
1023
|
+
const mouseoverSpy = jest.fn();
|
|
1024
|
+
dot.addEventListener('mouseover', mouseoverSpy);
|
|
1025
|
+
|
|
1026
|
+
fireEvent.focusIn(dot);
|
|
1027
|
+
|
|
1028
|
+
expect(mouseoverSpy).toHaveBeenCalledTimes(1);
|
|
1029
|
+
});
|
|
1030
|
+
|
|
1031
|
+
it('should dispatch mousemove on dot focusin', () => {
|
|
1032
|
+
const wrapper = renderChart();
|
|
1033
|
+
const dot = addDot(wrapper);
|
|
1034
|
+
|
|
1035
|
+
const mousemoveSpy = jest.fn();
|
|
1036
|
+
dot.addEventListener('mousemove', mousemoveSpy);
|
|
1037
|
+
|
|
1038
|
+
fireEvent.focusIn(dot);
|
|
1039
|
+
|
|
1040
|
+
expect(mousemoveSpy).toHaveBeenCalledTimes(1);
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
it('should not change opacity for non-dot circle elements on focusin', () => {
|
|
1044
|
+
const wrapper = renderChart();
|
|
1045
|
+
const nonDot = document.createElementNS(
|
|
1046
|
+
'http://www.w3.org/2000/svg',
|
|
1047
|
+
'circle'
|
|
1048
|
+
);
|
|
1049
|
+
wrapper.appendChild(nonDot);
|
|
1050
|
+
|
|
1051
|
+
fireEvent.focusIn(nonDot);
|
|
1052
|
+
|
|
1053
|
+
expect(nonDot.style.opacity).toBe('');
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
describe('data visibility', () => {
|
|
1058
|
+
it('should reset dot opacity when dot loses focus', () => {
|
|
1059
|
+
const wrapper = renderChart();
|
|
1060
|
+
const dot = addDot(wrapper);
|
|
1061
|
+
|
|
1062
|
+
fireEvent.focusIn(dot);
|
|
1063
|
+
expect(dot.style.opacity).toBe('1');
|
|
1064
|
+
|
|
1065
|
+
fireEvent.focusOut(dot);
|
|
1066
|
+
expect(dot.style.opacity).toBe('');
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
it('should dispatch mouseout on dot focusout to hide tooltip', () => {
|
|
1070
|
+
const wrapper = renderChart();
|
|
1071
|
+
const dot = addDot(wrapper);
|
|
1072
|
+
|
|
1073
|
+
const mouseoutSpy = jest.fn();
|
|
1074
|
+
dot.addEventListener('mouseout', mouseoutSpy);
|
|
1075
|
+
|
|
1076
|
+
fireEvent.focusIn(dot);
|
|
1077
|
+
fireEvent.focusOut(dot);
|
|
1078
|
+
|
|
1079
|
+
expect(mouseoutSpy).toHaveBeenCalledTimes(1);
|
|
1080
|
+
});
|
|
1081
|
+
});
|
|
1082
|
+
});
|
|
898
1083
|
});
|