@mui/x-charts 8.17.0 → 8.19.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 (134) hide show
  1. package/BarChart/BarLabel/BarLabel.d.ts +7 -1
  2. package/BarChart/BarLabel/BarLabel.js +41 -4
  3. package/BarChart/BarLabel/BarLabelItem.d.ts +6 -0
  4. package/BarChart/BarLabel/BarLabelItem.js +4 -2
  5. package/BarChart/BarLabel/BarLabelPlot.js +2 -3
  6. package/BarChart/BarPlot.js +5 -0
  7. package/BarChart/seriesConfig/bar/seriesProcessor.js +15 -9
  8. package/BarChart/types.d.ts +1 -0
  9. package/BarChart/useBarPlotData.js +3 -2
  10. package/CHANGELOG.md +213 -0
  11. package/ChartsSurface/ChartsSurface.js +5 -2
  12. package/LineChart/seriesConfig/seriesProcessor.js +15 -10
  13. package/PieChart/PieArcPlot.js +5 -3
  14. package/esm/BarChart/BarLabel/BarLabel.d.ts +7 -1
  15. package/esm/BarChart/BarLabel/BarLabel.js +41 -4
  16. package/esm/BarChart/BarLabel/BarLabelItem.d.ts +6 -0
  17. package/esm/BarChart/BarLabel/BarLabelItem.js +4 -2
  18. package/esm/BarChart/BarLabel/BarLabelPlot.js +2 -2
  19. package/esm/BarChart/BarPlot.js +5 -0
  20. package/esm/BarChart/seriesConfig/bar/seriesProcessor.js +15 -9
  21. package/esm/BarChart/types.d.ts +1 -0
  22. package/esm/BarChart/useBarPlotData.js +3 -2
  23. package/esm/ChartsSurface/ChartsSurface.js +5 -2
  24. package/esm/LineChart/seriesConfig/seriesProcessor.js +15 -10
  25. package/esm/PieChart/PieArcPlot.js +5 -3
  26. package/esm/hooks/animation/useAnimateBarLabel.d.ts +1 -1
  27. package/esm/hooks/animation/useAnimateBarLabel.js +61 -12
  28. package/esm/hooks/useAxis.d.ts +116 -16
  29. package/esm/hooks/useAxis.js +122 -18
  30. package/esm/hooks/useBarSeries.js +3 -5
  31. package/esm/hooks/useLineSeries.js +3 -5
  32. package/esm/hooks/usePieSeries.js +3 -5
  33. package/esm/hooks/useRadarSeries.js +3 -5
  34. package/esm/hooks/useScale.d.ts +25 -6
  35. package/esm/hooks/useScale.js +29 -8
  36. package/esm/hooks/useScatterSeries.js +3 -5
  37. package/esm/index.d.ts +2 -1
  38. package/esm/index.js +2 -1
  39. package/esm/internals/domUtils.js +30 -14
  40. package/esm/internals/getScale.d.ts +2 -1
  41. package/esm/internals/index.d.ts +1 -1
  42. package/esm/internals/index.js +1 -1
  43. package/esm/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.selectors.js +2 -2
  44. package/esm/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors.js +5 -6
  45. package/esm/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.selectors.js +2 -2
  46. package/esm/internals/plugins/corePlugins/useChartId/useChartId.selectors.js +2 -2
  47. package/esm/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.js +4 -1
  48. package/esm/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.types.d.ts +3 -1
  49. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.d.ts +1 -1
  50. package/esm/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.js +4 -4
  51. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.d.ts +1 -1
  52. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.js +15 -15
  53. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.ts +1 -1
  54. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisPreview.selectors.js +5 -5
  55. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +3 -0
  56. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +11 -11
  57. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianHighlight.selectors.js +5 -6
  58. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.js +7 -8
  59. package/esm/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.js +2 -2
  60. package/esm/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.selectors.js +2 -2
  61. package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +11 -12
  62. package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.selectors.js +8 -8
  63. package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartTooltip.selectors.js +4 -4
  64. package/esm/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.js +11 -11
  65. package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors.js +6 -6
  66. package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarInteraction.selectors.js +7 -8
  67. package/esm/internals/plugins/featurePlugins/useChartZAxis/useChartZAxis.selectors.js +2 -2
  68. package/esm/internals/plugins/utils/selectors.d.ts +1 -14
  69. package/esm/internals/plugins/utils/selectors.js +1 -5
  70. package/esm/internals/seriesSelectorOfType.d.ts +20 -0
  71. package/esm/internals/seriesSelectorOfType.js +38 -0
  72. package/esm/models/seriesType/bar.d.ts +7 -0
  73. package/esm/models/seriesType/config.d.ts +2 -2
  74. package/esm/utils/index.d.ts +4 -0
  75. package/esm/utils/index.js +5 -0
  76. package/esm/utils/niceDomain.d.ts +20 -0
  77. package/esm/utils/niceDomain.js +24 -0
  78. package/hooks/animation/useAnimateBarLabel.d.ts +1 -1
  79. package/hooks/animation/useAnimateBarLabel.js +61 -12
  80. package/hooks/useAxis.d.ts +116 -16
  81. package/hooks/useAxis.js +122 -18
  82. package/hooks/useBarSeries.js +3 -6
  83. package/hooks/useLineSeries.js +3 -6
  84. package/hooks/usePieSeries.js +3 -6
  85. package/hooks/useRadarSeries.js +3 -6
  86. package/hooks/useScale.d.ts +25 -6
  87. package/hooks/useScale.js +29 -8
  88. package/hooks/useScatterSeries.js +3 -6
  89. package/index.d.ts +2 -1
  90. package/index.js +13 -1
  91. package/internals/domUtils.js +30 -14
  92. package/internals/getScale.d.ts +2 -1
  93. package/internals/index.d.ts +1 -1
  94. package/internals/index.js +4 -4
  95. package/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.selectors.js +2 -2
  96. package/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors.js +4 -5
  97. package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.selectors.js +2 -2
  98. package/internals/plugins/corePlugins/useChartId/useChartId.selectors.js +2 -2
  99. package/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.js +4 -1
  100. package/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.types.d.ts +3 -1
  101. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.d.ts +1 -1
  102. package/internals/plugins/corePlugins/useChartSeries/useChartSeries.selectors.js +4 -4
  103. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.d.ts +1 -1
  104. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.js +15 -15
  105. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.ts +1 -1
  106. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisPreview.selectors.js +5 -5
  107. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +3 -0
  108. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +11 -11
  109. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianHighlight.selectors.js +4 -5
  110. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.js +6 -7
  111. package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.js +2 -2
  112. package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.selectors.js +2 -2
  113. package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +10 -11
  114. package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.selectors.js +8 -8
  115. package/internals/plugins/featurePlugins/useChartInteraction/useChartTooltip.selectors.js +4 -4
  116. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.js +11 -11
  117. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.selectors.js +6 -6
  118. package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarInteraction.selectors.js +6 -7
  119. package/internals/plugins/featurePlugins/useChartZAxis/useChartZAxis.selectors.js +2 -2
  120. package/internals/plugins/utils/selectors.d.ts +1 -14
  121. package/internals/plugins/utils/selectors.js +1 -8
  122. package/internals/seriesSelectorOfType.d.ts +20 -0
  123. package/internals/seriesSelectorOfType.js +46 -0
  124. package/models/seriesType/bar.d.ts +7 -0
  125. package/models/seriesType/config.d.ts +2 -2
  126. package/package.json +5 -5
  127. package/utils/index.d.ts +4 -0
  128. package/utils/index.js +16 -0
  129. package/utils/niceDomain.d.ts +20 -0
  130. package/utils/niceDomain.js +29 -0
  131. package/esm/internals/createSeriesSelectorOfType.d.ts +0 -4
  132. package/esm/internals/createSeriesSelectorOfType.js +0 -45
  133. package/internals/createSeriesSelectorOfType.d.ts +0 -4
  134. package/internals/createSeriesSelectorOfType.js +0 -53
