@mui/x-charts 9.12.0 → 9.13.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.
Files changed (78) hide show
  1. package/BarChart/BarChart.js +1 -1
  2. package/BarChart/BarChart.mjs +1 -1
  3. package/CHANGELOG.md +152 -0
  4. package/ChartsContainer/ChartsContainer.js +1 -1
  5. package/ChartsContainer/ChartsContainer.mjs +1 -1
  6. package/ChartsXAxis/useAxisTicksProps.js +2 -1
  7. package/ChartsXAxis/useAxisTicksProps.mjs +2 -1
  8. package/ChartsYAxis/shortenLabels.js +16 -26
  9. package/ChartsYAxis/shortenLabels.mjs +17 -27
  10. package/ChartsYAxis/useAxisTicksProps.js +2 -1
  11. package/ChartsYAxis/useAxisTicksProps.mjs +2 -1
  12. package/LineChart/LineChart.js +1 -1
  13. package/LineChart/LineChart.mjs +1 -1
  14. package/LineChart/MarkElement.js +13 -6
  15. package/LineChart/MarkElement.mjs +13 -6
  16. package/RadarChart/RadarAxis/RadarAxis.utils.d.mts +1 -1
  17. package/RadarChart/RadarAxis/RadarAxis.utils.d.ts +1 -1
  18. package/RadarChart/RadarChart.js +1 -1
  19. package/RadarChart/RadarChart.mjs +1 -1
  20. package/RadarChart/RadarSeriesPlot/RadarSeriesMarks.js +6 -2
  21. package/RadarChart/RadarSeriesPlot/RadarSeriesMarks.mjs +6 -2
  22. package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.js +2 -1
  23. package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.mjs +2 -1
  24. package/ScatterChart/ScatterChart.js +1 -1
  25. package/ScatterChart/ScatterChart.mjs +1 -1
  26. package/SparkLineChart/SparkLineChart.js +1 -1
  27. package/SparkLineChart/SparkLineChart.mjs +1 -1
  28. package/constants/index.d.mts +3 -1
  29. package/constants/index.d.ts +3 -1
  30. package/constants/index.js +5 -2
  31. package/constants/index.mjs +4 -1
  32. package/hooks/animation/index.d.mts +1 -0
  33. package/hooks/animation/index.d.ts +1 -0
  34. package/hooks/animation/index.js +11 -0
  35. package/hooks/animation/index.mjs +1 -0
  36. package/hooks/animation/useAnimateMark.d.mts +25 -0
  37. package/hooks/animation/useAnimateMark.d.ts +25 -0
  38. package/hooks/animation/useAnimateMark.js +45 -0
  39. package/hooks/animation/useAnimateMark.mjs +39 -0
  40. package/index.js +1 -1
  41. package/index.mjs +1 -1
  42. package/internals/domUtils.js +17 -16
  43. package/internals/domUtils.mjs +17 -15
  44. package/internals/ellipsize.d.mts +30 -0
  45. package/internals/ellipsize.d.ts +30 -0
  46. package/internals/ellipsize.js +60 -0
  47. package/internals/ellipsize.mjs +59 -0
  48. package/internals/index.d.mts +1 -0
  49. package/internals/index.d.ts +1 -0
  50. package/internals/index.js +8 -0
  51. package/internals/index.mjs +1 -0
  52. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.d.mts +3 -0
  53. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.d.ts +3 -0
  54. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.js +9 -5
  55. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisAutoSize.mjs +9 -5
  56. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartAxisAutoSize.selectors.js +9 -4
  57. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartAxisAutoSize.selectors.mjs +9 -4
  58. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.js +75 -3
  59. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.mjs +76 -3
  60. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.mts +6 -2
  61. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.ts +6 -2
  62. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.d.mts +1 -0
  63. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisLayout.selectors.d.ts +1 -0
  64. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.js +44 -11
  65. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.mjs +44 -11
  66. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.d.mts +18 -0
  67. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.d.ts +18 -0
  68. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.js +65 -0
  69. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getItemAtRotationIndex.mjs +60 -0
  70. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +43 -1
  71. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.mjs +43 -1
  72. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.types.d.mts +3 -2
  73. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.types.d.ts +3 -2
  74. package/internals/useDefaultTickLabelStyle.d.mts +7 -0
  75. package/internals/useDefaultTickLabelStyle.d.ts +7 -0
  76. package/internals/useDefaultTickLabelStyle.js +34 -0
  77. package/internals/useDefaultTickLabelStyle.mjs +28 -0
  78. package/package.json +6 -6
