@mui/x-charts 9.13.0 → 9.14.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 (52) hide show
  1. package/CHANGELOG.md +149 -0
  2. package/RadarChart/RadarAxis/RadarAxis.utils.d.mts +1 -1
  3. package/RadarChart/RadarAxis/RadarAxis.utils.d.ts +1 -1
  4. package/index.js +1 -1
  5. package/index.mjs +1 -1
  6. package/internals/components/ChartsAccessibilityProxy/ChartsAccessibilityProxy.js +31 -8
  7. package/internals/components/ChartsAccessibilityProxy/ChartsAccessibilityProxy.mjs +32 -9
  8. package/internals/components/ChartsAccessibilityProxy/useZoomAnnouncement.d.mts +9 -0
  9. package/internals/components/ChartsAccessibilityProxy/useZoomAnnouncement.d.ts +9 -0
  10. package/internals/components/ChartsAccessibilityProxy/useZoomAnnouncement.js +67 -0
  11. package/internals/components/ChartsAccessibilityProxy/useZoomAnnouncement.mjs +62 -0
  12. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.js +15 -5
  13. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.mjs +15 -5
  14. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.d.mts +3 -0
  15. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.d.ts +3 -0
  16. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.js +2 -1
  17. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.selectors.mjs +1 -0
  18. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.types.d.mts +12 -0
  19. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/useChartKeyboardNavigation.types.d.ts +12 -0
  20. package/locales/elGR.d.mts +5 -0
  21. package/locales/elGR.d.ts +5 -0
  22. package/locales/elGR.js +8 -0
  23. package/locales/elGR.mjs +8 -0
  24. package/locales/enUS.d.mts +5 -0
  25. package/locales/enUS.d.ts +5 -0
  26. package/locales/enUS.js +8 -0
  27. package/locales/enUS.mjs +8 -0
  28. package/locales/frFR.d.mts +5 -0
  29. package/locales/frFR.d.ts +5 -0
  30. package/locales/frFR.js +8 -0
  31. package/locales/frFR.mjs +8 -0
  32. package/locales/nbNO.d.mts +5 -0
  33. package/locales/nbNO.d.ts +5 -0
  34. package/locales/nbNO.js +8 -0
  35. package/locales/nbNO.mjs +8 -0
  36. package/locales/ptBR.d.mts +5 -0
  37. package/locales/ptBR.d.ts +5 -0
  38. package/locales/ptBR.js +8 -0
  39. package/locales/ptBR.mjs +8 -0
  40. package/locales/ptPT.d.mts +5 -0
  41. package/locales/ptPT.d.ts +5 -0
  42. package/locales/ptPT.js +8 -0
  43. package/locales/ptPT.mjs +8 -0
  44. package/locales/svSE.d.mts +5 -0
  45. package/locales/svSE.d.ts +5 -0
  46. package/locales/svSE.js +8 -0
  47. package/locales/svSE.mjs +8 -0
  48. package/locales/utils/chartsLocaleTextApi.d.mts +14 -0
  49. package/locales/utils/chartsLocaleTextApi.d.ts +14 -0
  50. package/locales/utils/getChartsLocalization.d.mts +5 -0
  51. package/locales/utils/getChartsLocalization.d.ts +5 -0
  52. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,154 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.14.0