@@ -26,8 +26,14 @@ export type BarLabelProps = Omit<React.SVGProps<SVGTextElement>, 'ref' | 'id' |
26
26
  * Height of the bar this label belongs to.
27
27
  */
28
28
  height: number;
29
+ /**
30
+ * The placement of the bar label.
31
+ * It controls whether the label is rendered in the center or outside the bar.
32
+ * @default 'center'
33
+ */
34
+ placement?: 'center' | 'outside';
29
35
  };
30
- declare function BarLabel(inProps: BarLabelProps): import("react/jsx-runtime").JSX.Element;
36
+ declare function BarLabel(inProps: BarLabelProps): React.JSX.Element;
31
37
  declare namespace BarLabel {
32
38
  var propTypes: any;
33
39
  }
@@ -16,7 +16,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
16
16
  var _useAnimateBarLabel = require("../../hooks/animation/useAnimateBarLabel");
17
17
  var _barLabelClasses = require("./barLabelClasses");
18
18
  var _jsxRuntime = require("react/jsx-runtime");
19
- const _excluded = ["seriesId", "dataIndex", "color", "isFaded", "isHighlighted", "classes", "skipAnimation", "layout", "xOrigin", "yOrigin"];
19
+ const _excluded = ["seriesId", "dataIndex", "color", "isFaded", "isHighlighted", "classes", "skipAnimation", "layout", "xOrigin", "yOrigin", "placement"];
20
20
  const BarLabelComponent = exports.BarLabelComponent = (0, _styles.styled)('text', {
21
21
  name: 'MuiBarLabel',
22
22
  slot: 'Root',
@@ -31,8 +31,6 @@ const BarLabelComponent = exports.BarLabelComponent = (0, _styles.styled)('text'
31
31
  stroke: 'none',
32
32
  fill: (theme.vars || theme)?.palette?.text?.primary,
33
33
  transition: 'opacity 0.2s ease-in, fill 0.2s ease-in',
34
- textAnchor: 'middle',
35
- dominantBaseline: 'central',
36
34
  pointerEvents: 'none',
37
35
  opacity: 1,
38
36
  [`&.${_barLabelClasses.barLabelClasses.faded}`]: {
@@ -46,7 +44,40 @@ function BarLabel(inProps) {
46
44
  });
47
45
  const otherProps = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
48
46
  const animatedProps = (0, _useAnimateBarLabel.useAnimateBarLabel)(props);
49
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(BarLabelComponent, (0, _extends2.default)({}, otherProps, animatedProps));
47
+ const textAnchor = getTextAnchor(props);
48
+ const dominantBaseline = getDominantBaseline(props);
49
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(BarLabelComponent, (0, _extends2.default)({
50
+ textAnchor: textAnchor,
51
+ dominantBaseline: dominantBaseline
52
+ }, otherProps, animatedProps));
53
+ }
54
+ function getTextAnchor({
55
+ placement,
56
+ layout,
57
+ xOrigin,
58
+ x
59
+ }) {
60
+ if (placement === 'outside') {
61
+ if (layout === 'horizontal') {
62
+ return x < xOrigin ? 'end' : 'start';
63
+ }
64
+ return 'middle';
65
+ }
66
+ return 'middle';
67
+ }
68
+ function getDominantBaseline({
69
+ placement,
70
+ layout,
71
+ yOrigin,
72
+ y
73
+ }) {
74
+ if (placement === 'outside') {
75
+ if (layout === 'horizontal') {
76
+ return 'central';
77
+ }
78
+ return y < yOrigin ? 'auto' : 'hanging';
79
+ }
80
+ return 'central';
50
81
  }
51
82
  process.env.NODE_ENV !== "production" ? BarLabel.propTypes = {
52
83
  // ----------------------------- Warning --------------------------------
@@ -62,6 +93,12 @@ process.env.NODE_ENV !== "production" ? BarLabel.propTypes = {
62
93
  isFaded: _propTypes.default.bool.isRequired,
63
94
  isHighlighted: _propTypes.default.bool.isRequired,
64
95
  layout: _propTypes.default.oneOf(['horizontal', 'vertical']).isRequired,
96
+ /**
97
+ * The placement of the bar label.
98
+ * It controls whether the label is rendered in the center or outside the bar.
99
+ * @default 'center'
100
+ */
101
+ placement: _propTypes.default.oneOf(['center', 'outside']),
65
102
  seriesId: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]).isRequired,
66
103
  skipAnimation: _propTypes.default.bool.isRequired,
67
104
  /**
@@ -67,6 +67,12 @@ export type BarLabelItemProps = Omit<BarLabelOwnerState, 'isFaded' | 'isHighligh
67
67
  * @returns {string} The formatted label.
68
68
  */
69
69
  barLabel?: 'value' | ((item: BarItem, context: BarLabelContext) => string | null | undefined);
70
+ /**
71
+ * The placement of the bar label.
72
+ * It controls whether the label is rendered in the center or outside the bar.
73
+ * @default 'center'
74
+ */
75
+ barLabelPlacement?: BarLabelProps['placement'];
70
76
  };
71
77
  /**
72
78
  * @ignore - internal component.
@@ -16,7 +16,7 @@ var _getBarLabel = require("./getBarLabel");
16
16
  var _BarLabel = require("./BarLabel");
17
17
  var _useItemHighlighted = require("../../hooks/useItemHighlighted");
18
18
  var _jsxRuntime = require("react/jsx-runtime");
19
- const _excluded = ["seriesId", "classes", "color", "dataIndex", "barLabel", "slots", "slotProps", "xOrigin", "yOrigin", "x", "y", "width", "height", "value", "skipAnimation", "layout"],
19
+ const _excluded = ["seriesId", "classes", "color", "dataIndex", "barLabel", "slots", "slotProps", "xOrigin", "yOrigin", "x", "y", "width", "height", "value", "skipAnimation", "layout", "barLabelPlacement"],
20
20
  _excluded2 = ["ownerState"];
21
21
  /**
22
22
  * @ignore - internal component.
@@ -38,7 +38,8 @@ function BarLabelItem(props) {
38
38
  height,
39
39
  value,
40
40
  skipAnimation,
41
- layout
41
+ layout,
42
+ barLabelPlacement
42
43
  } = props,
43
44
  other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
44
45
  const {
@@ -70,6 +71,7 @@ function BarLabelItem(props) {
70
71
  y,
71
72
  width,
72
73
  height,
74
+ placement: barLabelPlacement,
73
75
  className: classes.root
74
76
  }),
75
77
  ownerState
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.BarLabelPlot = BarLabelPlot;
9
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
9
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
11
- var React = _interopRequireWildcard(require("react"));
12
10
  var _BarLabelItem = require("./BarLabelItem");
13
11
  var _barClasses = require("../barClasses");
14
12
  var _jsxRuntime = require("react/jsx-runtime");
@@ -59,7 +57,8 @@ function BarLabelPlot(props) {
59
57
  skipAnimation: skipAnimation ?? false,
60
58
  layout: layout ?? 'vertical'
61
59
  }, other, {
62
- barLabel: barLabel
60
+ barLabel: barLabel,
61
+ barLabelPlacement: processedSeries.barLabelPlacement || 'center'
63
62
  }), dataIndex))
64
63
  }, seriesId);
65
64
  }
@@ -162,6 +162,11 @@ process.env.NODE_ENV !== "production" ? BarPlot.propTypes = {
162
162
  * @returns {string} The formatted label.
163
163
  */
164
164
  barLabel: _propTypes.default.oneOfType([_propTypes.default.oneOf(['value']), _propTypes.default.func]),
165
+ /**
166
+ * The placement of the bar label.
167
+ * It controls whether the label is rendered inside or outside the bar.
168
+ */
169
+ barLabelPlacement: _propTypes.default.oneOf(['outside', 'inside']),
165
170
  /**
166
171
  * Defines the border radius of the bar element.
167
172
  */
@@ -34,6 +34,20 @@ const seriesProcessor = (params, dataset) => {
34
34
  } else if (dataset === undefined) {
35
35
  throw new Error([`MUI X Charts: bar series with id='${id}' has no data.`, 'Either provide a data property to the series or use the dataset prop.'].join('\n'));
36
36
  }
37
+ if (process.env.NODE_ENV !== 'production') {
38
+ if (!data && dataset) {
39
+ const dataKey = series[id].dataKey;
40
+ if (!dataKey) {
41
+ throw new Error([`MUI X Charts: bar series with id='${id}' has no data and no dataKey.`, 'You must provide a dataKey when using the dataset prop.'].join('\n'));
42
+ }
43
+ dataset.forEach((entry, index) => {
44
+ const value = entry[dataKey];
45
+ if (value != null && typeof value !== 'number') {
46
+ (0, _warning.warnOnce)([`MUI X Charts: your dataset key "${dataKey}" is used for plotting bars, but the dataset contains the non-null non-numerical element "${value}" at index ${index}.`, 'Bar plots only support numeric and null values.'].join('\n'));
47
+ }
48
+ });
49
+ }
50
+ }
37
51
  });