@@ -13,6 +13,9 @@ import { selectorChartSeriesProcessed } from "../../corePlugins/useChartSeries/i
13
13
  import { selectorChartXAxis, selectorChartYAxis } from "../useChartCartesianAxis/useChartCartesianAxisRendering.selectors.mjs";
14
14
  import { getChartPoint } from "../../../getChartPoint.mjs";
15
15
  import { getItemAtAxisPosition } from "./utils/getItemAtAxisPosition.mjs";
16
+ import { getItemAtRotationIndex } from "./utils/getItemAtRotationIndex.mjs";
17
+ import { selectorChartRotationAxis } from "../useChartPolarAxis/useChartPolarAxis.selectors.mjs";
18
+ import { selectorChartsInteractionRotationAxisIndex } from "../useChartPolarAxis/useChartPolarInteraction.selectors.mjs";
16
19
  import { findItemActivationHandler, isItemActivationKey } from "./itemActivation.mjs";
17
20
  import { selectorChartsIsFocusVisible, selectorChartsIsKeyboardActivationEnabled } from "./useChartKeyboardNavigation.selectors.mjs";
18
21
 
@@ -131,30 +134,55 @@ export const useChartKeyboardNavigation = ({
131
134
  });
132
135
 
133
136
  /**
134
- * The item a click landed on, read from the item the pointer is over. Falls back to the axis
135
- * under the pointer, which covers the line and area paths, whose hovered item only knows its
136
- * series.
137
+ * The item a click landed on, read from the item the pointer is over. An area or line path only
138
+ * knows its series, and a radar reports no item at all, so an incomplete one falls back to the
139
+ * axis under the pointer.
137
140
  *
138
141
  * A click that resolves nothing is left alone rather than focusing the chart. The drawing area
139
142
  * is a rectangle, but the data rarely fills it: taking the focus from a click next to a pie,
140
143
  * outside its circle, reads as the chart grabbing clicks that were not meant for it.
141
144
  */
