@mui/x-charts 9.11.0 → 9.12.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/BarChart/BarChart.js +7 -0
- package/BarChart/BarChart.mjs +7 -0
- package/CHANGELOG.md +165 -0
- package/ChartsContainer/ChartsContainer.js +7 -0
- package/ChartsContainer/ChartsContainer.mjs +7 -0
- package/ChartsContainer/useChartsContainerProps.js +3 -1
- package/ChartsContainer/useChartsContainerProps.mjs +3 -1
- package/ChartsTooltip/ChartsAxisTooltipContent.js +2 -9
- package/ChartsTooltip/ChartsAxisTooltipContent.mjs +2 -9
- package/ChartsTooltip/ChartsItemTooltipContent.js +2 -2
- package/ChartsTooltip/ChartsItemTooltipContent.mjs +2 -2
- package/ChartsTooltip/ChartsTooltipContainer.js +6 -2
- package/ChartsTooltip/ChartsTooltipContainer.mjs +6 -2
- package/LineChart/CircleMarkElement.js +0 -4
- package/LineChart/CircleMarkElement.mjs +0 -4
- package/LineChart/LineChart.js +7 -0
- package/LineChart/LineChart.mjs +7 -0
- package/PieChart/PieChart.js +7 -0
- package/PieChart/PieChart.mjs +7 -0
- package/RadarChart/RadarAxis/RadarAxis.utils.d.mts +1 -1
- package/RadarChart/RadarAxis/RadarAxis.utils.d.ts +1 -1
- package/RadarChart/RadarChart.js +7 -0
- package/RadarChart/RadarChart.mjs +7 -0
- package/RadarChart/useRadarChartProps.js +3 -1
- package/RadarChart/useRadarChartProps.mjs +3 -1
- package/ScatterChart/ScatterChart.js +7 -0
- package/ScatterChart/ScatterChart.mjs +7 -0
- package/SparkLineChart/SparkLineChart.js +7 -0
- package/SparkLineChart/SparkLineChart.mjs +7 -0
- package/hooks/useInteractionItemProps.js +4 -0
- package/hooks/useInteractionItemProps.mjs +4 -0
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/internals/components/ChartsAccessibilityProxy/ChartsAccessibilityProxy.js +13 -3
- package/internals/components/ChartsAccessibilityProxy/ChartsAccessibilityProxy.mjs +12 -3
- package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.d.mts +8 -0
- package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.d.ts +8 -0
- package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.js +25 -0
- package/internals/components/ChartsAccessibilityProxy/focusAccessibilityProxy.mjs +19 -0
- package/internals/components/ChartsAccessibilityProxy/index.d.mts +2 -1
- package/internals/components/ChartsAccessibilityProxy/index.d.ts +2 -1
- package/internals/components/ChartsAccessibilityProxy/index.js +11 -0
- package/internals/components/ChartsAccessibilityProxy/index.mjs +2 -1
- package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.js +3 -1
- package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.mjs +3 -1
- package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.types.d.mts +5 -0
- package/internals/plugins/corePlugins/useChartElementRef/useChartElementRef.types.d.ts +5 -0
- package/internals/plugins/featurePlugins/shared/useRegisterPointerInteractions.js +10 -0
- package/internals/plugins/featurePlugins/shared/useRegisterPointerInteractions.mjs +10 -0
- package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.js +22 -0
- package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.mjs +22 -0
- package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.js +27 -1
- package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.mjs +27 -1
- package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.d.mts +20 -0
- package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.d.ts +20 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.js +209 -35
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.mjs +211 -36
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.d.mts +3 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.d.ts +3 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.js +12 -5
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.mjs +11 -4
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.types.d.mts +29 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.types.d.ts +29 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.d.mts +28 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.d.ts +28 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.js +81 -0
- package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtAxisPosition.mjs +76 -0
- package/package.json +4 -4
|
@@ -145,6 +145,13 @@ process.env.NODE_ENV !== "production" ? ScatterChart.propTypes /* remove-proptyp
|
|
|
145
145
|
keyboardActivation: PropTypes.bool,
|
|
146
146
|
progressiveRendering: PropTypes.bool
|
|
147
147
|
}),
|
|
148
|
+
/**
|
|
149
|
+
* If `true`, clicking an item immediately shows the keyboard focus indicator on it.
|
|
150
|
+
* By default, clicking sets the item that keyboard navigation starts from, but the focus
|
|
151
|
+
* indicator stays hidden until the user presses a key.
|
|
152
|
+
* @default false
|
|
153
|
+
*/
|
|
154
|
+
focusItemOnClick: PropTypes.bool,
|
|
148
155
|
/**
|
|
149
156
|
* Option to display a cartesian grid in the background.
|
|
150
157
|
*/
|
|
@@ -259,6 +259,13 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes /* remove-propt
|
|
|
259
259
|
keyboardActivation: _propTypes.default.bool,
|
|
260
260
|
progressiveRendering: _propTypes.default.bool
|
|
261
261
|
}),
|
|
262
|
+
/**
|
|
263
|
+
* If `true`, clicking an item immediately shows the keyboard focus indicator on it.
|
|
264
|
+
* By default, clicking sets the item that keyboard navigation starts from, but the focus
|
|
265
|
+
* indicator stays hidden until the user presses a key.
|
|
266
|
+
* @default false
|
|
267
|
+
*/
|
|
268
|
+
focusItemOnClick: _propTypes.default.bool,
|
|
262
269
|
/**
|
|
263
270
|
* The height of the chart in px. If not defined, it takes the height of the parent element.
|
|
264
271
|
*/
|
|
@@ -252,6 +252,13 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes /* remove-propt
|
|
|
252
252
|
keyboardActivation: PropTypes.bool,
|
|
253
253
|
progressiveRendering: PropTypes.bool
|
|
254
254
|
}),
|
|
255
|
+
/**
|
|
256
|
+
* If `true`, clicking an item immediately shows the keyboard focus indicator on it.
|
|
257
|
+
* By default, clicking sets the item that keyboard navigation starts from, but the focus
|
|
258
|
+
* indicator stays hidden until the user presses a key.
|
|
259
|
+
* @default false
|
|
260
|
+
*/
|
|
261
|
+
focusItemOnClick: PropTypes.bool,
|
|
255
262
|
/**
|
|
256
263
|
* The height of the chart in px. If not defined, it takes the height of the parent element.
|
|
257
264
|
*/
|
|
@@ -24,11 +24,13 @@ const useInteractionItemProps = data => {
|
|
|
24
24
|
const onPointerEnter = (0, _useEventCallback.default)(() => {
|
|
25
25
|
interactionActive.current = true;
|
|
26
26
|
instance.setLastUpdateSource('pointer');
|
|
27
|
+
instance.setHoveredItem(data);
|
|
27
28
|
instance.setTooltipItem(data);
|
|
28
29
|
instance.setHighlight(data);
|
|
29
30
|
});
|
|
30
31
|
const onPointerLeave = (0, _useEventCallback.default)(() => {
|
|
31
32
|
interactionActive.current = false;
|
|
33
|
+
instance.clearHoveredItem(data);
|
|
32
34
|
instance.removeTooltipItem(data);
|
|
33
35
|
instance.clearHighlight();
|
|
34
36
|
});
|
|
@@ -53,6 +55,7 @@ function getInteractionItemProps(instance, item) {
|
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
57
|
instance.setLastUpdateSource('pointer');
|
|
58
|
+
instance.setHoveredItem(item);
|
|
56
59
|
instance.setTooltipItem(item);
|
|
57
60
|
instance.setHighlight(item);
|
|
58
61
|
}
|
|
@@ -60,6 +63,7 @@ function getInteractionItemProps(instance, item) {
|
|
|
60
63
|
if (!item) {
|
|
61
64
|
return;
|
|
62
65
|
}
|
|
66
|
+
instance.clearHoveredItem(item);
|
|
63
67
|
instance.removeTooltipItem(item);
|
|
64
68
|
instance.clearHighlight();
|
|
65
69
|
}
|
|
@@ -16,11 +16,13 @@ export const useInteractionItemProps = data => {
|
|
|
16
16
|
const onPointerEnter = useEventCallback(() => {
|
|
17
17
|
interactionActive.current = true;
|
|
18
18
|
instance.setLastUpdateSource('pointer');
|
|
19
|
+
instance.setHoveredItem(data);
|
|
19
20
|
instance.setTooltipItem(data);
|
|
20
21
|
instance.setHighlight(data);
|
|
21
22
|
});
|
|
22
23
|
const onPointerLeave = useEventCallback(() => {
|
|
23
24
|
interactionActive.current = false;
|
|
25
|
+
instance.clearHoveredItem(data);
|
|
24
26
|
instance.removeTooltipItem(data);
|
|
25
27
|
instance.clearHighlight();
|
|
26
28
|
});
|
|
@@ -44,6 +46,7 @@ export function getInteractionItemProps(instance, item) {
|
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
48
|
instance.setLastUpdateSource('pointer');
|
|
49
|
+
instance.setHoveredItem(item);
|
|
47
50
|
instance.setTooltipItem(item);
|
|
48
51
|
instance.setHighlight(item);
|
|
49
52
|
}
|
|
@@ -51,6 +54,7 @@ export function getInteractionItemProps(instance, item) {
|
|
|
51
54
|
if (!item) {
|
|
52
55
|
return;
|
|
53
56
|
}
|
|
57
|
+
instance.clearHoveredItem(item);
|
|
54
58
|
instance.removeTooltipItem(item);
|
|
55
59
|
instance.clearHighlight();
|
|
56
60
|
}
|
package/index.js
CHANGED
package/index.mjs
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
'use client';
|
|
3
3
|
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
5
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
6
|
Object.defineProperty(exports, "__esModule", {
|
|
6
7
|
value: true
|
|
7
8
|
});
|
|
8
9
|
exports.ChartsAccessibilityProxy = ChartsAccessibilityProxy;
|
|
9
10
|
var React = _interopRequireWildcard(require("react"));
|
|
11
|
+
var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
|
|
10
12
|
var _useChartId = require("../../../hooks/useChartId");
|
|
13
|
+
var _ChartsProvider = require("../../../context/ChartsProvider");
|
|
11
14
|
var _useDescription = require("./useDescription");
|
|
12
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
16
|
/**
|
|
@@ -35,9 +38,13 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
35
38
|
function ChartsAccessibilityProxy() {
|
|
36
39
|
const message = (0, _useDescription.useDescription)();
|
|
37
40
|
const chartId = (0, _useChartId.useChartId)();
|
|
41
|
+
const {
|
|
42
|
+
instance
|
|
43
|
+
} = (0, _ChartsProvider.useChartsContext)();
|
|
38
44
|
const currentFormatRef = React.useRef(null);
|
|
39
45
|
const currentIndexRef = React.useRef(0);
|
|
40
46
|
const containerRef = React.useRef(null);
|
|
47
|
+
const handleRef = (0, _useForkRef.default)(containerRef, instance.chartsAccessibilityProxyRef);
|
|
41
48
|
React.useEffect(() => {
|
|
42
49
|
const container = containerRef.current;
|
|
43
50
|
if (!container) {
|
|
@@ -93,9 +100,12 @@ function ChartsAccessibilityProxy() {
|
|
|
93
100
|
}
|
|
94
101
|
}, [message, chartId]);
|
|
95
102
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
96
|
-
role: "none"
|
|
97
|
-
|
|
98
|
-
|
|
103
|
+
role: "none"
|
|
104
|
+
// Stays focusable once an announcer child owns the tab stop, otherwise the browser would
|
|
105
|
+
// blur the root mid hand-off and the chart would look like it lost the focus.
|
|
106
|
+
,
|
|
107
|
+
tabIndex: message ? -1 : 0,
|
|
108
|
+
ref: handleRef,
|
|
99
109
|
style: fullSizeLayerStyle
|
|
100
110
|
});
|
|
101
111
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
+
import useForkRef from '@mui/utils/useForkRef';
|
|
4
5
|
import { useChartId } from "../../../hooks/useChartId.mjs";
|
|
6
|
+
import { useChartsContext } from "../../../context/ChartsProvider/index.mjs";
|
|
5
7
|
import { useDescription } from "./useDescription.mjs";
|
|
6
8
|
|
|
7
9
|
/**
|
|
@@ -31,9 +33,13 @@ const fullSizeLayerStyle = {
|
|
|
31
33
|
export function ChartsAccessibilityProxy() {
|
|
32
34
|
const message = useDescription();
|
|
33
35
|
const chartId = useChartId();
|
|
36
|
+
const {
|
|
37
|
+
instance
|
|
38
|
+
} = useChartsContext();
|
|
34
39
|
const currentFormatRef = React.useRef(null);
|
|
35
40
|
const currentIndexRef = React.useRef(0);
|
|
36
41
|
const containerRef = React.useRef(null);
|
|
42
|
+
const handleRef = useForkRef(containerRef, instance.chartsAccessibilityProxyRef);
|
|
37
43
|
React.useEffect(() => {
|
|
38
44
|
const container = containerRef.current;
|
|
39
45
|
if (!container) {
|
|
@@ -89,9 +95,12 @@ export function ChartsAccessibilityProxy() {
|
|
|
89
95
|
}
|
|
90
96
|
}, [message, chartId]);
|
|
91
97
|
return /*#__PURE__*/_jsx("div", {
|
|
92
|
-
role: "none"
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
role: "none"
|
|
99
|
+
// Stays focusable once an announcer child owns the tab stop, otherwise the browser would
|
|
100
|
+
// blur the root mid hand-off and the chart would look like it lost the focus.
|
|
101
|
+
,
|
|
102
|
+
tabIndex: message ? -1 : 0,
|
|
103
|
+
ref: handleRef,
|
|
95
104
|
style: fullSizeLayerStyle
|
|
96
105
|
});
|
|
97
106
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moves the DOM focus to the chart tab stop.
|
|
3
|
+
* The proxy root is only tabbable while there is no description, otherwise one of the announcer
|
|
4
|
+
* children holds the tab stop.
|
|
5
|
+
* @param {HTMLDivElement | null} root The accessibility proxy root.
|
|
6
|
+
* @returns {boolean} `true` when an element was focused.
|
|
7
|
+
*/
|
|
8
|
+
export declare function focusAccessibilityProxy(root: HTMLDivElement | null): boolean;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moves the DOM focus to the chart tab stop.
|
|
3
|
+
* The proxy root is only tabbable while there is no description, otherwise one of the announcer
|
|
4
|
+
* children holds the tab stop.
|
|
5
|
+
* @param {HTMLDivElement | null} root The accessibility proxy root.
|
|
6
|
+
* @returns {boolean} `true` when an element was focused.
|
|
7
|
+
*/
|
|
8
|
+
export declare function focusAccessibilityProxy(root: HTMLDivElement | null): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.focusAccessibilityProxy = focusAccessibilityProxy;
|
|
7
|
+
/**
|
|
8
|
+
* Moves the DOM focus to the chart tab stop.
|
|
9
|
+
* The proxy root is only tabbable while there is no description, otherwise one of the announcer
|
|
10
|
+
* children holds the tab stop.
|
|
11
|
+
* @param {HTMLDivElement | null} root The accessibility proxy root.
|
|
12
|
+
* @returns {boolean} `true` when an element was focused.
|
|
13
|
+
*/
|
|
14
|
+
function focusAccessibilityProxy(root) {
|
|
15
|
+
if (!root) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const target = root.querySelector('[tabindex="0"]') ?? (root.tabIndex >= 0 ? root : null);
|
|
19
|
+
|
|
20
|
+
// The proxy covers the whole chart, focusing it would scroll long pages.
|
|
21
|
+
target?.focus({
|
|
22
|
+
preventScroll: true
|
|
23
|
+
});
|
|
24
|
+
return target !== null;
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moves the DOM focus to the chart tab stop.
|
|
3
|
+
* The proxy root is only tabbable while there is no description, otherwise one of the announcer
|
|
4
|
+
* children holds the tab stop.
|
|
5
|
+
* @param {HTMLDivElement | null} root The accessibility proxy root.
|
|
6
|
+
* @returns {boolean} `true` when an element was focused.
|
|
7
|
+
*/
|
|
8
|
+
export function focusAccessibilityProxy(root) {
|
|
9
|
+
if (!root) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const target = root.querySelector('[tabindex="0"]') ?? (root.tabIndex >= 0 ? root : null);
|
|
13
|
+
|
|
14
|
+
// The proxy covers the whole chart, focusing it would scroll long pages.
|
|
15
|
+
target?.focus({
|
|
16
|
+
preventScroll: true
|
|
17
|
+
});
|
|
18
|
+
return target !== null;
|
|
19
|
+
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./ChartsAccessibilityProxy.mjs";
|
|
1
|
+
export * from "./ChartsAccessibilityProxy.mjs";
|
|
2
|
+
export * from "./focusAccessibilityProxy.mjs";
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./ChartsAccessibilityProxy.js";
|
|
1
|
+
export * from "./ChartsAccessibilityProxy.js";
|
|
2
|
+
export * from "./focusAccessibilityProxy.js";
|
|
@@ -13,4 +13,15 @@ Object.keys(_ChartsAccessibilityProxy).forEach(function (key) {
|
|
|
13
13
|
return _ChartsAccessibilityProxy[key];
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
|
+
});
|
|
17
|
+
var _focusAccessibilityProxy = require("./focusAccessibilityProxy");
|
|
18
|
+
Object.keys(_focusAccessibilityProxy).forEach(function (key) {
|
|
19
|
+
if (key === "default" || key === "__esModule") return;
|
|
20
|
+
if (key in exports && exports[key] === _focusAccessibilityProxy[key]) return;
|
|
21
|
+
Object.defineProperty(exports, key, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () {
|
|
24
|
+
return _focusAccessibilityProxy[key];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
16
27
|
});
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./ChartsAccessibilityProxy.mjs";
|
|
1
|
+
export * from "./ChartsAccessibilityProxy.mjs";
|
|
2
|
+
export * from "./focusAccessibilityProxy.mjs";
|
|
@@ -10,10 +10,12 @@ var React = _interopRequireWildcard(require("react"));
|
|
|
10
10
|
const useChartElementRef = () => {
|
|
11
11
|
const chartsLayerContainerRef = React.useRef(null);
|
|
12
12
|
const chartRootRef = React.useRef(null);
|
|
13
|
+
const chartsAccessibilityProxyRef = React.useRef(null);
|
|
13
14
|
return {
|
|
14
15
|
instance: {
|
|
15
16
|
chartsLayerContainerRef,
|
|
16
|
-
chartRootRef
|
|
17
|
+
chartRootRef,
|
|
18
|
+
chartsAccessibilityProxyRef
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
21
|
};
|
|
@@ -4,10 +4,12 @@ import * as React from 'react';
|
|
|
4
4
|
export const useChartElementRef = () => {
|
|
5
5
|
const chartsLayerContainerRef = React.useRef(null);
|
|
6
6
|
const chartRootRef = React.useRef(null);
|
|
7
|
+
const chartsAccessibilityProxyRef = React.useRef(null);
|
|
7
8
|
return {
|
|
8
9
|
instance: {
|
|
9
10
|
chartsLayerContainerRef,
|
|
10
|
-
chartRootRef
|
|
11
|
+
chartRootRef,
|
|
12
|
+
chartsAccessibilityProxyRef
|
|
11
13
|
}
|
|
12
14
|
};
|
|
13
15
|
};
|
|
@@ -9,6 +9,11 @@ export interface UseChartElementRefInstance {
|
|
|
9
9
|
* Reference to the chart root element.
|
|
10
10
|
*/
|
|
11
11
|
chartRootRef: React.RefObject<Element | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Reference to the root of the accessibility proxy, the element owning the chart tab stop.
|
|
14
|
+
* It is `null` when keyboard navigation is disabled.
|
|
15
|
+
*/
|
|
16
|
+
chartsAccessibilityProxyRef: React.RefObject<HTMLDivElement | null>;
|
|
12
17
|
}
|
|
13
18
|
export type UseChartElementRefSignature = ChartPluginSignature<{
|
|
14
19
|
instance: UseChartElementRefInstance;
|
|
@@ -9,6 +9,11 @@ export interface UseChartElementRefInstance {
|
|
|
9
9
|
* Reference to the chart root element.
|
|
10
10
|
*/
|
|
11
11
|
chartRootRef: React.RefObject<Element | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Reference to the root of the accessibility proxy, the element owning the chart tab stop.
|
|
14
|
+
* It is `null` when keyboard navigation is disabled.
|
|
15
|
+
*/
|
|
16
|
+
chartsAccessibilityProxyRef: React.RefObject<HTMLDivElement | null>;
|
|
12
17
|
}
|
|
13
18
|
export type UseChartElementRefSignature = ChartPluginSignature<{
|
|
14
19
|
instance: UseChartElementRefInstance;
|
|
@@ -40,6 +40,7 @@ function useRegisterPointerInteractions() {
|
|
|
40
40
|
const lastItem = lastItemRef.current;
|
|
41
41
|
if (lastItem) {
|
|
42
42
|
lastItemRef.current = undefined;
|
|
43
|
+
instance.clearHoveredItem(lastItem);
|
|
43
44
|
instance.removeTooltipItem(lastItem);
|
|
44
45
|
instance.clearHighlight();
|
|
45
46
|
}
|
|
@@ -66,6 +67,7 @@ function useRegisterPointerInteractions() {
|
|
|
66
67
|
}
|
|
67
68
|
if (item) {
|
|
68
69
|
instance.setLastUpdateSource('pointer');
|
|
70
|
+
instance.setHoveredItem(item);
|
|
69
71
|
instance.setTooltipItem(item);
|
|
70
72
|
instance.setHighlight(item);
|
|
71
73
|
lastItemRef.current = item;
|
|
@@ -73,10 +75,18 @@ function useRegisterPointerInteractions() {
|
|
|
73
75
|
reset();
|
|
74
76
|
}
|
|
75
77
|
};
|
|
78
|
+
|
|
79
|
+
// Touch has no hover phase, so a tap may never produce a `pointermove`. Resolving on
|
|
80
|
+
// `pointerdown` too is what makes the pointer item known for a stationary tap.
|
|
81
|
+
const onPointerDown = function onPointerDown(event) {
|
|
82
|
+
onPointerMove(event);
|
|
83
|
+
};
|
|
84
|
+
element.addEventListener('pointerdown', onPointerDown);
|
|
76
85
|
element.addEventListener('pointerleave', onPointerLeave);
|
|
77
86
|
element.addEventListener('pointermove', onPointerMove);
|
|
78
87
|
element.addEventListener('pointerenter', onPointerEnter);
|
|
79
88
|
return () => {
|
|
89
|
+
element.removeEventListener('pointerdown', onPointerDown);
|
|
80
90
|
element.removeEventListener('pointerenter', onPointerEnter);
|
|
81
91
|
element.removeEventListener('pointermove', onPointerMove);
|
|
82
92
|
element.removeEventListener('pointerleave', onPointerLeave);
|
|
@@ -34,6 +34,7 @@ export function useRegisterPointerInteractions() {
|
|
|
34
34
|
const lastItem = lastItemRef.current;
|
|
35
35
|
if (lastItem) {
|
|
36
36
|
lastItemRef.current = undefined;
|
|
37
|
+
instance.clearHoveredItem(lastItem);
|
|
37
38
|
instance.removeTooltipItem(lastItem);
|
|
38
39
|
instance.clearHighlight();
|
|
39
40
|
}
|
|
@@ -60,6 +61,7 @@ export function useRegisterPointerInteractions() {
|
|
|
60
61
|
}
|
|
61
62
|
if (item) {
|
|
62
63
|
instance.setLastUpdateSource('pointer');
|
|
64
|
+
instance.setHoveredItem(item);
|
|
63
65
|
instance.setTooltipItem(item);
|
|
64
66
|
instance.setHighlight(item);
|
|
65
67
|
lastItemRef.current = item;
|
|
@@ -67,10 +69,18 @@ export function useRegisterPointerInteractions() {
|
|
|
67
69
|
reset();
|
|
68
70
|
}
|
|
69
71
|
};
|
|
72
|
+
|
|
73
|
+
// Touch has no hover phase, so a tap may never produce a `pointermove`. Resolving on
|
|
74
|
+
// `pointerdown` too is what makes the pointer item known for a stationary tap.
|
|
75
|
+
const onPointerDown = function onPointerDown(event) {
|
|
76
|
+
onPointerMove(event);
|
|
77
|
+
};
|
|
78
|
+
element.addEventListener('pointerdown', onPointerDown);
|
|
70
79
|
element.addEventListener('pointerleave', onPointerLeave);
|
|
71
80
|
element.addEventListener('pointermove', onPointerMove);
|
|
72
81
|
element.addEventListener('pointerenter', onPointerEnter);
|
|
73
82
|
return () => {
|
|
83
|
+
element.removeEventListener('pointerdown', onPointerDown);
|
|
74
84
|
element.removeEventListener('pointerenter', onPointerEnter);
|
|
75
85
|
element.removeEventListener('pointermove', onPointerMove);
|
|
76
86
|
element.removeEventListener('pointerleave', onPointerLeave);
|
|
@@ -144,6 +144,7 @@ const useChartClosestPoint = ({
|
|
|
144
144
|
const moveEndHandler = instance.addInteractionListener('moveEnd', event => {
|
|
145
145
|
if (!event.detail.activeGestures.pan) {
|
|
146
146
|
instance.cleanInteraction?.();
|
|
147
|
+
instance.clearHoveredItem?.();
|
|
147
148
|
instance.clearHighlight?.();
|
|
148
149
|
instance.removeTooltipItem?.();
|
|
149
150
|
}
|
|
@@ -151,6 +152,7 @@ const useChartClosestPoint = ({
|
|
|
151
152
|
const panEndHandler = instance.addInteractionListener('panEnd', event => {
|
|
152
153
|
if (!event.detail.activeGestures.move) {
|
|
153
154
|
instance.cleanInteraction?.();
|
|
155
|
+
instance.clearHoveredItem?.();
|
|
154
156
|
instance.clearHighlight?.();
|
|
155
157
|
instance.removeTooltipItem?.();
|
|
156
158
|
}
|
|
@@ -158,6 +160,7 @@ const useChartClosestPoint = ({
|
|
|
158
160
|
const pressEndHandler = instance.addInteractionListener('quickPressEnd', event => {
|
|
159
161
|
if (!event.detail.activeGestures.move && !event.detail.activeGestures.pan) {
|
|
160
162
|
instance.cleanInteraction?.();
|
|
163
|
+
instance.clearHoveredItem?.();
|
|
161
164
|
instance.clearHighlight?.();
|
|
162
165
|
instance.removeTooltipItem?.();
|
|
163
166
|
}
|
|
@@ -166,12 +169,14 @@ const useChartClosestPoint = ({
|
|
|
166
169
|
const closestPoint = getClosestPoint(event.detail.srcEvent);
|
|
167
170
|
if (closestPoint === 'outside-chart') {
|
|
168
171
|
instance.cleanInteraction?.();
|
|
172
|
+
instance.clearHoveredItem?.();
|
|
169
173
|
instance.clearHighlight?.();
|
|
170
174
|
instance.removeTooltipItem?.();
|
|
171
175
|
return;
|
|
172
176
|
}
|
|
173
177
|
if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') {
|
|
174
178
|
instance.removeTooltipItem?.();
|
|
179
|
+
instance.clearHoveredItem?.();
|
|
175
180
|
instance.clearHighlight?.();
|
|
176
181
|
instance.removeTooltipItem?.();
|
|
177
182
|
return;
|
|
@@ -180,6 +185,11 @@ const useChartClosestPoint = ({
|
|
|
180
185
|
seriesId,
|
|
181
186
|
dataIndex
|
|
182
187
|
} = closestPoint;
|
|
188
|
+
instance.setHoveredItem?.({
|
|
189
|
+
type: 'scatter',
|
|
190
|
+
seriesId,
|
|
191
|
+
dataIndex
|
|
192
|
+
});
|
|
183
193
|
instance.setTooltipItem?.({
|
|
184
194
|
type: 'scatter',
|
|
185
195
|
seriesId,
|
|
@@ -192,6 +202,17 @@ const useChartClosestPoint = ({
|
|
|
192
202
|
dataIndex
|
|
193
203
|
});
|
|
194
204
|
};
|
|
205
|
+
|
|
206
|
+
// A tap resolves nothing without a preceding move, and touch has no hover phase, so the
|
|
207
|
+
// pointer item is also resolved on `pointerdown`.
|
|
208
|
+
const onPointerDown = function onPointerDown(event) {
|
|
209
|
+
gestureHandler({
|
|
210
|
+
detail: {
|
|
211
|
+
srcEvent: event
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
element.addEventListener('pointerdown', onPointerDown);
|
|
195
216
|
const tapHandler = instance.addInteractionListener('tap', event => {
|
|
196
217
|
const closestPoint = getClosestPoint(event.detail.srcEvent);
|
|
197
218
|
if (typeof closestPoint !== 'string' && onItemClick) {
|
|
@@ -210,6 +231,7 @@ const useChartClosestPoint = ({
|
|
|
210
231
|
const panHandler = instance.addInteractionListener('pan', gestureHandler);
|
|
211
232
|
const pressHandler = instance.addInteractionListener('quickPress', gestureHandler);
|
|
212
233
|
return () => {
|
|
234
|
+
element.removeEventListener('pointerdown', onPointerDown);
|
|
213
235
|
tapHandler.cleanup();
|
|
214
236
|
moveHandler.cleanup();
|
|
215
237
|
moveEndHandler.cleanup();
|
|
@@ -137,6 +137,7 @@ export const useChartClosestPoint = ({
|
|
|
137
137
|
const moveEndHandler = instance.addInteractionListener('moveEnd', event => {
|
|
138
138
|
if (!event.detail.activeGestures.pan) {
|
|
139
139
|
instance.cleanInteraction?.();
|
|
140
|
+
instance.clearHoveredItem?.();
|
|
140
141
|
instance.clearHighlight?.();
|
|
141
142
|
instance.removeTooltipItem?.();
|
|
142
143
|
}
|
|
@@ -144,6 +145,7 @@ export const useChartClosestPoint = ({
|
|
|
144
145
|
const panEndHandler = instance.addInteractionListener('panEnd', event => {
|
|
145
146
|
if (!event.detail.activeGestures.move) {
|
|
146
147
|
instance.cleanInteraction?.();
|
|
148
|
+
instance.clearHoveredItem?.();
|
|
147
149
|
instance.clearHighlight?.();
|
|
148
150
|
instance.removeTooltipItem?.();
|
|
149
151
|
}
|
|
@@ -151,6 +153,7 @@ export const useChartClosestPoint = ({
|
|
|
151
153
|
const pressEndHandler = instance.addInteractionListener('quickPressEnd', event => {
|
|
152
154
|
if (!event.detail.activeGestures.move && !event.detail.activeGestures.pan) {
|
|
153
155
|
instance.cleanInteraction?.();
|
|
156
|
+
instance.clearHoveredItem?.();
|
|
154
157
|
instance.clearHighlight?.();
|
|
155
158
|
instance.removeTooltipItem?.();
|
|
156
159
|
}
|
|
@@ -159,12 +162,14 @@ export const useChartClosestPoint = ({
|
|
|
159
162
|
const closestPoint = getClosestPoint(event.detail.srcEvent);
|
|
160
163
|
if (closestPoint === 'outside-chart') {
|
|
161
164
|
instance.cleanInteraction?.();
|
|
165
|
+
instance.clearHoveredItem?.();
|
|
162
166
|
instance.clearHighlight?.();
|
|
163
167
|
instance.removeTooltipItem?.();
|
|
164
168
|
return;
|
|
165
169
|
}
|
|
166
170
|
if (closestPoint === 'outside-voronoi-max-radius' || closestPoint === 'no-point-found') {
|
|
167
171
|
instance.removeTooltipItem?.();
|
|
172
|
+
instance.clearHoveredItem?.();
|
|
168
173
|
instance.clearHighlight?.();
|
|
169
174
|
instance.removeTooltipItem?.();
|
|
170
175
|
return;
|
|
@@ -173,6 +178,11 @@ export const useChartClosestPoint = ({
|
|
|
173
178
|
seriesId,
|
|
174
179
|
dataIndex
|
|
175
180
|
} = closestPoint;
|
|
181
|
+
instance.setHoveredItem?.({
|
|
182
|
+
type: 'scatter',
|
|
183
|
+
seriesId,
|
|
184
|
+
dataIndex
|
|
185
|
+
});
|
|
176
186
|
instance.setTooltipItem?.({
|
|
177
187
|
type: 'scatter',
|
|
178
188
|
seriesId,
|
|
@@ -185,6 +195,17 @@ export const useChartClosestPoint = ({
|
|
|
185
195
|
dataIndex
|
|
186
196
|
});
|
|
187
197
|
};
|
|
198
|
+
|
|
199
|
+
// A tap resolves nothing without a preceding move, and touch has no hover phase, so the
|
|
200
|
+
// pointer item is also resolved on `pointerdown`.
|
|
201
|
+
const onPointerDown = function onPointerDown(event) {
|
|
202
|
+
gestureHandler({
|
|
203
|
+
detail: {
|
|
204
|
+
srcEvent: event
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
element.addEventListener('pointerdown', onPointerDown);
|
|
188
209
|
const tapHandler = instance.addInteractionListener('tap', event => {
|
|
189
210
|
const closestPoint = getClosestPoint(event.detail.srcEvent);
|
|
190
211
|
if (typeof closestPoint !== 'string' && onItemClick) {
|
|
@@ -203,6 +224,7 @@ export const useChartClosestPoint = ({
|
|
|
203
224
|
const panHandler = instance.addInteractionListener('pan', gestureHandler);
|
|
204
225
|
const pressHandler = instance.addInteractionListener('quickPress', gestureHandler);
|
|
205
226
|
return () => {
|
|
227
|
+
element.removeEventListener('pointerdown', onPointerDown);
|
|
206
228
|
tapHandler.cleanup();
|
|
207
229
|
moveHandler.cleanup();
|
|
208
230
|
moveEndHandler.cleanup();
|
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.useChartInteraction = void 0;
|
|
8
8
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
9
|
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
|
|
10
|
+
var _fastObjectShallowCompare = require("@mui/x-internals/fastObjectShallowCompare");
|
|
10
11
|
const useChartInteraction = ({
|
|
11
12
|
store
|
|
12
13
|
}) => {
|
|
@@ -24,6 +25,28 @@ const useChartInteraction = ({
|
|
|
24
25
|
}));
|
|
25
26
|
}
|
|
26
27
|
});
|
|
28
|
+
const setHoveredItem = (0, _useEventCallback.default)(function setHoveredItem(item) {
|
|
29
|
+
const previousItem = store.state.interaction.hoveredItem;
|
|
30
|
+
if (previousItem !== null && (0, _fastObjectShallowCompare.fastObjectShallowCompare)(previousItem, item)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
store.set('interaction', (0, _extends2.default)({}, store.state.interaction, {
|
|
34
|
+
hoveredItem: item
|
|
35
|
+
}));
|
|
36
|
+
});
|
|
37
|
+
const clearHoveredItem = (0, _useEventCallback.default)(function clearHoveredItem(itemToRemove) {
|
|
38
|
+
const previousItem = store.state.interaction.hoveredItem;
|
|
39
|
+
if (previousItem === null) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (itemToRemove !== undefined && !(0, _fastObjectShallowCompare.fastObjectShallowCompare)(previousItem, itemToRemove)) {
|
|
43
|
+
// Another item took over already.
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
store.set('interaction', (0, _extends2.default)({}, store.state.interaction, {
|
|
47
|
+
hoveredItem: null
|
|
48
|
+
}));
|
|
49
|
+
});
|
|
27
50
|
const setPointerCoordinate = (0, _useEventCallback.default)(function setPointerCoordinate(coordinate) {
|
|
28
51
|
store.set('interaction', (0, _extends2.default)({}, store.state.interaction, {
|
|
29
52
|
pointer: coordinate,
|
|
@@ -44,6 +67,8 @@ const useChartInteraction = ({
|
|
|
44
67
|
instance: {
|
|
45
68
|
cleanInteraction,
|
|
46
69
|
setLastUpdateSource,
|
|
70
|
+
setHoveredItem,
|
|
71
|
+
clearHoveredItem,
|
|
47
72
|
setPointerCoordinate,
|
|
48
73
|
handlePointerEnter,
|
|
49
74
|
handlePointerLeave
|
|
@@ -56,7 +81,8 @@ useChartInteraction.getInitialState = () => ({
|
|
|
56
81
|
item: null,
|
|
57
82
|
pointer: null,
|
|
58
83
|
lastUpdate: 'pointer',
|
|
59
|
-
pointerType: null
|
|
84
|
+
pointerType: null,
|
|
85
|
+
hoveredItem: null
|
|
60
86
|
}
|
|
61
87
|
});
|
|
62
88
|
useChartInteraction.params = {};
|