4
+
5
+ _Sep 17, 2026_
6
+
7
+ We'd like to extend a big thank you to the 16 contributors who made this release possible. Here are some highlights ✨:
8
+
9
+ - 🌍 Add Hebrew (he-IL) locale to the Scheduler
10
+ - 📅 Scheduler time grid now opens at 7 AM by default, configurable with the new `initialScrollTime` prop
11
+ - 🗓️ Auto-scheduling engine for finish-to-start dependencies in the Premium Event Timeline
12
+ - 🧩 New content slots for the Event Timeline event block and resource title cell
13
+ - ♿️ Charts announce the visible zoom range to screen readers
14
+ - 🐞 Bugfixes
15
+ - 📚 Documentation improvements
16
+
17
+ Special thanks go out to these community members for their valuable contributions:
18
+ @eterry1388, @jamesDin, @kareem-ib, @mateuseap, @mustafajw07
19
+
20
+ The following team members contributed to this release:
21
+ @arminmeh, @bernardobelchior, @brijeshb42, @flaviendelangle, @hasdfa, @Janpot, @JCQuintas, @MBilalShafi, @michelengelen, @noraleonte, @rita-codes
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@9.14.0`
26
+
27
+ - [DataGrid] Do not crash on unmount when the document has no body (#23431) @eterry1388
28
+ - [DataGrid] Fix `MissingRowIdError` on cell `mousedown`/`mouseup` after row removal (#23261) @kareem-ib
29
+ - [DataGrid] Fix quick filter dropping a pending search on parser identity change (#23575) @michelengelen
30
+ - [DataGrid] Keep overlays sticky in RTL mode (#23492) @arminmeh
31
+ - [DataGrid] Prevent scroll area state update before mount (#23478) @michelengelen
32
+ - [DataGrid] Remove `'menu'` role from the actions cell (#23437) @michelengelen
33
+
34
+ #### `@mui/x-data-grid-pro@9.14.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
35
+
36
+ Same changes as in `@mui/x-data-grid@9.14.0`, plus:
37
+
38
+ - [DataGridPro] Fix data integrity issue in nested server data (#23518) @MBilalShafi
39
+ - [DataGridPro] Keep parent selection when lazily loaded children arrive (#23421) @michelengelen
40
+
41
+ #### `@mui/x-data-grid-premium@9.14.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
42
+
43
+ Same changes as in `@mui/x-data-grid-pro@9.14.0`.
44
+
45
+ ### Date and Time Pickers
46
+
47
+ #### `@mui/x-date-pickers@9.14.0`
48
+
49
+ Internal changes.
50
+
51
+ #### `@mui/x-date-pickers-pro@9.14.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
52
+
53
+ Same changes as in `@mui/x-date-pickers@9.14.0`.
54
+
55
+ ### Charts
56
+
57
+ #### `@mui/x-charts@9.14.0`
58
+
59
+ - [charts] Announce the visible zoom range to screen readers (#23371) @JCQuintas
60
+ - [charts] Fix Premium chart zoom props and `apiRef` forwarding (#23590) @bernardobelchior
61
+
62
+ #### `@mui/x-charts-pro@9.14.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
63
+
64
+ Same changes as in `@mui/x-charts@9.14.0`.
65
+
66
+ #### `@mui/x-charts-premium@9.14.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
67
+
68
+ Same changes as in `@mui/x-charts-pro@9.14.0`, plus:
69
+
70
+ - [charts-premium] Add the Excel data extraction layer (#23569) @JCQuintas
71
+ - [charts-premium] Forward `apiRef` on `RadialBarChart` and `RadialLineChart` (#23625) @JCQuintas
72
+
73
+ ### Tree View
74
+
75
+ #### `@mui/x-tree-view@9.14.0`
76
+
77
+ - [tree view] Optimize lazy loading store writes for nested children (#23489) @noraleonte
78
+ - [tree view] Prune stale children when replacing an item's children (#23598) @JCQuintas
79
+
80
+ #### `@mui/x-tree-view-pro@9.14.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
81
+
82
+ Same changes as in `@mui/x-tree-view@9.14.0`.
83
+
84
+ ### Scheduler
85
+
86
+ #### Breaking changes
87
+
88
+ - The `dataSource` prop has been removed from the Community Event Calendar components:
89
+ `EventCalendar`, `StandaloneDayView`, `StandaloneWeekView`, `StandaloneMonthView`,
90
+ `StandaloneAgendaView`, `StandaloneCompactDayView`, `StandaloneCompactThreeDayView` and
91
+ `StandaloneCompactWeekView`.
92
+
93
+ Lazy loading has always been Premium-only, and the prop never had any effect on these
94
+ components: it left the calendar in a permanent loading state. To load events through a data
95
+ source, use `EventCalendarPremium` (or the Premium standalone views) and `EventTimelinePremium`,
96
+ where `dataSource` is unchanged.
97
+
98
+ ```diff
99
+ -import { EventCalendar } from '@mui/x-scheduler/event-calendar';
100
+ +import { EventCalendarPremium } from '@mui/x-scheduler-premium/event-calendar-premium';
101
+
102
+ -<EventCalendar dataSource={dataSource} />
103
+ +<EventCalendarPremium dataSource={dataSource} />
104
+ ```
105
+
106
+ #### `@mui/x-scheduler@9.0.0-beta.12`
107
+
108
+ - [l10n] Add Hebrew (he-IL) locale (#23577) @jamesDin
109
+ - [scheduler] Add content slots for the Event Timeline event block and resource title cell (#23557) @rita-codes
110
+ - [scheduler] Fix `onPreferencesChange` never being called on `EventCalendar` (#23568) @rita-codes
111
+ - [scheduler] Fix flaky timeline observer absorb (#23523) @JCQuintas
112
+ - [scheduler] Open the time grid at 7 AM by default and add `initialScrollTime` (#23594) @rita-codes
113
+ - [scheduler] Pin sibling scheduler packages to exact versions (#23574) @rita-codes
114
+ - [scheduler] Read form initialization settings without subscriptions (#23614) @flaviendelangle
115
+ - [scheduler] Remove `dataSource` from the Community components (#23483) @mustafajw07
116
+ - [scheduler] Remove redundant recurrence subscriptions (#23610) @flaviendelangle
117
+ - [scheduler] Remove unused more-events popover count (#23619) @flaviendelangle
118
+ - [scheduler] Remove unused refs (#23616) @flaviendelangle
119
+ - [scheduler] Reuse precomputed timeline duration (#23620) @flaviendelangle
120
+ - [scheduler] Reuse recurrence option labels (#23609) @flaviendelangle
121
+ - [scheduler] Reuse recurrence presets for form drafts (#23615) @flaviendelangle
122
+ - [scheduler] Simplify month-view overflow counting (#23617) @flaviendelangle
123
+ - [scheduler] Use form store state to guard submissions (#23613) @flaviendelangle
124
+
125
+ #### `@mui/x-scheduler-premium@9.0.0-beta.12` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
126
+
127
+ Same changes as in `@mui/x-scheduler@9.0.0-beta.12`, plus:
128
+
129
+ - [scheduler-premium] Dependencies - Arrows and terminals for SS, FF and SF (#23524) @rita-codes
130
+ - [scheduler-premium] Dependencies - Auto-scheduling engine (FS) (#23439) @rita-codes
131
+
132
+ ### Docs
133
+
134
+ - [DataGrid][docs] Fix "Apply filters on demand" demo (#23602) @mateuseap
135
+ - [docs] Add recipe for getting the tree view's root DOM element via `ref` (#22941) @michelengelen
136
+ - [docs][pickers] Mention `Moment.js` maintenance mode (#23601) @mateuseap
137
+
138
+ ### Core
139
+
140
+ - [code-infra] Gate the `DataGridScrollRestoration` screenshot on the horizontal restore (#23527) @JCQuintas
141
+ - [code-infra] Let the `NoColumnsOverlay` demo settle before screenshotting (#23529) @JCQuintas
142
+ - [code-infra] Pin the only-allow version in the preinstall hook (#23551) @Janpot
143
+ - [code-infra] Remove disabled Discord release announcement workflow (#23554) @Janpot
144
+ - [code-infra] Trial: Claude CI flake-fix caller (#23556) @Janpot
145
+
146
+ ### Miscellaneous
147
+
148
+ - [chat] Add feedback form to the docs (#23403) @hasdfa
149
+ - [ci] Grant actions: read to the flake-fix caller (#23560) @Janpot
150
+ - [ci] Update flake-fix caller to mui-public#1849 (#23571) @Janpot
151
+
3
152
  ## 9.13.0
4
153
 
5
154
  <!-- generated comparing v9.12.0..master -->
@@ -5,11 +5,11 @@ interface GetLabelAttributesParams extends Required<Pick<RadarAxisProps, 'labelO
5
5
  angle: number;
6
6
  }
7
7
  export declare function getLabelAttributes(params: GetLabelAttributesParams): {
8
- transform?: undefined;
9
8
  x: number;
10
9
  y: number;
11
10
  textAnchor: "end" | "inherit" | "middle" | "start" | undefined;
12
11
  dominantBaseline: "alphabetic" | "auto" | "central" | "hanging" | "ideographic" | "inherit" | "mathematical" | "middle" | "no-change" | "reset-size" | "text-after-edge" | "text-before-edge" | "use-script" | undefined;
12
+ transform?: undefined;
13
13
  } | {
14
14
  x: number;
15
15
  y: number;
@@ -5,11 +5,11 @@ interface GetLabelAttributesParams extends Required<Pick<RadarAxisProps, 'labelO
5
5
  angle: number;
6
6
  }
7
7
  export declare function getLabelAttributes(params: GetLabelAttributesParams): {
8
- transform?: undefined;
9
8
  x: number;
10
9
  y: number;
11
10
  textAnchor: "end" | "inherit" | "middle" | "start" | undefined;
12
11
  dominantBaseline: "alphabetic" | "auto" | "central" | "hanging" | "ideographic" | "inherit" | "mathematical" | "middle" | "no-change" | "reset-size" | "text-after-edge" | "text-before-edge" | "use-script" | undefined;
12
+ transform?: undefined;
13
13
  } | {
14
14
  x: number;
15
15
  y: number;
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v9.13.0
2
+ * @mui/x-charts v9.14.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v9.13.0
2
+ * @mui/x-charts v9.14.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -12,6 +12,7 @@ var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
12
12
  var _useChartId = require("../../../hooks/useChartId");
13
13
  var _ChartsProvider = require("../../../context/ChartsProvider");
14
14
  var _useDescription = require("./useDescription");
15
+ var _useZoomAnnouncement = require("./useZoomAnnouncement");
15
16
  var _jsxRuntime = require("react/jsx-runtime");
16
17
  /**
17
18
  * Make the proxy looks like a layer.
@@ -28,6 +29,19 @@ var _jsxRuntime = require("react/jsx-runtime");
28
29
  pointerEvents: 'none'
29
30
  };
30
31
 
32
+ /**
33
+ * Keeps the live region out of sight without removing it from the accessibility tree.
34
+ */
35
+ const liveRegionStyle = {
36
+ position: 'absolute',
37
+ width: 1,
38
+ height: 1,
39
+ overflow: 'hidden',
40
+ clipPath: 'inset(50%)',
41
+ whiteSpace: 'nowrap',
42
+ pointerEvents: 'none'
43
+ };
44
+
31
45
  // The proxy is implemented by having two divs with the same content, and toggling the visibility of each one when the content changes.
32
46
  // The idea is to imitate the behavior of the focus moving from a list element to another, but with the minimal number of DOM elements.
33
47
 
@@ -37,6 +51,7 @@ var _jsxRuntime = require("react/jsx-runtime");
37
51
  */
38
52
  function ChartsAccessibilityProxy() {
39
53
  const message = (0, _useDescription.useDescription)();
54
+ const zoomMessage = (0, _useZoomAnnouncement.useZoomAnnouncement)();
40
55
  const chartId = (0, _useChartId.useChartId)();
41
56
  const {
42
57
  instance
@@ -99,13 +114,21 @@ function ChartsAccessibilityProxy() {
99
114
  activeDiv.focus();
100
115
  }
101
116
  }, [message, chartId]);
102
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
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,
109
- style: fullSizeLayerStyle
117
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
118
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
119
+ role: "none"
120
+ // Stays focusable once an announcer child owns the tab stop, otherwise the browser would
121
+ // blur the root mid hand-off and the chart would look like it lost the focus.
122
+ ,
123
+ tabIndex: message ? -1 : 0,
124
+ ref: handleRef,
125
+ style: fullSizeLayerStyle
126
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
127
+ role: "status",
128
+ "aria-live": "polite",
129
+ "aria-atomic": "true",
130
+ style: liveRegionStyle,
131
+ children: zoomMessage
132
+ })]
110
133
  });
111
134
  }
@@ -5,12 +5,13 @@ import useForkRef from '@mui/utils/useForkRef';
5
5
  import { useChartId } from "../../../hooks/useChartId.mjs";
6
6
  import { useChartsContext } from "../../../context/ChartsProvider/index.mjs";
7
7
  import { useDescription } from "./useDescription.mjs";
8
+ import { useZoomAnnouncement } from "./useZoomAnnouncement.mjs";
8
9
 
9
10
  /**
10
11
  * Make the proxy looks like a layer.
11
12
  * Having a non-zero size is important for some screen readers to announce the content.
12
13
  */
13
- import { jsx as _jsx } from "react/jsx-runtime";
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
15
  const fullSizeLayerStyle = {
15
16
  borderWidth: 0,
16
17
  width: '100%',
@@ -23,6 +24,19 @@ const fullSizeLayerStyle = {
23
24
  pointerEvents: 'none'
24
25
  };
25
26
 
27
+ /**
28
+ * Keeps the live region out of sight without removing it from the accessibility tree.
29
+ */
30
+ const liveRegionStyle = {
31
+ position: 'absolute',
32
+ width: 1,
33
+ height: 1,
34
+ overflow: 'hidden',
35
+ clipPath: 'inset(50%)',
36
+ whiteSpace: 'nowrap',
37
+ pointerEvents: 'none'
38
+ };
39
+
26
40
  // The proxy is implemented by having two divs with the same content, and toggling the visibility of each one when the content changes.
27
41
  // The idea is to imitate the behavior of the focus moving from a list element to another, but with the minimal number of DOM elements.
28
42
 
@@ -32,6 +46,7 @@ const fullSizeLayerStyle = {
32
46
  */
33
47
  export function ChartsAccessibilityProxy() {
34
48
  const message = useDescription();
49
+ const zoomMessage = useZoomAnnouncement();
35
50
  const chartId = useChartId();
36
51
  const {
37
52
  instance
@@ -94,13 +109,21 @@ export function ChartsAccessibilityProxy() {
94
109
  activeDiv.focus();
95
110
  }
96
111
  }, [message, chartId]);
97
- return /*#__PURE__*/_jsx("div", {
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,
104
- style: fullSizeLayerStyle
112
+ return /*#__PURE__*/_jsxs(React.Fragment, {
113
+ children: [/*#__PURE__*/_jsx("div", {
114
+ role: "none"
115
+ // Stays focusable once an announcer child owns the tab stop, otherwise the browser would
116
+ // blur the root mid hand-off and the chart would look like it lost the focus.
117
+ ,
118
+ tabIndex: message ? -1 : 0,
119
+ ref: handleRef,
120
+ style: fullSizeLayerStyle
121
+ }), /*#__PURE__*/_jsx("div", {
122
+ role: "status",
123
+ "aria-live": "polite",
124
+ "aria-atomic": "true",
125
+ style: liveRegionStyle,
126
+ children: zoomMessage
127
+ })]
105
128
  });
106
129
  }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Get the message announcing the visible range of the zoomable axes.
3
+ *
4
+ * The message is taken when the keyboard zoom and pan asks for it, not derived from the zoom
5
+ * itself: the zoom also moves on wheel, drag, and from the application, and the live region must
6
+ * stay silent then.
7
+ * @returns {string | null} the message to announce, or `null` when there is nothing to announce
8
+ */
9
+ export declare function useZoomAnnouncement(): string | null;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Get the message announcing the visible range of the zoomable axes.
3
+ *
4
+ * The message is taken when the keyboard zoom and pan asks for it, not derived from the zoom
5
+ * itself: the zoom also moves on wheel, drag, and from the application, and the live region must
6
+ * stay silent then.
7
+ * @returns {string | null} the message to announce, or `null` when there is nothing to announce
8
+ */
9
+ export declare function useZoomAnnouncement(): string | null;
@@ -0,0 +1,67 @@
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.useZoomAnnouncement = useZoomAnnouncement;
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _hooks = require("../../../hooks");
11
+ var _useStore = require("../../store/useStore");
12
+ var _useChartKeyboardNavigation = require("../../plugins/featurePlugins/useChartKeyboardNavigation");
13
+ var _useChartCartesianAxis = require("../../plugins/featurePlugins/useChartCartesianAxis");
14
+ /**
15
+ * Get the message announcing the visible range of the zoomable axes.
16
+ *
17
+ * The message is taken when the keyboard zoom and pan asks for it, not derived from the zoom
18
+ * itself: the zoom also moves on wheel, drag, and from the application, and the live region must
19
+ * stay silent then.
20
+ * @returns {string | null} the message to announce, or `null` when there is nothing to announce
21
+ */
22
+ function useZoomAnnouncement() {
23
+ const store = (0, _useStore.useStore)();
24
+ const announcement = store.use(_useChartKeyboardNavigation.selectorChartsZoomAnnouncement);
25
+ const zoomMap = store.use(_useChartCartesianAxis.selectorChartZoomMap);
26
+ const optionsLookup = store.use(_useChartCartesianAxis.selectorChartZoomOptionsLookup);
27
+ const {
28
+ localeText
29
+ } = (0, _hooks.useChartsLocalization)();
30
+ const [message, setMessage] = React.useState(null);
31
+
32
+ // The announcement is written from the values of the render the request lands on, so a later
33
+ // zoom coming from elsewhere does not rewrite the live region.
34
+ const currentValuesRef = React.useRef({
35
+ zoomMap,
36
+ optionsLookup,
37
+ localeText
38
+ });
39
+ currentValuesRef.current = {
40
+ zoomMap,
41
+ optionsLookup,
42
+ localeText
43
+ };
44
+ React.useEffect(() => {
45
+ if (announcement === 0) {
46
+ setMessage(null);
47
+ return;
48
+ }
49
+ const current = currentValuesRef.current;
50
+ if (!current.zoomMap) {
51
+ return;
52
+ }
53
+ const descriptions = Object.values(current.optionsLookup).map(options => {
54
+ const zoomData = current.zoomMap.get(options.axisId);
55
+ if (!zoomData) {
56
+ return null;
57
+ }
58
+ return current.localeText.zoomRangeDescription({
59
+ axisDirection: options.axisDirection,
60
+ start: zoomData.start,
61
+ end: zoomData.end
62
+ });
63
+ }).filter(Boolean);
64
+ setMessage(descriptions.length === 0 ? null : descriptions.join(current.localeText.a11yConnector));
65
+ }, [announcement]);
66
+ return message;
67
+ }
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { useChartsLocalization } from "../../../hooks/index.mjs";
5
+ import { useStore } from "../../store/useStore.mjs";
6
+ import { selectorChartsZoomAnnouncement } from "../../plugins/featurePlugins/useChartKeyboardNavigation/index.mjs";
7
+ import { selectorChartZoomMap, selectorChartZoomOptionsLookup } from "../../plugins/featurePlugins/useChartCartesianAxis/index.mjs";
8
+
9
+ /**
10
+ * Get the message announcing the visible range of the zoomable axes.
11
+ *
12
+ * The message is taken when the keyboard zoom and pan asks for it, not derived from the zoom
13
+ * itself: the zoom also moves on wheel, drag, and from the application, and the live region must
14
+ * stay silent then.
15
+ * @returns {string | null} the message to announce, or `null` when there is nothing to announce
16
+ */
17
+ export function useZoomAnnouncement() {
18
+ const store = useStore();
19
+ const announcement = store.use(selectorChartsZoomAnnouncement);
20
+ const zoomMap = store.use(selectorChartZoomMap);
21
+ const optionsLookup = store.use(selectorChartZoomOptionsLookup);
22
+ const {
23
+ localeText
24
+ } = useChartsLocalization();
25
+ const [message, setMessage] = React.useState(null);
26
+
27
+ // The announcement is written from the values of the render the request lands on, so a later
28
+ // zoom coming from elsewhere does not rewrite the live region.
29
+ const currentValuesRef = React.useRef({
30
+ zoomMap,
31
+ optionsLookup,
32
+ localeText
33
+ });
34
+ currentValuesRef.current = {
35
+ zoomMap,
36
+ optionsLookup,
37
+ localeText
38
+ };
39
+ React.useEffect(() => {
40
+ if (announcement === 0) {
41
+ setMessage(null);
42
+ return;
43
+ }
44
+ const current = currentValuesRef.current;
45
+ if (!current.zoomMap) {
46
+ return;
47
+ }
48
+ const descriptions = Object.values(current.optionsLookup).map(options => {
49
+ const zoomData = current.zoomMap.get(options.axisId);
50
+ if (!zoomData) {
51
+ return null;
52
+ }
53
+ return current.localeText.zoomRangeDescription({
54
+ axisDirection: options.axisDirection,
55
+ start: zoomData.start,
56
+ end: zoomData.end
57
+ });
58
+ }).filter(Boolean);
59
+ setMessage(descriptions.length === 0 ? null : descriptions.join(current.localeText.a11yConnector));
60
+ }, [announcement]);
61
+ return message;
62
+ }
@@ -192,6 +192,11 @@ const useChartKeyboardNavigation = ({
192
192
  });
193
193
  const activationRegistrationsRef = React.useRef(new Map());
194
194
  const nextRegistrationIdRef = React.useRef(0);
195
+ const announceZoomChange = React.useCallback(() => {
196
+ store.set('keyboardNavigation', (0, _extends2.default)({}, store.state.keyboardNavigation, {
197
+ zoomAnnouncement: store.state.keyboardNavigation.zoomAnnouncement + 1
198
+ }));
199
+ }, [store]);
195
200
  const registerItemActivationHandler = React.useCallback((scope, handler) => {
196
201
  const registrationId = nextRegistrationIdRef.current;
197
202
  nextRegistrationIdRef.current += 1;
@@ -219,10 +224,13 @@ const useChartKeyboardNavigation = ({
219
224
  if (root && next !== null && root.contains(next)) {
220
225
  return;
221
226
  }
222
- if (store.state.keyboardNavigation.isFocused) {
223
- store.set('keyboardNavigation', (0, _extends2.default)({}, store.state.keyboardNavigation, {
227
+ const keyboardNavigation = store.state.keyboardNavigation;
228
+ if (keyboardNavigation.isFocused || keyboardNavigation.zoomAnnouncement > 0) {
229
+ store.set('keyboardNavigation', (0, _extends2.default)({}, keyboardNavigation, {
224
230
  isFocused: false,
225
- isFocusVisible: false
231
+ isFocusVisible: false,
232
+ // The visible range is only announced while the user operates the chart.
233
+ zoomAnnouncement: 0
226
234
  }));
227
235
  }
228
236
  }
@@ -345,7 +353,8 @@ const useChartKeyboardNavigation = ({
345
353
  return {
346
354
  instance: {
347
355
  focusItem,
348
- registerItemActivationHandler
356
+ registerItemActivationHandler,
357
+ announceZoomChange
349
358
  }
350
359
  };
351
360
  };
@@ -355,7 +364,8 @@ useChartKeyboardNavigation.getInitialState = params => ({
355
364
  item: null,
356
365
  isFocused: false,
357
366
  isFocusVisible: false,
358
- enabled: !params.disableKeyboardNavigation
367
+ enabled: !params.disableKeyboardNavigation,
368
+ zoomAnnouncement: 0
359
369
  }
360
370
  });
361
371
  useChartKeyboardNavigation.params = {
@@ -186,6 +186,11 @@ export const useChartKeyboardNavigation = ({
186
186
  });
187
187
  const activationRegistrationsRef = React.useRef(new Map());
188
188
  const nextRegistrationIdRef = React.useRef(0);
189
+ const announceZoomChange = React.useCallback(() => {
190
+ store.set('keyboardNavigation', _extends({}, store.state.keyboardNavigation, {
191
+ zoomAnnouncement: store.state.keyboardNavigation.zoomAnnouncement + 1
192
+ }));
193
+ }, [store]);
189
194
  const registerItemActivationHandler = React.useCallback((scope, handler) => {
190
195
  const registrationId = nextRegistrationIdRef.current;
191
196
  nextRegistrationIdRef.current += 1;
@@ -213,10 +218,13 @@ export const useChartKeyboardNavigation = ({
213
218
  if (root && next !== null && root.contains(next)) {
214
219
  return;
215
220
  }
216
- if (store.state.keyboardNavigation.isFocused) {
217
- store.set('keyboardNavigation', _extends({}, store.state.keyboardNavigation, {
221
+ const keyboardNavigation = store.state.keyboardNavigation;
222
+ if (keyboardNavigation.isFocused || keyboardNavigation.zoomAnnouncement > 0) {
223
+ store.set('keyboardNavigation', _extends({}, keyboardNavigation, {
218
224
  isFocused: false,
219
- isFocusVisible: false
225
+ isFocusVisible: false,
226
+ // The visible range is only announced while the user operates the chart.
227
+ zoomAnnouncement: 0
220
228
  }));
221
229
  }
222
230
  }
@@ -339,7 +347,8 @@ export const useChartKeyboardNavigation = ({
339
347
  return {
340
348
  instance: {
341
349
  focusItem,
342
- registerItemActivationHandler
350
+ registerItemActivationHandler,
351
+ announceZoomChange
343
352
  }
344
353
  };
345
354
  };
@@ -348,7 +357,8 @@ useChartKeyboardNavigation.getInitialState = params => ({
348
357
  item: null,
349
358
  isFocused: false,
350
359
  isFocusVisible: false,
351
- enabled: !params.disableKeyboardNavigation
360
+ enabled: !params.disableKeyboardNavigation,
361
+ zoomAnnouncement: 0
352
362
  }
353
363
  });
354
364
  useChartKeyboardNavigation.params = {
@@ -20,6 +20,9 @@ export declare const selectorChartsFocusedItem: (args_0: import("../../corePlugi
20
20
  export declare const selectorChartsFocusedOrToFocusedItem: (args_0: import("../../corePlugins/useChartId/useChartId.types.mjs").UseChartIdState & import("../../corePlugins/useChartSeriesConfig/useChartSeriesConfig.types.mjs").UseChartSeriesConfigState<keyof import("../../../index.mjs").ChartsSeriesConfig> & import("../../corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.mjs").UseChartExperimentalFeaturesState & import("../../corePlugins/useChartDimensions/useChartDimensions.types.mjs").UseChartDimensionsState & import("../../corePlugins/useChartSeries/useChartSeries.types.mjs").UseChartSeriesState<keyof import("../../../index.mjs").ChartsSeriesConfig> & import("../../corePlugins/useChartAnimation/useChartAnimation.types.mjs").UseChartAnimationState & import("../../../index.mjs").UseChartInteractionListenerState & Partial<import("./useChartKeyboardNavigation.types.mjs").UseChartKeyboardNavigationState> & {
21
21
  cacheKey: import("../../models/index.mjs").ChartStateCacheKey;
22
22
  }) => FocusedItemIdentifier<keyof import("../../../index.mjs").ChartsSeriesConfig> | null;
23
+ export declare const selectorChartsZoomAnnouncement: (args_0: import("../../corePlugins/useChartId/useChartId.types.mjs").UseChartIdState & import("../../corePlugins/useChartSeriesConfig/useChartSeriesConfig.types.mjs").UseChartSeriesConfigState<keyof import("../../../index.mjs").ChartsSeriesConfig> & import("../../corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.mjs").UseChartExperimentalFeaturesState & import("../../corePlugins/useChartDimensions/useChartDimensions.types.mjs").UseChartDimensionsState & import("../../corePlugins/useChartSeries/useChartSeries.types.mjs").UseChartSeriesState<keyof import("../../../index.mjs").ChartsSeriesConfig> & import("../../corePlugins/useChartAnimation/useChartAnimation.types.mjs").UseChartAnimationState & import("../../../index.mjs").UseChartInteractionListenerState & Partial<import("./useChartKeyboardNavigation.types.mjs").UseChartKeyboardNavigationState> & {
24
+ cacheKey: import("../../models/index.mjs").ChartStateCacheKey;
25
+ }) => number;
23
26
  export declare const selectorChartsIsKeyboardNavigationEnabled: (args_0: import("../../corePlugins/useChartId/useChartId.types.mjs").UseChartIdState & import("../../corePlugins/useChartSeriesConfig/useChartSeriesConfig.types.mjs").UseChartSeriesConfigState<keyof import("../../../index.mjs").ChartsSeriesConfig> & import("../../corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.mjs").UseChartExperimentalFeaturesState & import("../../corePlugins/useChartDimensions/useChartDimensions.types.mjs").UseChartDimensionsState & import("../../corePlugins/useChartSeries/useChartSeries.types.mjs").UseChartSeriesState<keyof import("../../../index.mjs").ChartsSeriesConfig> & import("../../corePlugins/useChartAnimation/useChartAnimation.types.mjs").UseChartAnimationState & import("../../../index.mjs").UseChartInteractionListenerState & Partial<import("./useChartKeyboardNavigation.types.mjs").UseChartKeyboardNavigationState> & {
24
27
  cacheKey: import("../../models/index.mjs").ChartStateCacheKey;
25
28
  }) => boolean;
@@ -20,6 +20,9 @@ export declare const selectorChartsFocusedItem: (args_0: import("../../corePlugi
20
20
  export declare const selectorChartsFocusedOrToFocusedItem: (args_0: import("../../corePlugins/useChartId/useChartId.types.js").UseChartIdState & import("../../corePlugins/useChartSeriesConfig/useChartSeriesConfig.types.js").UseChartSeriesConfigState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../../corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../../corePlugins/useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("../../corePlugins/useChartSeries/useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../../corePlugins/useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../../../index.js").UseChartInteractionListenerState & Partial<import("./useChartKeyboardNavigation.types.js").UseChartKeyboardNavigationState> & {
21
21
  cacheKey: import("../../models/index.js").ChartStateCacheKey;
22
22
  }) => FocusedItemIdentifier<keyof import("../../../index.js").ChartsSeriesConfig> | null;
23
+ export declare const selectorChartsZoomAnnouncement: (args_0: import("../../corePlugins/useChartId/useChartId.types.js").UseChartIdState & import("../../corePlugins/useChartSeriesConfig/useChartSeriesConfig.types.js").UseChartSeriesConfigState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../../corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../../corePlugins/useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("../../corePlugins/useChartSeries/useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../../corePlugins/useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../../../index.js").UseChartInteractionListenerState & Partial<import("./useChartKeyboardNavigation.types.js").UseChartKeyboardNavigationState> & {
24
+ cacheKey: import("../../models/index.js").ChartStateCacheKey;
25
+ }) => number;
23
26
  export declare const selectorChartsIsKeyboardNavigationEnabled: (args_0: import("../../corePlugins/useChartId/useChartId.types.js").UseChartIdState & import("../../corePlugins/useChartSeriesConfig/useChartSeriesConfig.types.js").UseChartSeriesConfigState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../../corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.js").UseChartExperimentalFeaturesState & import("../../corePlugins/useChartDimensions/useChartDimensions.types.js").UseChartDimensionsState & import("../../corePlugins/useChartSeries/useChartSeries.types.js").UseChartSeriesState<keyof import("../../../index.js").ChartsSeriesConfig> & import("../../corePlugins/useChartAnimation/useChartAnimation.types.js").UseChartAnimationState & import("../../../index.js").UseChartInteractionListenerState & Partial<import("./useChartKeyboardNavigation.types.js").UseChartKeyboardNavigationState> & {
24
27
  cacheKey: import("../../models/index.js").ChartStateCacheKey;
25
28
  }) => boolean;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.selectorChartsKeyboardYAxisIndex = exports.selectorChartsKeyboardXAxisIndex = exports.selectorChartsKeyboardItem = exports.selectorChartsItemIsFocused = exports.selectorChartsIsKeyboardNavigationEnabled = exports.selectorChartsIsKeyboardActivationEnabled = exports.selectorChartsIsFocusVisible = exports.selectorChartsHasFocusedItem = exports.selectorChartsFocusedOrToFocusedItem = exports.selectorChartsFocusedItem = void 0;
6
+ exports.selectorChartsZoomAnnouncement = exports.selectorChartsKeyboardYAxisIndex = exports.selectorChartsKeyboardXAxisIndex = exports.selectorChartsKeyboardItem = exports.selectorChartsItemIsFocused = exports.selectorChartsIsKeyboardNavigationEnabled = exports.selectorChartsIsKeyboardActivationEnabled = exports.selectorChartsIsFocusVisible = exports.selectorChartsHasFocusedItem = exports.selectorChartsFocusedOrToFocusedItem = exports.selectorChartsFocusedItem = void 0;
7
7
  var _store = require("@mui/x-internals/store");
8
8
  var _fastObjectShallowCompare = require("@mui/x-internals/fastObjectShallowCompare");
9
9
  var _useChartSeries = require("../../corePlugins/useChartSeries");
@@ -26,6 +26,7 @@ const selectorChartsFocusedItem = exports.selectorChartsFocusedItem = (0, _store
26
26
  * - will be focused when user focuses the chart
27
27
  */
28
28
  const selectorChartsFocusedOrToFocusedItem = exports.selectorChartsFocusedOrToFocusedItem = (0, _store.createSelector)(selectKeyboardNavigation, keyboardNavigationState => keyboardNavigationState?.item ?? null);
29
+ const selectorChartsZoomAnnouncement = exports.selectorChartsZoomAnnouncement = (0, _store.createSelector)(selectKeyboardNavigation, keyboardNavigationState => keyboardNavigationState?.zoomAnnouncement ?? 0);
29
30
  const selectorChartsIsKeyboardNavigationEnabled = exports.selectorChartsIsKeyboardNavigationEnabled = (0, _store.createSelector)(selectKeyboardNavigation, keyboardNavigationState => !!keyboardNavigationState?.enabled);
30
31
  const selectKeyboardActivationFeature = state => state.experimentalFeatures?.keyboardActivation;
31
32
  const selectorChartsIsKeyboardActivationEnabled = exports.selectorChartsIsKeyboardActivationEnabled = (0, _store.createSelector)(selectKeyboardNavigation, selectKeyboardActivationFeature, (keyboardNavigationState, keyboardActivation) => keyboardActivation === true && !!keyboardNavigationState?.enabled);
@@ -20,6 +20,7 @@ export const selectorChartsFocusedItem = createSelector(selectKeyboardNavigation
20
20
  * - will be focused when user focuses the chart
21
21
  */
22
22
  export const selectorChartsFocusedOrToFocusedItem = createSelector(selectKeyboardNavigation, keyboardNavigationState => keyboardNavigationState?.item ?? null);
23
+ export const selectorChartsZoomAnnouncement = createSelector(selectKeyboardNavigation, keyboardNavigationState => keyboardNavigationState?.zoomAnnouncement ?? 0);
23
24
  export const selectorChartsIsKeyboardNavigationEnabled = createSelector(selectKeyboardNavigation, keyboardNavigationState => !!keyboardNavigationState?.enabled);
24
25
  const selectKeyboardActivationFeature = state => state.experimentalFeatures?.keyboardActivation;
25
26
  export const selectorChartsIsKeyboardActivationEnabled = createSelector(selectKeyboardNavigation, selectKeyboardActivationFeature, (keyboardNavigationState, keyboardActivation) => keyboardActivation === true && !!keyboardNavigationState?.enabled);
@@ -58,6 +58,12 @@ export interface UseChartKeyboardNavigationInstance {
58
58
  * @returns {() => void} A cleanup function unregistering the handler.
59
59
  */
60
60
  registerItemActivationHandler: (scope: ItemActivationScope, handler: ItemActivationHandler) => () => void;
61
+ /**
62
+ * Asks for the visible zoom range to be announced to screen readers.
63
+ * Called by the plugin owning keyboard zoom and pan, on each change the user makes with the keys.
64
+ * @returns {void}
65
+ */
66
+ announceZoomChange: () => void;
61
67
  }
62
68
  export interface UseChartKeyboardNavigationState {
63
69
  keyboardNavigation: {
@@ -78,6 +84,12 @@ export interface UseChartKeyboardNavigationState {
78
84
  * Indicates whether keyboard navigation is enabled or not.
79
85
  */
80
86
  enabled: boolean;
87
+ /**
88
+ * Incremented on each zoom change the user makes with the keyboard, and reset when the chart
89
+ * loses focus. The live region reads the visible range when it changes, so a zoom coming from
90
+ * the pointer or from the application is not announced.
91
+ */
92
+ zoomAnnouncement: number;
81
93
  };
82
94
  }
83
95
  type UseChartKeyboardNavigationParameters = {
@@ -58,6 +58,12 @@ export interface UseChartKeyboardNavigationInstance {
58
58
  * @returns {() => void} A cleanup function unregistering the handler.
59
59
  */
60
60
  registerItemActivationHandler: (scope: ItemActivationScope, handler: ItemActivationHandler) => () => void;
61
+ /**
62
+ * Asks for the visible zoom range to be announced to screen readers.
63
+ * Called by the plugin owning keyboard zoom and pan, on each change the user makes with the keys.
64
+ * @returns {void}
65
+ */
66
+ announceZoomChange: () => void;
61
67
  }
62
68
  export interface UseChartKeyboardNavigationState {
63
69
  keyboardNavigation: {
@@ -78,6 +84,12 @@ export interface UseChartKeyboardNavigationState {
78
84
  * Indicates whether keyboard navigation is enabled or not.
79
85
  */
80
86
  enabled: boolean;
87
+ /**
88
+ * Incremented on each zoom change the user makes with the keyboard, and reset when the chart
89
+ * loses focus. The live region reads the visible range when it changes, so a zoom coming from
90
+ * the pointer or from the application is not announced.
91
+ */
92
+ zoomAnnouncement: number;
81
93
  };
82
94
  }
83
95
  type UseChartKeyboardNavigationParameters = {
@@ -114,6 +114,11 @@ export declare const elGR: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/elGR.d.ts CHANGED
@@ -114,6 +114,11 @@ export declare const elGR: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/elGR.js CHANGED
@@ -125,6 +125,14 @@ const elGRLocaleText = exports.elGRLocaleText = {
125
125
  // Accessibility descriptions
126
126
  // a11yNoValue: 'no value',
127
127
  // a11yConnector: '; ',
128
+ // zoomRangeDescription: function zoomRangeDescription({
129
+ // axisDirection,
130
+ // start,
131
+ // end
132
+ // }) {
133
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
134
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
135
+ // },
128
136
  // barDescription: function barDescription({
129
137
  // value,
130
138
  // formattedValue,
package/locales/elGR.mjs CHANGED
@@ -119,6 +119,14 @@ export const elGRLocaleText = {
119
119
  // Accessibility descriptions
120
120
  // a11yNoValue: 'no value',
121
121
  // a11yConnector: '; ',
122
+ // zoomRangeDescription: function zoomRangeDescription({
123
+ // axisDirection,
124
+ // start,
125
+ // end
126
+ // }) {
127
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
128
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
129
+ // },
122
130
  // barDescription: function barDescription({
123
131
  // value,
124
132
  // formattedValue,
@@ -115,6 +115,11 @@ export declare const enUS: {
115
115
  close?: string | undefined;
116
116
  a11yNoValue?: string | undefined;
117
117
  a11yConnector?: string | undefined;
118
+ zoomRangeDescription?: ((params: {
119
+ axisDirection: 'x' | 'y';
120
+ start: number;
121
+ end: number;
122
+ }) => string) | undefined;
118
123
  barDescription?: ((params: {
119
124
  value: number | null;
120
125
  formattedValue: string;
package/locales/enUS.d.ts CHANGED
@@ -115,6 +115,11 @@ export declare const enUS: {
115
115
  close?: string | undefined;
116
116
  a11yNoValue?: string | undefined;
117
117
  a11yConnector?: string | undefined;
118
+ zoomRangeDescription?: ((params: {
119
+ axisDirection: 'x' | 'y';
120
+ start: number;
121
+ end: number;
122
+ }) => string) | undefined;
118
123
  barDescription?: ((params: {
119
124
  value: number | null;
120
125
  formattedValue: string;
package/locales/enUS.js CHANGED
@@ -125,6 +125,14 @@ const enUSLocaleText = exports.enUSLocaleText = {
125
125
  // Accessibility descriptions
126
126
  a11yNoValue: 'no value',
127
127
  a11yConnector: '; ',
128
+ zoomRangeDescription: function zoomRangeDescription({
129
+ axisDirection,
130
+ start,
131
+ end
132
+ }) {
133
+ const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
134
+ return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
135
+ },
128
136
  barDescription: function barDescription({
129
137
  value,
130
138
  formattedValue,
package/locales/enUS.mjs CHANGED
@@ -120,6 +120,14 @@ export const enUSLocaleText = {
120
120
  // Accessibility descriptions
121
121
  a11yNoValue: 'no value',
122
122
  a11yConnector: '; ',
123
+ zoomRangeDescription: function zoomRangeDescription({
124
+ axisDirection,
125
+ start,
126
+ end
127
+ }) {
128
+ const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
129
+ return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
130
+ },
123
131
  barDescription: function barDescription({
124
132
  value,
125
133
  formattedValue,
@@ -114,6 +114,11 @@ export declare const frFR: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/frFR.d.ts CHANGED
@@ -114,6 +114,11 @@ export declare const frFR: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/frFR.js CHANGED
@@ -125,6 +125,14 @@ const frFRLocalText = exports.frFRLocalText = {
125
125
  // Accessibility descriptions
126
126
  // a11yNoValue: 'no value',
127
127
  // a11yConnector: '; ',
128
+ // zoomRangeDescription: function zoomRangeDescription({
129
+ // axisDirection,
130
+ // start,
131
+ // end
132
+ // }) {
133
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
134
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
135
+ // },
128
136
  // barDescription: function barDescription({
129
137
  // value,
130
138
  // formattedValue,
package/locales/frFR.mjs CHANGED
@@ -119,6 +119,14 @@ export const frFRLocalText = {
119
119
  // Accessibility descriptions
120
120
  // a11yNoValue: 'no value',
121
121
  // a11yConnector: '; ',
122
+ // zoomRangeDescription: function zoomRangeDescription({
123
+ // axisDirection,
124
+ // start,
125
+ // end
126
+ // }) {
127
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
128
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
129
+ // },
122
130
  // barDescription: function barDescription({
123
131
  // value,
124
132
  // formattedValue,
@@ -114,6 +114,11 @@ export declare const nbNO: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/nbNO.d.ts CHANGED
@@ -114,6 +114,11 @@ export declare const nbNO: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/nbNO.js CHANGED
@@ -125,6 +125,14 @@ const nbNOLocaleText = exports.nbNOLocaleText = {
125
125
  // Accessibility descriptions
126
126
  // a11yNoValue: 'no value',
127
127
  // a11yConnector: '; ',
128
+ // zoomRangeDescription: function zoomRangeDescription({
129
+ // axisDirection,
130
+ // start,
131
+ // end
132
+ // }) {
133
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
134
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
135
+ // },
128
136
  // barDescription: function barDescription({
129
137
  // value,
130
138
  // formattedValue,
package/locales/nbNO.mjs CHANGED
@@ -119,6 +119,14 @@ export const nbNOLocaleText = {
119
119
  // Accessibility descriptions
120
120
  // a11yNoValue: 'no value',
121
121
  // a11yConnector: '; ',
122
+ // zoomRangeDescription: function zoomRangeDescription({
123
+ // axisDirection,
124
+ // start,
125
+ // end
126
+ // }) {
127
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
128
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
129
+ // },
122
130
  // barDescription: function barDescription({
123
131
  // value,
124
132
  // formattedValue,
@@ -114,6 +114,11 @@ export declare const ptBR: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/ptBR.d.ts CHANGED
@@ -114,6 +114,11 @@ export declare const ptBR: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/ptBR.js CHANGED
@@ -125,6 +125,14 @@ const ptBRLocaleText = exports.ptBRLocaleText = {
125
125
  // Accessibility descriptions
126
126
  // a11yNoValue: 'no value',
127
127
  // a11yConnector: '; ',
128
+ // zoomRangeDescription: function zoomRangeDescription({
129
+ // axisDirection,
130
+ // start,
131
+ // end
132
+ // }) {
133
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
134
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
135
+ // },
128
136
  // barDescription: function barDescription({
129
137
  // value,
130
138
  // formattedValue,
package/locales/ptBR.mjs CHANGED
@@ -119,6 +119,14 @@ export const ptBRLocaleText = {
119
119
  // Accessibility descriptions
120
120
  // a11yNoValue: 'no value',
121
121
  // a11yConnector: '; ',
122
+ // zoomRangeDescription: function zoomRangeDescription({
123
+ // axisDirection,
124
+ // start,
125
+ // end
126
+ // }) {
127
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
128
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
129
+ // },
122
130
  // barDescription: function barDescription({
123
131
  // value,
124
132
  // formattedValue,
@@ -114,6 +114,11 @@ export declare const ptPT: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/ptPT.d.ts CHANGED
@@ -114,6 +114,11 @@ export declare const ptPT: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/ptPT.js CHANGED
@@ -124,6 +124,14 @@ const ptPTLocaleText = exports.ptPTLocaleText = {
124
124
  // Accessibility descriptions
125
125
  // a11yNoValue: 'no value',
126
126
  // a11yConnector: '; ',
127
+ // zoomRangeDescription: function zoomRangeDescription({
128
+ // axisDirection,
129
+ // start,
130
+ // end
131
+ // }) {
132
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
133
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
134
+ // },
127
135
  // barDescription: function barDescription({
128
136
  // value,
129
137
  // formattedValue,
package/locales/ptPT.mjs CHANGED
@@ -118,6 +118,14 @@ export const ptPTLocaleText = {
118
118
  // Accessibility descriptions
119
119
  // a11yNoValue: 'no value',
120
120
  // a11yConnector: '; ',
121
+ // zoomRangeDescription: function zoomRangeDescription({
122
+ // axisDirection,
123
+ // start,
124
+ // end
125
+ // }) {
126
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
127
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
128
+ // },
121
129
  // barDescription: function barDescription({
122
130
  // value,
123
131
  // formattedValue,
@@ -114,6 +114,11 @@ export declare const svSE: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/svSE.d.ts CHANGED
@@ -114,6 +114,11 @@ export declare const svSE: {
114
114
  close?: string | undefined;
115
115
  a11yNoValue?: string | undefined;
116
116
  a11yConnector?: string | undefined;
117
+ zoomRangeDescription?: ((params: {
118
+ axisDirection: 'x' | 'y';
119
+ start: number;
120
+ end: number;
121
+ }) => string) | undefined;
117
122
  barDescription?: ((params: {
118
123
  value: number | null;
119
124
  formattedValue: string;
package/locales/svSE.js CHANGED
@@ -127,6 +127,14 @@ const svSELocaleText = exports.svSELocaleText = {
127
127
  // Accessibility descriptions
128
128
  // a11yNoValue: 'no value',
129
129
  // a11yConnector: '; ',
130
+ // zoomRangeDescription: function zoomRangeDescription({
131
+ // axisDirection,
132
+ // start,
133
+ // end
134
+ // }) {
135
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
136
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
137
+ // },
130
138
  // barDescription: function barDescription({
131
139
  // value,
132
140
  // formattedValue,
package/locales/svSE.mjs CHANGED
@@ -121,6 +121,14 @@ export const svSELocaleText = {
121
121
  // Accessibility descriptions
122
122
  // a11yNoValue: 'no value',
123
123
  // a11yConnector: '; ',
124
+ // zoomRangeDescription: function zoomRangeDescription({
125
+ // axisDirection,
126
+ // start,
127
+ // end
128
+ // }) {
129
+ // const axisName = axisDirection === 'x' ? 'horizontal axis' : 'vertical axis';
130
+ // return `Showing ${Math.round(start)}% to ${Math.round(end)}% of the ${axisName}`;
131
+ // },
124
132
  // barDescription: function barDescription({
125
133
  // value,
126
134
  // formattedValue,
@@ -440,6 +440,20 @@ export interface ChartsLocaleText {
440
440
  * The string used to merge description values.
441
441
  */
442
442
  a11yConnector: string;
443
+ /**
444
+ * The description of the visible range of a zoomable axis for accessibility purpose.
445
+ * It is announced when the user zooms or pans the chart with the keyboard.
446
+ * @param {object} params - The parameters for the description getter.
447
+ * @param {'x'|'y'} params.axisDirection - The direction of the zoomed axis.
448
+ * @param {number} params.start - The start of the visible range, as a percentage of the axis extent.
449
+ * @param {number} params.end - The end of the visible range, as a percentage of the axis extent.
450
+ * @returns {string} The localized description of the visible range.
451
+ */
452
+ zoomRangeDescription: (params: {
453
+ axisDirection: 'x' | 'y';
454
+ start: number;
455
+ end: number;
456
+ }) => string;
443
457
  /**
444
458
  * The description of a bar series item for accessibility purpose.
445
459
  * @param {object} params - The parameters for the description getter.
@@ -440,6 +440,20 @@ export interface ChartsLocaleText {
440
440
  * The string used to merge description values.
441
441
  */
442
442
  a11yConnector: string;
443
+ /**
444
+ * The description of the visible range of a zoomable axis for accessibility purpose.
445
+ * It is announced when the user zooms or pans the chart with the keyboard.
446
+ * @param {object} params - The parameters for the description getter.
447
+ * @param {'x'|'y'} params.axisDirection - The direction of the zoomed axis.
448
+ * @param {number} params.start - The start of the visible range, as a percentage of the axis extent.
449
+ * @param {number} params.end - The end of the visible range, as a percentage of the axis extent.
450
+ * @returns {string} The localized description of the visible range.
451
+ */
452
+ zoomRangeDescription: (params: {
453
+ axisDirection: 'x' | 'y';
454
+ start: number;
455
+ end: number;
456
+ }) => string;
443
457
  /**
444
458
  * The description of a bar series item for accessibility purpose.
445
459
  * @param {object} params - The parameters for the description getter.
@@ -118,6 +118,11 @@ export declare const getChartsLocalization: (chartsTranslations: Partial<ChartsL
118
118
  close?: string | undefined;
119
119
  a11yNoValue?: string | undefined;
120
120
  a11yConnector?: string | undefined;
121
+ zoomRangeDescription?: ((params: {
122
+ axisDirection: 'x' | 'y';
123
+ start: number;
124
+ end: number;
125
+ }) => string) | undefined;
121
126
  barDescription?: ((params: {
122
127
  value: number | null;
123
128
  formattedValue: string;
@@ -118,6 +118,11 @@ export declare const getChartsLocalization: (chartsTranslations: Partial<ChartsL
118
118
  close?: string | undefined;
119
119
  a11yNoValue?: string | undefined;
120
120
  a11yConnector?: string | undefined;
121
+ zoomRangeDescription?: ((params: {
122
+ axisDirection: 'x' | 'y';
123
+ start: number;
124
+ end: number;
125
+ }) => string) | undefined;
121
126
  barDescription?: ((params: {
122
127
  value: number | null;
123
128
  formattedValue: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-charts",
3
- "version": "9.13.0",
3
+ "version": "9.14.0",
4
4
  "author": "MUI Team",
5
5
  "description": "The community edition of MUI X Charts components.",
6
6
  "license": "MIT",
@@ -30,13 +30,13 @@
30
30
  "@babel/runtime": "^7.29.7",
31
31
  "@mui/utils": "^9.4.0",
32
32
  "@mui/x-charts-vendor": "^9.13.0",
33
- "@mui/x-internal-gestures": "^9.13.0",
34
- "@mui/x-internals": "^9.13.0",
35
- "bezier-easing": "^3.0.1",
33
+ "@mui/x-internal-gestures": "^9.14.0",
34
+ "@mui/x-internals": "^9.14.0",
35
+ "bezier-easing": "^3.1.0",
36
36
  "clsx": "^2.1.1",
37
37
  "prop-types": "^15.8.1",
38
38
  "reselect": "^5.2.0",
39
- "use-sync-external-store": "^1.6.0"
39
+ "use-sync-external-store": "^1.7.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@emotion/react": "^11.9.0",