38
52
  const completedSeries = {};
39
53
  stackingGroups.forEach(stackingGroup => {
@@ -59,15 +73,7 @@ const seriesProcessor = (params, dataset) => {
59
73
  }, series[id], {
60
74
  data: dataKey ? dataset.map(data => {
61
75
  const value = data[dataKey];
62
- if (typeof value !== 'number') {
63
- if (process.env.NODE_ENV !== 'production') {
64
- if (value !== null) {
65
- (0, _warning.warnOnce)([`MUI X Charts: your dataset key "${dataKey}" is used for plotting bars, but contains nonnumerical elements.`, 'Bar plots only support numbers and null values.']);
66
- }
67
- }
68
- return null;
69
- }
70
- return value;
76
+ return typeof value === 'number' ? value : null;
71
77
  }) : series[id].data,
72
78
  stackedData: stackedSeries[index].map(([a, b]) => [a, b])
73
79
  });
@@ -13,6 +13,7 @@ export interface ProcessedBarSeriesData {
13
13
  seriesId: SeriesId;
14
14
  data: ProcessedBarData[];
15
15
  barLabel?: BarSeriesType['barLabel'];
16
+ barLabelPlacement?: BarSeriesType['barLabelPlacement'];
16
17
  }
17
18
  export interface ProcessedBarData extends AnimationData {
18
19
  seriesId: SeriesId;
@@ -63,8 +63,8 @@ function useBarPlotData(drawingArea, xAxes, yAxes) {
63
63
  seriesId,
64
64
  dataIndex,
65
65
  layout: series[seriesId].layout,
66
- xOrigin: xScale(0) ?? 0,
67
- yOrigin: yScale(0) ?? 0
66
+ xOrigin: Math.round(xScale(0) ?? 0),
67
+ yOrigin: Math.round(yScale(0) ?? 0)
68
68
  }, barDimensions, {
69
69
  color: colorGetter(dataIndex),
70
70
  value: series[seriesId].data[dataIndex],
@@ -100,6 +100,7 @@ function useBarPlotData(drawingArea, xAxes, yAxes) {
100
100
  return {
101
101
  seriesId,
102
102
  barLabel: series[seriesId].barLabel,
103
+ barLabelPlacement: series[seriesId].barLabelPlacement,
103
104
  data: seriesDataPoints
104
105
  };
105
106
  });
package/CHANGELOG.md CHANGED
@@ -5,6 +5,219 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.19.0
9
+
10
+ _Nov 20, 2025_
11
+
12
+ We'd like to extend a big thank you to the 15 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🔎 Add pan on `wheel` to the charts zoom
15
+ - ⌨️ Allow opt-in to [tab navigation](https://mui.com/x/react-data-grid/accessibility/#tab-navigation) inside the Data Grid.
16
+ - ⚙️ New way of defining [action columns](https://mui.com/x/react-data-grid/column-definition/#ActionsWithModalGrid.tsx) in the Data Grid that makes it easier to keep `columns` prop stable.
17
+ - 🐞 Bugfixes
18
+ - 📚 Documentation improvements
19
+
20
+ Special thanks go out to these community members for their valuable contributions:
21
+ @lauri865, @noobyogi0010, @sai6855
22
+
23
+ The following team members contributed to this release:
24
+ @alexfauquette, @arminmeh, @bernardobelchior, @cherniavskii, @flaviendelangle, @Janpot, @JCQuintas, @mj12albert, @noraleonte, @rita-codes, @siriwatknp, @ZeeshanTamboli
25
+
26
+ ### Data Grid
27
+
28
+ #### `@mui/x-data-grid@8.19.0`
29
+
30
+ - [DataGrid] Add `tabNavigation` prop to control tab navigation in the grid (#20286) @arminmeh
31
+ - [DataGrid] Allow to focus disabled checkbox cells (#19959) @mj12albert
32
+ - [DataGrid] Alternative actions column definition API (#15041) @cherniavskii
33
+ - [DataGrid] Fix failing tests (#20332) @cherniavskii
34
+ - [DataGrid] Prevent Safari 26 error in the event handler (#20369) @arminmeh
35
+ - [DataGrid] Undeprecate the `autoHeight` prop (#20363) @cherniavskii
36
+ - [DataGrid] Fix print export grid dimensions with dynamic row height and print styles (#19835) @cherniavskii
37
+
38
+ #### `@mui/x-data-grid-pro@8.19.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
39
+
40
+ Same changes as in `@mui/x-data-grid@8.19.0`.
41
+
42
+ #### `@mui/x-data-grid-premium@8.19.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
43
+
44
+ Same changes as in `@mui/x-data-grid-pro@8.19.0`, plus:
45
+
46
+ - [DataGridPremium] Fix aggregation with sorting (#19892) @lauri865
47
+ - [DataGridPremium] Lock `ExcelJS` version (#20329) @cherniavskii
48
+
49
+ ### Date and Time Pickers
50
+
51
+ #### `@mui/x-date-pickers@8.19.0`
52
+
53
+ - [pickers] Do not loose `slotProps.field.slotProps` (#20322) @flaviendelangle
54
+
55
+ #### `@mui/x-date-pickers-pro@8.19.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
56
+
57
+ Same changes as in `@mui/x-date-pickers@8.19.0`.
58
+
59
+ ### Charts
60
+
61
+ #### `@mui/x-charts@8.19.0`
62
+
63
+ - [charts] Expose `niceDomain` utility (#20250) @bernardobelchior
64
+ - [charts] Fix benchmark regression by downgrading to JSDOM v26 (#20405) @bernardobelchior
65
+ - [charts] Fix Pie Chart keyboard focus highlight (#20358) @JCQuintas
66
+ - [charts] Memoize series selectors (#20326) @JCQuintas
67
+ - [charts] Relax dataset type (#20294) @bernardobelchior
68
+ - [charts] Remove `touch-action: pan-y` when zoom is disabled (#20204) @bernardobelchior
69
+ - [charts] Use `getBBox()` for correct SVG sizes in firefox (#20309) @JCQuintas
70
+ - [charts] Use directly selector from `@mui/x-internals` (#20365) @alexfauquette
71
+ - [charts] Fix unnecessary errors in dev mode (#20380) @JCQuintas
72
+
73
+ #### `@mui/x-charts-pro@8.19.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
74
+
75
+ Same changes as in `@mui/x-charts@8.19.0`, plus:
76
+
77
+ - [charts-pro] Add pan on `wheel` to zoom (#19998) @JCQuintas
78
+ - [charts-pro] Fix zoom slider preview having an opaque background in dark mode (#20367) @bernardobelchior
79
+
80
+ #### `@mui/x-charts-premium@8.19.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
81
+
82
+ Same changes as in `@mui/x-charts-pro@8.19.0`.
83
+
84
+ ### Tree View
85
+
86
+ #### `@mui/x-tree-view@8.19.0`
87
+
88
+ - [tree view] Enable lazy load when children count is not know in tree view (#18680) @noobyogi0010
89
+ - [tree view] Fix unwanted behaviors on the item re-ordering (#20368) @flaviendelangle
90
+
91
+ #### `@mui/x-tree-view-pro@8.19.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
92
+
93
+ Same changes as in `@mui/x-tree-view@8.19.0`.
94
+
95
+ ### Codemod
96
+
97
+ #### `@mui/x-codemod@8.19.0`
98
+
99
+ Internal changes.
100
+
101
+ ### Docs
102
+
103
+ - [docs] Add minimum Typescript version to migration guide (#20320) @siriwatknp
104
+ - [docs] Fix Autosizing documentation (#20348) @siriwatknp
105
+ - [docs] Fix separator opacity in demo (#20293) @sai6855
106
+ - [docs] Replace deprecated `LoadingButton` with `Button` component (#20208) @Janpot
107
+
108
+ ### Core
109
+
110
+ - [code-infra] Add new broken links checker (#20120) @Janpot
111
+ - [code-infra] Disable Codspeed pipeline (#20370) @JCQuintas
112
+ - [code-infra] Optimize `checkMaterialVersion` (#20307) @Janpot
113
+ - [code-infra] Use utils from code-infra for changelog and PR creation (#20406) @brijeshb42
114
+ - [docs-infra] Revert `@docsearch/react` (#20313) @Janpot
115
+
116
+ ### Miscellaneous
117
+
118
+ - [test] Fix browser tests skipping some projects (#20318) @cherniavskii
119
+ - [test] Update `use-react-version` pnpm script (#20319) @cherniavskii
120
+
121
+ ## 8.18.0
122
+
123
+ <!-- generated comparing v8.17.0..master -->
124
+
125
+ _Nov 13, 2025_
126
+
127
+ We'd like to extend a big thank you to the 14 contributors who made this release possible. Here are some highlights ✨:
128
+
129
+ - Add `barLabelPlacement` property to customize the bar label position in bar charts, enabling labels to be placed above bars.
130
+
131
+ ![image](https://github.com/user-attachments/assets/4bc3a75b-74b8-4c6d-896b-5f5bf837bcda)
132
+
133
+ - Add `source` property to the date/time picker lifecycle and event handler context, enabling clearer differentiation between changes initiated by the picker UI and those from direct field input.
134
+ - 🐞 Bugfixes
135
+ - 📚 Documentation improvements
136
+
137
+ Special thanks go out to these community members for their valuable contributions:
138
+ @htollefsen, @sai6855, @Sigdriv
139
+
140
+ The following team members contributed to this release:
141
+ @arminmeh, @bernardobelchior, @brijeshb42, @cherniavskii, @flaviendelangle, @JCQuintas, @michelengelen, @noraleonte, @prakhargupta1, @rita-codes, @siriwatknp
142
+
143
+ ### Data Grid
144
+
145
+ #### `@mui/x-data-grid@8.18.0`
146
+
147
+ - [DataGrid] Allow default event in the column action cell item click event handler (#20272) @arminmeh
148
+ - [DataGrid] Remove unnecessary generic from `useGridApiRef` (#20277) @cherniavskii
149
+
150
+ #### `@mui/x-data-grid-pro@8.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
151
+
152
+ Same changes as in `@mui/x-data-grid@8.18.0`.
153
+
154
+ #### `@mui/x-data-grid-premium@8.18.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
155
+
156
+ Same changes as in `@mui/x-data-grid-pro@8.18.0`, plus:
157
+
158
+ - [DataGridPremium] Return the correct `cellParams` value from the aggregation cells (#20224) @arminmeh
159
+
160
+ ### Date and Time Pickers
161
+
162
+ #### `@mui/x-date-pickers@8.18.0`
163
+
164
+ - [pickers] Keep invalid date state consistent (#20040) @michelengelen
165
+ - [pickers] Adds new `source` property to `onChange` and `onAccept` context object (#20234) @michelengelen
166
+
167
+ #### `@mui/x-date-pickers-pro@8.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
168
+
169
+ Same changes as in `@mui/x-date-pickers@8.18.0`.
170
+
171
+ ### Charts
172
+
173
+ #### `@mui/x-charts@8.18.0`
174
+
175
+ - [charts] Add prop for positioning a bar label (#20194) @Sigdriv
176
+ - [charts] Fix applying dark mode styles in `ChartAxisZoomSliderThumb` (#20232) @sai6855
177
+
178
+ #### `@mui/x-charts-pro@8.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
179
+
180
+ Same changes as in `@mui/x-charts@8.18.0`, plus:
181
+
182
+ - [charts-pro] Allow specifying Content Security Policy nonce on export (#20053) @bernardobelchior
183
+ - [charts-pro] Fix applying dark mode styles to slider (#20220) @sai6855
184
+ - [charts-pro] Sankey should respect node order (#20065) @JCQuintas
185
+
186
+ #### `@mui/x-charts-premium@8.18.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
187
+
188
+ Same changes as in `@mui/x-charts-pro@8.18.0`.
189
+
190
+ ### Tree View
191
+
192
+ #### `@mui/x-tree-view@8.18.0`
193
+
194
+ - [tree view] Prepare tests for the new store structure (#20225) @flaviendelangle
195
+ - [tree view] Prepare the item plugin files for the store migration (#20240) @flaviendelangle
196
+ - [tree view] Use `TreeItemId` type instead of raw string (#20233) @flaviendelangle
197
+
198
+ #### `@mui/x-tree-view-pro@8.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
199
+
200
+ Same changes as in `@mui/x-tree-view@8.18.0`.
201
+
202
+ ### Codemod
203
+
204
+ #### `@mui/x-codemod@8.18.0`
205
+
206
+ Internal changes.
207
+
208
+ ### Docs
209
+
210
+ - [charts] Add a demo for a custom tick label (#20073) @prakhargupta1
211
+ - [charts] Create `useAxes()` hook documentation page (#20229) @JCQuintas
212
+ - [charts] Fix logo alignment (#20228) @JCQuintas
213
+ - [charts] Fixes typo in import example (#20236) @htollefsen
214
+ - [Data Grid] Add recipe for cursor pagination with data source (#19700) @siriwatknp
215
+ - [Data Grid] Add a demo for pinned rows aggregation (#20198) @cherniavskii
216
+
217
+ ### Core
218
+
219
+ - [docs-infra] Use deployment config from docs-infra package (#20243) @brijeshb42
220
+
8
221
  ## 8.17.0
9
222
 
10
223
  _Nov 5, 2025_
@@ -21,6 +21,7 @@ var _useStore = require("../internals/store/useStore");
21
21
  var _useChartDimensions = require("../internals/plugins/corePlugins/useChartDimensions/useChartDimensions.selectors");
22
22
  var _useChartKeyboardNavigation = require("../internals/plugins/featurePlugins/useChartKeyboardNavigation");
23
23
  var _chartsSurfaceClasses = require("./chartsSurfaceClasses");
24
+ var _useChartCartesianAxisRendering = require("../internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors");
24
25
  var _jsxRuntime = require("react/jsx-runtime");
25
26
  const _excluded = ["children", "className", "title", "desc"];
26
27
  const ChartsSurfaceStyles = (0, _styles.styled)('svg', {
@@ -40,7 +41,7 @@ const ChartsSurfaceStyles = (0, _styles.styled)('svg', {
40
41
  overflow: 'hidden',
41
42
  // This prevents default touch actions when using the svg on mobile devices.
42
43
  // For example, prevent page scroll & zoom.
43
- touchAction: 'pan-y',
44
+ touchAction: ownerState.hasZoom ? 'pan-y' : undefined,
44
45
  userSelect: 'none',
45
46
  gridArea: 'chart',
46
47
  '&:focus': {
@@ -81,6 +82,7 @@ const ChartsSurface = exports.ChartsSurface = /*#__PURE__*/React.forwardRef(func
81
82
  const propsHeight = (0, _useSelector.useSelector)(store, _useChartDimensions.selectorChartPropsHeight);
82
83
  const isKeyboardNavigationEnabled = (0, _useSelector.useSelector)(store, _useChartKeyboardNavigation.selectorChartsIsKeyboardNavigationEnabled);
83
84
  const hasFocusedItem = (0, _useSelector.useSelector)(store, _useChartKeyboardNavigation.selectorChartsHasFocusedItem);
85
+ const hasZoom = (0, _useSelector.useSelector)(store, _useChartCartesianAxisRendering.selectorChartHasZoom);
84
86
  const svgRef = (0, _useSvgRef.useSvgRef)();
85
87
  const handleRef = (0, _useForkRef.default)(svgRef, ref);
86
88
  const themeProps = (0, _styles.useThemeProps)({
@@ -99,7 +101,8 @@ const ChartsSurface = exports.ChartsSurface = /*#__PURE__*/React.forwardRef(func
99
101
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(ChartsSurfaceStyles, (0, _extends2.default)({
100
102
  ownerState: {
101
103
  width: propsWidth,
102
- height: propsHeight
104
+ height: propsHeight,
105
+ hasZoom
103
106
  },
104
107
  viewBox: `${0} ${0} ${svgWidth} ${svgHeight}`,
105
108
  className: (0, _clsx.default)(classes.root, className),
@@ -10,7 +10,6 @@ var _d3Shape = require("@mui/x-charts-vendor/d3-shape");
10
10
  var _warning = require("@mui/x-internals/warning");
11
11
  var _stackSeries = require("../../internals/stackSeries");
12
12
  var _defaultizeValueFormatter = require("../../internals/defaultizeValueFormatter");
13
- // For now it's a copy past of bar charts formatter, but maybe will diverge later
14
13
  const seriesProcessor = (params, dataset) => {
15
14
  const {
16
15
  seriesOrder,
@@ -39,6 +38,20 @@ const seriesProcessor = (params, dataset) => {
39
38
  } else if (dataset === undefined && process.env.NODE_ENV !== 'production') {
40
39
  throw new Error([`MUI X Charts: line series with id='${id}' has no data.`, 'Either provide a data property to the series or use the dataset prop.'].join('\n'));
41
40
  }
41
+ if (process.env.NODE_ENV !== 'production') {
42
+ if (!data && dataset) {
43
+ const dataKey = series[id].dataKey;
44
+ if (!dataKey) {
45
+ throw new Error([`MUI X Charts: line series with id='${id}' has no data and no dataKey.`, 'You must provide a dataKey when using the dataset prop.'].join('\n'));
46
+ }
47
+ dataset.forEach((entry, index) => {
48
+ const value = entry[dataKey];
49
+ if (value != null && typeof value !== 'number') {
50
+ (0, _warning.warnOnce)([`MUI X Charts: your dataset key "${dataKey}" is used for plotting lines, but the dataset contains the non-null non-numerical element "${value}" at index ${index}.`, 'Line plots only support numeric and null values.'].join('\n'));
51
+ }
52
+ });
53
+ }
54
+ }
42
55
  });
43
56
  const completedSeries = {};
44
57
  stackingGroups.forEach(stackingGroup => {
@@ -61,15 +74,7 @@ const seriesProcessor = (params, dataset) => {
61
74
  }, series[id], {
62
75
  data: dataKey ? dataset.map(data => {
63
76
  const value = data[dataKey];
64
- if (typeof value !== 'number') {
65
- if (process.env.NODE_ENV !== 'production') {
66
- if (value !== null) {
67
- (0, _warning.warnOnce)([`MUI X Charts: Your dataset key "${dataKey}" is used for plotting line, but contains nonnumerical elements.`, 'Line plots only support numbers and null values.']);
68
- }
69
- }
70
- return null;
71
- }
72
- return value;
77
+ return typeof value === 'number' ? value : null;
73
78
  }) : series[id].data,
74
79
  stackedData: stackedSeries[index].map(([a, b]) => [a, b])
75
80
  });
@@ -47,9 +47,11 @@ function PieArcPlot(props) {
47
47
  data
48
48
  });
49
49
  const {
50
- dataIndex: focusedIndex = -1
50
+ dataIndex,
51
+ seriesId,
52
+ seriesType
51
53
  } = (0, _useFocusedItem.useFocusedItem)() ?? {};
52
- const focusedItem = focusedIndex !== -1 ? transformedData[focusedIndex] : null;
54
+ const focusedItem = dataIndex !== undefined && seriesId === id && seriesType === 'pie' ? transformedData[dataIndex] : null;
53
55
  if (data.length === 0) {
54
56
  return null;
55
57
  }
@@ -90,7 +92,7 @@ function PieArcPlot(props) {
90
92
  stroke: (theme.vars ?? theme).palette.text.primary,
91
93
  id: id,
92
94
  className: _PieArc.pieArcClasses.focusIndicator,
93
- dataIndex: focusedIndex,
95
+ dataIndex: focusedItem.dataIndex,
94
96
  isFaded: false,
95
97
  isHighlighted: false,
96
98
  isFocused: false,
@@ -26,8 +26,14 @@ export type BarLabelProps = Omit<React.SVGProps<SVGTextElement>, 'ref' | 'id' |
26
26
  * Height of the bar this label belongs to.
27
27
  */
28
28
  height: number;
29
+ /**
30
+ * The placement of the bar label.
31
+ * It controls whether the label is rendered in the center or outside the bar.
32
+ * @default 'center'
33
+ */
34
+ placement?: 'center' | 'outside';
29
35
  };
30
- declare function BarLabel(inProps: BarLabelProps): import("react/jsx-runtime").JSX.Element;
36
+ declare function BarLabel(inProps: BarLabelProps): React.JSX.Element;
31
37
  declare namespace BarLabel {
32
38
  var propTypes: any;
33
39
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
4
4
  import _extends from "@babel/runtime/helpers/esm/extends";
5
- const _excluded = ["seriesId", "dataIndex", "color", "isFaded", "isHighlighted", "classes", "skipAnimation", "layout", "xOrigin", "yOrigin"];
5
+ const _excluded = ["seriesId", "dataIndex", "color", "isFaded", "isHighlighted", "classes", "skipAnimation", "layout", "xOrigin", "yOrigin", "placement"];
6
6
  import * as React from 'react';
7
7
  import { styled, useThemeProps } from '@mui/material/styles';
8
8
  import PropTypes from 'prop-types';
@@ -23,8 +23,6 @@ export const BarLabelComponent = styled('text', {
23
23
  stroke: 'none',
24
24
  fill: (theme.vars || theme)?.palette?.text?.primary,
25
25
  transition: 'opacity 0.2s ease-in, fill 0.2s ease-in',
26
- textAnchor: 'middle',
27
- dominantBaseline: 'central',
28
26
  pointerEvents: 'none',
29
27
  opacity: 1,
30
28
  [`&.${barLabelClasses.faded}`]: {
@@ -38,7 +36,40 @@ function BarLabel(inProps) {
38
36
  });
39
37
  const otherProps = _objectWithoutPropertiesLoose(props, _excluded);
40
38
  const animatedProps = useAnimateBarLabel(props);
41
- return /*#__PURE__*/_jsx(BarLabelComponent, _extends({}, otherProps, animatedProps));
39
+ const textAnchor = getTextAnchor(props);
40
+ const dominantBaseline = getDominantBaseline(props);
41
+ return /*#__PURE__*/_jsx(BarLabelComponent, _extends({
42
+ textAnchor: textAnchor,
43
+ dominantBaseline: dominantBaseline
44
+ }, otherProps, animatedProps));
45
+ }
46
+ function getTextAnchor({
47
+ placement,
48
+ layout,
49
+ xOrigin,
50
+ x
51
+ }) {
52
+ if (placement === 'outside') {
53
+ if (layout === 'horizontal') {
54
+ return x < xOrigin ? 'end' : 'start';
55
+ }
56
+ return 'middle';
57
+ }
58
+ return 'middle';
59
+ }
60
+ function getDominantBaseline({
61
+ placement,
62
+ layout,
63
+ yOrigin,
64
+ y
65
+ }) {
66
+ if (placement === 'outside') {
67
+ if (layout === 'horizontal') {
68
+ return 'central';
69
+ }
70
+ return y < yOrigin ? 'auto' : 'hanging';
71
+ }
72
+ return 'central';
42
73
  }
43
74
  process.env.NODE_ENV !== "production" ? BarLabel.propTypes = {
44
75
  // ----------------------------- Warning --------------------------------
@@ -54,6 +85,12 @@ process.env.NODE_ENV !== "production" ? BarLabel.propTypes = {
54
85
  isFaded: PropTypes.bool.isRequired,
55
86
  isHighlighted: PropTypes.bool.isRequired,
56
87
  layout: PropTypes.oneOf(['horizontal', 'vertical']).isRequired,
88
+ /**
89
+ * The placement of the bar label.
90
+ * It controls whether the label is rendered in the center or outside the bar.
91
+ * @default 'center'
92
+ */
93
+ placement: PropTypes.oneOf(['center', 'outside']),
57
94
  seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
58
95
  skipAnimation: PropTypes.bool.isRequired,
59
96
  /**
@@ -67,6 +67,12 @@ export type BarLabelItemProps = Omit<BarLabelOwnerState, 'isFaded' | 'isHighligh
67
67
  * @returns {string} The formatted label.
68
68
  */
69
69
  barLabel?: 'value' | ((item: BarItem, context: BarLabelContext) => string | null | undefined);
70
+ /**
71
+ * The placement of the bar label.
72
+ * It controls whether the label is rendered in the center or outside the bar.
73
+ * @default 'center'
74
+ */
75
+ barLabelPlacement?: BarLabelProps['placement'];
70
76
  };
71
77
  /**
72
78
  * @ignore - internal component.