142
145
  const resolveItemAtPointer = useEventCallback(event => {
143
- // Every series reports the item under the pointer, so the click itself needs no wiring.
146
+ const seriesConfig = selectorChartSeriesConfig(store.state);
144
147
  const hoveredItem = store.state.interaction?.hoveredItem;
145
- if (hoveredItem != null) {
146
- return hoveredItem;
148
+ // Cleaned before the check, because what a series stores is not always an identifier: the
149
+ // scatter reports its whole data point, whose optional `id` would read as an incomplete one.
150
+ const cleanedHoveredItem = hoveredItem == null ? null : cleanIdentifier(seriesConfig, hoveredItem);
151
+
152
+ // Series that report a complete item need no further wiring.
153
+ if (cleanedHoveredItem != null && isCompleteFocusIdentifier(cleanedHoveredItem)) {
154
+ return cleanedHoveredItem;
147
155
  }
148
156
  const element = chartsLayerContainerRef.current;
149
157
  const point = element === null ? null : getChartPoint(element, event);
150
- const item = point && instance.isPointInside?.(point.x, point.y) ? getItemAtAxisPosition({
158
+ if (!point || !instance.isPointInside?.(point.x, point.y)) {
159
+ return null;
160
+ }
161
+ const processedSeries = selectorChartSeriesProcessed(store.state);
162
+ // An incomplete hovered item still names the series under the pointer, which is a better
163
+ // target than the focused one: a click on a series should stay on it.
164
+ const focusedItem = cleanedHoveredItem ?? store.state.keyboardNavigation.item;
165
+ const item = getItemAtAxisPosition({
151
166
  point,
152
167
  xAxis: selectorChartXAxis(store.state),
153
168
  yAxis: selectorChartYAxis(store.state),
154
- processedSeries: selectorChartSeriesProcessed(store.state),
155
- focusedItem: store.state.keyboardNavigation.item
156
- }) : null;
157
- return item;
169
+ processedSeries,
170
+ focusedItem
171
+ });
172
+ if (item !== null) {
173
+ return item;
174
+ }
175
+
176
+ // A radar area only covers the polygon the data draws, so a click inside the chart but outside
177
+ // it resolves nothing above. Fall back to the rotation axis, the same one the highlight uses.
178
+ if (selectorChartRotationAxis(store.state).axisIds.length === 0) {
179
+ return null;
180
+ }
181
+ return getItemAtRotationIndex({
182
+ dataIndex: selectorChartsInteractionRotationAxisIndex(store.state),
183
+ processedSeries,
184
+ focusedItem
185
+ });
158
186
  });
159
187
  const activationRegistrationsRef = React.useRef(new Map());
160
188
  const nextRegistrationIdRef = React.useRef(0);
@@ -234,6 +262,11 @@ export const useChartKeyboardNavigation = ({
234
262
  handler(event, focusedItem);
235
263
  }
236
264
  function keyboardHandler(event) {
265
+ // Item navigation only uses unmodified keys.
266
+ // Modified ones are left to the browser, and to chart interactions such as keyboard zoom and pan.
267
+ if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
268
+ return;
269
+ }
237
270
  let newFocusedItem = store.state.keyboardNavigation.item;
238
271
  const seriesConfig = selectorChartSeriesConfig(store.state);
239
272
  let seriesType = newFocusedItem?.type;
@@ -0,0 +1,18 @@
1
+ import type { ChartSeriesType } from "../../../../../models/seriesType/config.mjs";
2
+ import type { FocusedItemIdentifier } from "../../../../../models/seriesType/index.mjs";
3
+ import type { ProcessedSeries } from "../../../corePlugins/useChartSeries/useChartSeries.types.mjs";
4
+ /**
5
+ * Resolves the item a click falls on from the rotation axis index, for charts with no cartesian
6
+ * axis to fall back to. Keeps the focused series when there is one.
7
+ *
8
+ * The index comes from the axis highlight, so a click between two spokes picks the one it shows.
9
+ */
10
+ export declare function getItemAtRotationIndex({
11
+ dataIndex,
12
+ processedSeries,
13
+ focusedItem
14
+ }: {
15
+ dataIndex: number | null;
16
+ processedSeries: ProcessedSeries<ChartSeriesType>;
17
+ focusedItem: FocusedItemIdentifier<ChartSeriesType> | null;
18
+ }): FocusedItemIdentifier<ChartSeriesType> | null;
@@ -0,0 +1,18 @@
1
+ import type { ChartSeriesType } from "../../../../../models/seriesType/config.js";
2
+ import type { FocusedItemIdentifier } from "../../../../../models/seriesType/index.js";
3
+ import type { ProcessedSeries } from "../../../corePlugins/useChartSeries/useChartSeries.types.js";
4
+ /**
5
+ * Resolves the item a click falls on from the rotation axis index, for charts with no cartesian
6
+ * axis to fall back to. Keeps the focused series when there is one.
7
+ *
8
+ * The index comes from the axis highlight, so a click between two spokes picks the one it shows.
9
+ */
10
+ export declare function getItemAtRotationIndex({
11
+ dataIndex,
12
+ processedSeries,
13
+ focusedItem
14
+ }: {
15
+ dataIndex: number | null;
16
+ processedSeries: ProcessedSeries<ChartSeriesType>;
17
+ focusedItem: FocusedItemIdentifier<ChartSeriesType> | null;
18
+ }): FocusedItemIdentifier<ChartSeriesType> | null;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getItemAtRotationIndex = getItemAtRotationIndex;
7
+ var _getNonEmptySeriesArray = require("./getNonEmptySeriesArray");
8
+ var _findVisibleDataIndex = require("./findVisibleDataIndex");
9
+ /** Series drawn against a rotation axis, and navigable with the keyboard. */
10
+ const rotationSeriesTypes = new Set(['radar']);
11
+
12
+ /**
13
+ * Resolves the item a click falls on from the rotation axis index, for charts with no cartesian
14
+ * axis to fall back to. Keeps the focused series when there is one.
15
+ *
16
+ * The index comes from the axis highlight, so a click between two spokes picks the one it shows.
17
+ */
18
+ function getItemAtRotationIndex({
19
+ dataIndex,
20
+ processedSeries,
21
+ focusedItem
22
+ }) {
23
+ if (dataIndex === null || dataIndex < 0) {
24
+ return null;
25
+ }
26
+ const target = getTargetSeries(processedSeries, focusedItem);
27
+ if (target === null) {
28
+ return null;
29
+ }
30
+ const data = processedSeries[target.type]?.series[target.seriesId]?.data;
31
+ if (!data || data.length === 0) {
32
+ return null;
33
+ }
34
+
35
+ // The axis can be longer than the series it is shared with, and the index may be hidden.
36
+ const findVisible = direction => (0, _findVisibleDataIndex.findVisibleDataIndex)({
37
+ processedSeries,
38
+ type: target.type,
39
+ seriesId: target.seriesId,
40
+ startIndex: Math.min(dataIndex, data.length - 1),
41
+ dataLength: data.length,
42
+ direction,
43
+ allowCycles: false
44
+ });
45
+ const visibleDataIndex = findVisible(1) ?? findVisible(-1);
46
+ if (visibleDataIndex === null) {
47
+ return null;
48
+ }
49
+ return {
50
+ type: target.type,
51
+ seriesId: target.seriesId,
52
+ dataIndex: visibleDataIndex
53
+ };
54
+ }
55
+
56
+ /** The focused series when it is drawn against a rotation axis, the first one with data otherwise. */
57
+ function getTargetSeries(processedSeries, focusedItem) {
58
+ if (focusedItem != null && rotationSeriesTypes.has(focusedItem.type) && processedSeries[focusedItem.type]?.series[focusedItem.seriesId] !== undefined) {
59
+ return {
60
+ type: focusedItem.type,
61
+ seriesId: focusedItem.seriesId
62
+ };
63
+ }
64
+ return (0, _getNonEmptySeriesArray.getNonEmptySeriesArray)(processedSeries, rotationSeriesTypes)[0] ?? null;
65
+ }
@@ -0,0 +1,60 @@
1
+ import { getNonEmptySeriesArray } from "./getNonEmptySeriesArray.mjs";
2
+ import { findVisibleDataIndex } from "./findVisibleDataIndex.mjs";
3
+
4
+ /** Series drawn against a rotation axis, and navigable with the keyboard. */
5
+ const rotationSeriesTypes = new Set(['radar']);
6
+
7
+ /**
8
+ * Resolves the item a click falls on from the rotation axis index, for charts with no cartesian
9
+ * axis to fall back to. Keeps the focused series when there is one.
10
+ *
11
+ * The index comes from the axis highlight, so a click between two spokes picks the one it shows.
12
+ */
13
+ export function getItemAtRotationIndex({
14
+ dataIndex,
15
+ processedSeries,
16
+ focusedItem
17
+ }) {
18
+ if (dataIndex === null || dataIndex < 0) {
19
+ return null;
20
+ }
21
+ const target = getTargetSeries(processedSeries, focusedItem);
22
+ if (target === null) {
23
+ return null;
24
+ }
25
+ const data = processedSeries[target.type]?.series[target.seriesId]?.data;
26
+ if (!data || data.length === 0) {
27
+ return null;
28
+ }
29
+
30
+ // The axis can be longer than the series it is shared with, and the index may be hidden.
31
+ const findVisible = direction => findVisibleDataIndex({
32
+ processedSeries,
33
+ type: target.type,
34
+ seriesId: target.seriesId,
35
+ startIndex: Math.min(dataIndex, data.length - 1),
36
+ dataLength: data.length,
37
+ direction,
38
+ allowCycles: false
39
+ });
40
+ const visibleDataIndex = findVisible(1) ?? findVisible(-1);
41
+ if (visibleDataIndex === null) {
42
+ return null;
43
+ }
44
+ return {
45
+ type: target.type,
46
+ seriesId: target.seriesId,
47
+ dataIndex: visibleDataIndex
48
+ };
49
+ }
50
+
51
+ /** The focused series when it is drawn against a rotation axis, the first one with data otherwise. */
52
+ function getTargetSeries(processedSeries, focusedItem) {
53
+ if (focusedItem != null && rotationSeriesTypes.has(focusedItem.type) && processedSeries[focusedItem.type]?.series[focusedItem.seriesId] !== undefined) {
54
+ return {
55
+ type: focusedItem.type,
56
+ seriesId: focusedItem.seriesId
57
+ };
58
+ }
59
+ return getNonEmptySeriesArray(processedSeries, rotationSeriesTypes)[0] ?? null;
60
+ }
@@ -10,6 +10,7 @@ exports.useChartPolarAxis = void 0;
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
  var React = _interopRequireWildcard(require("react"));
12
12
  var _warning = require("@mui/x-internals/warning");
13
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
13
14
  var _useChartDimensions = require("../../corePlugins/useChartDimensions/useChartDimensions.selectors");
14
15
  var _defaultizeAxis = require("./defaultizeAxis");
15
16
  var _useChartInteraction = require("../useChartInteraction");
@@ -20,6 +21,7 @@ var _getAxisIndex = require("./getAxisIndex");
20
21
  var _useChartSeries = require("../../corePlugins/useChartSeries");
21
22
  var _checkHasInteractionPlugin = require("../useChartInteraction/checkHasInteractionPlugin");
22
23
  var _getPolarAxisClickPayload = require("./getPolarAxisClickPayload");
24
+ var _useChartKeyboardNavigation = require("../useChartKeyboardNavigation");
23
25
  const useChartPolarAxis = ({
24
26
  params,
25
27
  store,
@@ -205,7 +207,47 @@ const useChartPolarAxis = ({
205
207
  return () => {
206
208
  axisClickHandler.cleanup();
207
209
  };
208
- }, [center, instance, params.onAxisClick, processedSeries, radiusAxisWithScale, rotationAxisWithScale, chartsLayerContainerRef, usedRadiusAxisId, usedRotationAxisId]);
210
+ }, [center, instance, params.onAxisClick, processedSeries, store, radiusAxisWithScale, rotationAxisWithScale, chartsLayerContainerRef, usedRadiusAxisId, usedRotationAxisId]);
211
+
212
+ /**
213
+ * Kept out of the pointer effect so the listener survives re-renders. See the cartesian axis
214
+ * plugin for why re-subscribing per render drops keystrokes.
215
+ */
216
+ const handleKeyboardActivation = (0, _useEventCallback.default)(event => {
217
+ const onAxisClick = params.onAxisClick;
218
+ if (!onAxisClick ||
219
+ // Ignore the auto-repeat while the key is held: a pointer click does not repeat either.
220
+ event.repeat || !(0, _useChartKeyboardNavigation.isItemActivationKey)(event) || !(0, _useChartKeyboardNavigation.selectorChartsIsKeyboardActivationEnabled)(store.state)) {
221
+ return;
222
+ }
223
+ const focusedItem = (0, _useChartKeyboardNavigation.selectorChartsFocusedItem)(store.state);
224
+ if (focusedItem === null || !('dataIndex' in focusedItem)) {
225
+ return;
226
+ }
227
+ const payload = (0, _getPolarAxisClickPayload.getPolarAxisClickPayload)({
228
+ dataIndex: focusedItem.dataIndex,
229
+ isRotationAxis: true,
230
+ rotationAxes: (0, _useChartPolarAxis.selectorChartRotationAxis)(store.state),
231
+ radiusAxes: (0, _useChartPolarAxis.selectorChartRadiusAxis)(store.state),
232
+ processedSeries: (0, _useChartSeries.selectorChartSeriesProcessed)(store.state)
233
+ });
234
+ if (payload === null) {
235
+ return;
236
+ }
237
+ event.preventDefault();
238
+ // The callback only describes the pointer event unless the user augments the types.
239
+ onAxisClick(event, payload);
240
+ });
241
+ React.useEffect(() => {
242
+ const element = chartsLayerContainerRef.current;
243
+ if (element === null) {
244
+ return undefined;
245
+ }
246
+ element.addEventListener('keydown', handleKeyboardActivation);
247
+ return () => {
248
+ element.removeEventListener('keydown', handleKeyboardActivation);
249
+ };
250
+ }, [chartsLayerContainerRef, handleKeyboardActivation]);
209
251
  return {
210
252
  instance: {
211
253
  svg2polar,
@@ -3,6 +3,7 @@
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import { warnOnce } from '@mui/x-internals/warning';
6
+ import useEventCallback from '@mui/utils/useEventCallback';
6
7
  import { selectorChartDrawingArea } from "../../corePlugins/useChartDimensions/useChartDimensions.selectors.mjs";
7
8
  import { defaultizeAxis } from "./defaultizeAxis.mjs";
8
9
  import { selectorChartsInteractionIsInitialized } from "../useChartInteraction/index.mjs";
@@ -13,6 +14,7 @@ import { getRadiusAxisIndex, getRotationAxisIndex } from "./getAxisIndex.mjs";
13
14
  import { selectorChartSeriesProcessed } from "../../corePlugins/useChartSeries/index.mjs";
14
15
  import { checkHasInteractionPlugin } from "../useChartInteraction/checkHasInteractionPlugin.mjs";
15
16
  import { getPolarAxisClickPayload } from "./getPolarAxisClickPayload.mjs";
17
+ import { isItemActivationKey, selectorChartsFocusedItem, selectorChartsIsKeyboardActivationEnabled } from "../useChartKeyboardNavigation/index.mjs";
16
18
  export const useChartPolarAxis = ({
17
19
  params,
18
20
  store,
@@ -198,7 +200,47 @@ export const useChartPolarAxis = ({
198
200
  return () => {
199
201
  axisClickHandler.cleanup();
200
202
  };
201
- }, [center, instance, params.onAxisClick, processedSeries, radiusAxisWithScale, rotationAxisWithScale, chartsLayerContainerRef, usedRadiusAxisId, usedRotationAxisId]);
203
+ }, [center, instance, params.onAxisClick, processedSeries, store, radiusAxisWithScale, rotationAxisWithScale, chartsLayerContainerRef, usedRadiusAxisId, usedRotationAxisId]);
204
+
205
+ /**
206
+ * Kept out of the pointer effect so the listener survives re-renders. See the cartesian axis
207
+ * plugin for why re-subscribing per render drops keystrokes.
208
+ */
209
+ const handleKeyboardActivation = useEventCallback(event => {
210
+ const onAxisClick = params.onAxisClick;
211
+ if (!onAxisClick ||
212
+ // Ignore the auto-repeat while the key is held: a pointer click does not repeat either.
213
+ event.repeat || !isItemActivationKey(event) || !selectorChartsIsKeyboardActivationEnabled(store.state)) {
214
+ return;
215
+ }
216
+ const focusedItem = selectorChartsFocusedItem(store.state);
217
+ if (focusedItem === null || !('dataIndex' in focusedItem)) {
218
+ return;
219
+ }
220
+ const payload = getPolarAxisClickPayload({
221
+ dataIndex: focusedItem.dataIndex,
222
+ isRotationAxis: true,
223
+ rotationAxes: selectorChartRotationAxis(store.state),
224
+ radiusAxes: selectorChartRadiusAxis(store.state),
225
+ processedSeries: selectorChartSeriesProcessed(store.state)
226
+ });
227
+ if (payload === null) {
228
+ return;
229
+ }
230
+ event.preventDefault();
231
+ // The callback only describes the pointer event unless the user augments the types.
232
+ onAxisClick(event, payload);
233
+ });
234
+ React.useEffect(() => {
235
+ const element = chartsLayerContainerRef.current;
236
+ if (element === null) {
237
+ return undefined;
238
+ }
239
+ element.addEventListener('keydown', handleKeyboardActivation);
240
+ return () => {
241
+ element.removeEventListener('keydown', handleKeyboardActivation);
242
+ };
243
+ }, [chartsLayerContainerRef, handleKeyboardActivation]);
202
244
  return {
203
245
  instance: {
204
246
  svg2polar,
@@ -3,6 +3,7 @@ import type { ChartSeriesType, DatasetType } from "../../../../models/seriesType
3
3
  import type { ScaleName, PolarAxisConfig, ChartsRotationAxisProps, ChartsRadiusAxisProps, RadiusAxis, RotationAxis, ChartsAxisData } from "../../../../models/axis.mjs";
4
4
  import type { UseChartSeriesSignature } from "../../corePlugins/useChartSeries/index.mjs";
5
5
  import type { UseChartInteractionSignature } from "../useChartInteraction/index.mjs";
6
+ import type { ChartsActivationEvent } from "../../../../models/events.mjs";
6
7
  export interface UseChartPolarAxisInstance {
7
8
  /**
8
9
  * Transform (rotation, radius) to the SVG (x, y).
@@ -52,10 +53,10 @@ export interface UseChartPolarAxisParameters {
52
53
  /**
53
54
  * The function called for onClick events.
54
55
  * The second argument contains information about all line/bar elements at the current mouse position.
55
- * @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
56
+ * @param {ChartsActivationEvent} event The event recorded on the `<svg/>` element.
56
57
  * @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
57
58
  */
58
- onAxisClick?: (event: MouseEvent, data: null | ChartsAxisData) => void;
59
+ onAxisClick?: (event: ChartsActivationEvent, data: null | ChartsAxisData) => void;
59
60
  }
60
61
  export type UseChartPolarAxisDefaultizedParameters = UseChartPolarAxisParameters & {};
61
62
  export interface UseChartPolarAxisState {
@@ -3,6 +3,7 @@ import type { ChartSeriesType, DatasetType } from "../../../../models/seriesType
3
3
  import type { ScaleName, PolarAxisConfig, ChartsRotationAxisProps, ChartsRadiusAxisProps, RadiusAxis, RotationAxis, ChartsAxisData } from "../../../../models/axis.js";
4
4
  import type { UseChartSeriesSignature } from "../../corePlugins/useChartSeries/index.js";
5
5
  import type { UseChartInteractionSignature } from "../useChartInteraction/index.js";
6
+ import type { ChartsActivationEvent } from "../../../../models/events.js";
6
7
  export interface UseChartPolarAxisInstance {
7
8
  /**
8
9
  * Transform (rotation, radius) to the SVG (x, y).
@@ -52,10 +53,10 @@ export interface UseChartPolarAxisParameters {
52
53
  /**
53
54
  * The function called for onClick events.
54
55
  * The second argument contains information about all line/bar elements at the current mouse position.
55
- * @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
56
+ * @param {ChartsActivationEvent} event The event recorded on the `<svg/>` element.
56
57
  * @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
57
58
  */
58
- onAxisClick?: (event: MouseEvent, data: null | ChartsAxisData) => void;
59
+ onAxisClick?: (event: ChartsActivationEvent, data: null | ChartsAxisData) => void;
59
60
  }
60
61
  export type UseChartPolarAxisDefaultizedParameters = UseChartPolarAxisParameters & {};
61
62
  export interface UseChartPolarAxisState {
@@ -0,0 +1,7 @@
1
+ import type { ChartsTextStyle } from "./getWordsByLines.mjs";
2
+ /**
3
+ * The font the axes render their tick labels with.
4
+ * Axis auto-sizing measures outside React, so it cannot read the theme itself and needs this handed
5
+ * to it. Keep in sync with the style `useAxisTicksProps` renders the ticks with.
6
+ */
7
+ export declare function useDefaultTickLabelStyle(): ChartsTextStyle;
@@ -0,0 +1,7 @@
1
+ import type { ChartsTextStyle } from "./getWordsByLines.js";
2
+ /**
3
+ * The font the axes render their tick labels with.
4
+ * Axis auto-sizing measures outside React, so it cannot read the theme itself and needs this handed
5
+ * to it. Keep in sync with the style `useAxisTicksProps` renders the ticks with.
6
+ */
7
+ export declare function useDefaultTickLabelStyle(): ChartsTextStyle;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.useDefaultTickLabelStyle = useDefaultTickLabelStyle;
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _styles = require("@mui/material/styles");
11
+ var _constants = require("../constants");
12
+ /**
13
+ * The font the axes render their tick labels with.
14
+ * Axis auto-sizing measures outside React, so it cannot read the theme itself and needs this handed
15
+ * to it. Keep in sync with the style `useAxisTicksProps` renders the ticks with.
16
+ */
17
+ function useDefaultTickLabelStyle() {
18
+ const theme = (0, _styles.useTheme)();
19
+ const {
20
+ fontFamily,
21
+ fontStyle,
22
+ fontWeight,
23
+ letterSpacing,
24
+ textTransform
25
+ } = theme.typography.caption;
26
+ return React.useMemo(() => ({
27
+ fontFamily,
28
+ fontStyle,
29
+ fontWeight,
30
+ letterSpacing,
31
+ textTransform,
32
+ fontSize: _constants.DEFAULT_TICK_LABEL_FONT_SIZE
33
+ }), [fontFamily, fontStyle, fontWeight, letterSpacing, textTransform]);
34
+ }
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { useTheme } from '@mui/material/styles';
5
+ import { DEFAULT_TICK_LABEL_FONT_SIZE } from "../constants/index.mjs";
6
+ /**
7
+ * The font the axes render their tick labels with.
8
+ * Axis auto-sizing measures outside React, so it cannot read the theme itself and needs this handed
9
+ * to it. Keep in sync with the style `useAxisTicksProps` renders the ticks with.
10
+ */
11
+ export function useDefaultTickLabelStyle() {
12
+ const theme = useTheme();
13
+ const {
14
+ fontFamily,
15
+ fontStyle,
16
+ fontWeight,
17
+ letterSpacing,
18
+ textTransform
19
+ } = theme.typography.caption;
20
+ return React.useMemo(() => ({
21
+ fontFamily,
22
+ fontStyle,
23
+ fontWeight,
24
+ letterSpacing,
25
+ textTransform,
26
+ fontSize: DEFAULT_TICK_LABEL_FONT_SIZE
27
+ }), [fontFamily, fontStyle, fontWeight, letterSpacing, textTransform]);
28
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-charts",
3
- "version": "9.12.0",
3
+ "version": "9.13.0",
4
4
  "author": "MUI Team",
5
5
  "description": "The community edition of MUI X Charts components.",
6
6
  "license": "MIT",
@@ -28,15 +28,15 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@babel/runtime": "^7.29.7",
31
- "@mui/utils": "^9.3.0",
31
+ "@mui/utils": "^9.4.0",
32
+ "@mui/x-charts-vendor": "^9.13.0",
33
+ "@mui/x-internal-gestures": "^9.13.0",
34
+ "@mui/x-internals": "^9.13.0",
32
35
  "bezier-easing": "^3.0.1",
33
36
  "clsx": "^2.1.1",
34
37
  "prop-types": "^15.8.1",
35
38
  "reselect": "^5.2.0",
36
- "use-sync-external-store": "^1.6.0",
37
- "@mui/x-charts-vendor": "^9.11.1",
38
- "@mui/x-internals": "^9.12.0",
39
- "@mui/x-internal-gestures": "^9.12.0"
39
+ "use-sync-external-store": "^1.6.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@emotion/react": "^11.9.0",