@mui/x-date-pickers 9.0.0-alpha.2 → 9.0.0-alpha.4

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 (48) hide show
  1. package/CHANGELOG.md +246 -1
  2. package/DateCalendar/PickersSlideTransition.js +7 -13
  3. package/DateCalendar/PickersSlideTransition.mjs +7 -13
  4. package/DateField/DateField.js +4 -4
  5. package/DateField/DateField.mjs +4 -4
  6. package/DateTimeField/DateTimeField.js +4 -4
  7. package/DateTimeField/DateTimeField.mjs +4 -4
  8. package/DigitalClock/DigitalClock.js +3 -1
  9. package/DigitalClock/DigitalClock.mjs +3 -1
  10. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +44 -7
  11. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.mjs +44 -7
  12. package/TimeField/TimeField.js +4 -4
  13. package/TimeField/TimeField.mjs +4 -4
  14. package/hooks/useSplitFieldProps.d.mts +1 -1
  15. package/hooks/useSplitFieldProps.d.ts +1 -1
  16. package/hooks/useSplitFieldProps.js +1 -1
  17. package/hooks/useSplitFieldProps.mjs +1 -1
  18. package/index.js +1 -1
  19. package/index.mjs +1 -1
  20. package/internals/components/PickerPopper/PickerPopper.js +17 -2
  21. package/internals/components/PickerPopper/PickerPopper.mjs +17 -2
  22. package/internals/components/PickersModalDialog.js +7 -4
  23. package/internals/components/PickersModalDialog.mjs +7 -4
  24. package/internals/hooks/useField/useField.types.d.mts +1 -1
  25. package/internals/hooks/useField/useField.types.d.ts +1 -1
  26. package/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +2 -2
  27. package/internals/hooks/useField/useFieldInternalPropsWithDefaults.mjs +2 -2
  28. package/internals/hooks/useField/useFieldV6TextField.js +4 -3
  29. package/internals/hooks/useField/useFieldV6TextField.mjs +4 -3
  30. package/internals/hooks/useField/useFieldV7TextField.js +4 -3
  31. package/internals/hooks/useField/useFieldV7TextField.mjs +4 -3
  32. package/internals/hooks/useNullableFieldPrivateContext.d.mts +2 -1
  33. package/internals/hooks/useNullableFieldPrivateContext.d.ts +2 -1
  34. package/internals/hooks/usePicker/usePicker.js +13 -8
  35. package/internals/hooks/usePicker/usePicker.mjs +13 -8
  36. package/internals/hooks/usePicker/usePicker.types.d.mts +2 -1
  37. package/internals/hooks/usePicker/usePicker.types.d.ts +2 -1
  38. package/internals/index.d.mts +1 -0
  39. package/internals/index.d.ts +1 -0
  40. package/internals/index.js +7 -0
  41. package/internals/index.mjs +1 -0
  42. package/internals/utils/isElementInteractive.d.mts +1 -0
  43. package/internals/utils/isElementInteractive.d.ts +1 -0
  44. package/internals/utils/isElementInteractive.js +34 -0
  45. package/internals/utils/isElementInteractive.mjs +28 -0
  46. package/models/fields.d.mts +5 -1
  47. package/models/fields.d.ts +5 -1
  48. package/package.json +50 -50
package/CHANGELOG.md CHANGED
@@ -1,5 +1,250 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.0.0-alpha.4
4
+
5
+ _Mar 19, 2026_
6
+
7
+ We'd like to extend a big thank you to the 12 contributors who made this release possible. Here are some highlights ✨:
8
+
9
+ - 🐞 Bugfixes and internal improvements
10
+
11
+ The following team members contributed to this release:
12
+ @aemartos, @alexfauquette, @bernardobelchior, @Janpot, @JCQuintas, @LukasTy, @mapache-salvaje, @michelengelen, @noraleonte, @rita-codes, @sai6855, @siriwatknp
13
+
14
+ ### Data Grid
15
+
16
+ #### `@mui/x-data-grid@9.0.0-alpha.4`
17
+
18
+ - [DataGrid] Mark charts integration as stable (#21764) @JCQuintas
19
+ - [DataGrid] Move `elementOverrides` to constants and remove duplicates (#21618) @sai6855
20
+ - [DataGrid] Migrate from deprecated Material UI APIs (#21682) @siriwatknp
21
+
22
+ #### `@mui/x-data-grid-pro@9.0.0-alpha.4` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
23
+
24
+ Same changes as in `@mui/x-data-grid@9.0.0-alpha.4`.
25
+
26
+ #### `@mui/x-data-grid-premium@9.0.0-alpha.4` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
27
+
28
+ Same changes as in `@mui/x-data-grid-pro@9.0.0-alpha.4`.
29
+
30
+ ### Date and Time Pickers
31
+
32
+ #### `@mui/x-date-pickers@9.0.0-alpha.4`
33
+
34
+ - [pickers] Avoid stealing focus on click away (#13434) @LukasTy
35
+ - [pickers] Promote `fieldRef` to stable and add `clearValue` method (#21655) @michelengelen
36
+
37
+ #### `@mui/x-date-pickers-pro@9.0.0-alpha.4` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
38
+
39
+ Same changes as in `@mui/x-date-pickers@9.0.0-alpha.4`.
40
+
41
+ ### Charts
42
+
43
+ #### `@mui/x-charts@9.0.0-alpha.4`
44
+
45
+ - [charts] Add v9 chart series types and helper functions migration (#21009) @bernardobelchior
46
+ - [charts] Extract event listener to the layer container (#21751) @alexfauquette
47
+ - [charts] Fix WebGL print export canvas stretching (#21738) @JCQuintas
48
+ - [charts] Improve deprecation warnings (#21760) @alexfauquette
49
+ - [charts] Improve type safety in `identifierCleaner` (#21719) @bernardobelchior
50
+ - [charts] Make `preferStrictDomainInLineCharts` the default (#21744) @JCQuintas
51
+ - [charts] Move title and description to the layer container (#21757) @alexfauquette
52
+ - [charts] Refactor `FunnelChart` classes structure (#21652) @JCQuintas
53
+ - [charts] Refactor `Heatmap` classes structure (#21653) @JCQuintas
54
+ - [charts] Refactor `RadarChart` classes structure (#21650) @JCQuintas
55
+ - [charts] Refactor `SankeyChart` classes structure (#21654) @JCQuintas
56
+ - [charts] Refactor legend getters to use utility functions (#21628) @sai6855
57
+ - [charts] Remove deprecated `ChartContainer` and `ChartDataProvider` (#21777) @alexfauquette
58
+ - [charts] Remove deprecated `itemId` from `SeriesLegendItemContext` (#21788) @alexfauquette
59
+ - [charts] Remove deprecated `useMouseTracker()` (#21787) @alexfauquette
60
+ - [charts] Remove deprecated classes (#21775) @alexfauquette
61
+ - [charts] Remove deprecated props from PieArcLabel animation (#21789) @alexfauquette
62
+ - [charts] Remove get*UtilityClass from public exports (#21769) @JCQuintas
63
+ - [charts] Remove the deprecated `disableHover` property (#21785) @alexfauquette
64
+ - [charts] Remove the deprecated `message` prop (#21784) @alexfauquette
65
+ - [charts] Remove deprecated props about voronoi (#21796) @alexfauquette
66
+ - [charts] Remove deprecated pieArcClasses (#21795) @alexfauquette
67
+ - [charts] Rename `data-series-id` by `data-series` (#21761) @alexfauquette
68
+ - [charts] Rename `voronoiMaxRadius`/`disableVoronoi` to `hitAreaRadius`/`disableHitArea` (#21750) @bernardobelchior
69
+ - [charts] Update pt-PT locale (#21296) @bernardobelchior
70
+ - [charts] Use different shape per series by default (#21713) @alexfauquette
71
+ - [charts] Add className prop to Radar components (#21794) @JCQuintas
72
+ - [charts] Add className prop to shared chart components (#21792) @JCQuintas
73
+ - [charts] Add className prop to BarPlot (#21791) @JCQuintas
74
+ - [charts] Portal tooltip into ChartsLayerContainer (#21801) @JCQuintas
75
+
76
+ #### `@mui/x-charts-pro@9.0.0-alpha.4` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
77
+
78
+ Same changes as in `@mui/x-charts@9.0.0-alpha.4`, plus:
79
+
80
+ - [charts-pro] Allow `brush` interaction to accept `requiredKeys/pointerMode` (#21716) @JCQuintas
81
+ - [charts-pro] Remove deprecated `onAxisClick` for Heatmap (#21786) @alexfauquette
82
+
83
+ #### `@mui/x-charts-premium@9.0.0-alpha.4` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
84
+
85
+ Same changes as in `@mui/x-charts-pro@9.0.0-alpha.4`, plus:
86
+
87
+ - [charts-premium] Add candlestick chart (#21129) @bernardobelchior
88
+
89
+ ### Tree View
90
+
91
+ #### `@mui/x-tree-view@9.0.0-alpha.4`
92
+
93
+ Internal changes.
94
+
95
+ #### `@mui/x-tree-view-pro@9.0.0-alpha.4` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
96
+
97
+ Same changes as in `@mui/x-tree-view@9.0.0-alpha.4`.
98
+
99
+ ### Codemod
100
+
101
+ #### `@mui/x-codemod@9.0.0-alpha.4`
102
+
103
+ Internal changes.
104
+
105
+ ### Docs
106
+
107
+ - [docs-infra] Exclude `ServerSideLazyLoadingRevalidation` from argos (#21734) @sai6855
108
+ - [docs] Update charts v9 migration guide to include premium package (#21743) @bernardobelchior
109
+ - [docs] Update v9 migration guides to install next tag (#21741) @bernardobelchior
110
+ - [docs] Revise the Pie chart docs (#21565) @mapache-salvaje
111
+ - [docs] Revise the Bar Chart docs (#21482) @mapache-salvaje
112
+ - [docs] Removed a `console.log` from an aggregation demo (#21698) @michelengelen
113
+
114
+ ### Core
115
+
116
+ - [code-infra] Add pkg-pr-new as dev dependency (#21754) @Janpot
117
+ - [code-infra] Prevent `combiner` to have default parameters (#21707) @JCQuintas
118
+ - [code-infra] Remove CI coverage collection and upload to Codecov (#21671) @Janpot
119
+ - [internal] Remove @bernardobelchior from Charts CODEOWNERS (#21776) @Copilot
120
+
121
+ ### Miscellaneous
122
+
123
+ - [x-license] Fix process.env.MUI_VERSION not being replaced during build (#21727) @aemartos
124
+ - [x-license] Add new watermark license status message (#21720) @aemartos
125
+
126
+ ## 9.0.0-alpha.3
127
+
128
+ _Mar 12, 2026_
129
+
130
+ We'd like to extend a big thank you to the 13 contributors who made this release possible. Here are some highlights ✨:
131
+
132
+ - 🐞 Bugfixes and internal improvements
133
+
134
+ The following team members contributed to this release:
135
+ @aemartos, @alexfauquette, @bernardobelchior, @brijeshb42, @cherniavskii, @flaviendelangle, @Janpot, @JCQuintas, @MBilalShafi, @michelengelen, @rita-codes, @sai6855, @siriwatknp
136
+
137
+ ### Data Grid
138
+
139
+ #### `@mui/x-data-grid@9.0.0-alpha.3`
140
+
141
+ - [DataGrid] Fix crash when `rows` and `rowModesModel` are updated simultaneously (#21265) @michelengelen
142
+ - [DataGrid] Add missing `resizablePanelHandle` classes to `gridClasses` object (#21538) @sai6855
143
+ - [DataGrid] Refactor `headerAlign` style calls (#21541) @sai6855
144
+
145
+ #### `@mui/x-data-grid-pro@9.0.0-alpha.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
146
+
147
+ Same changes as in `@mui/x-data-grid@9.0.0-alpha.3`, plus:
148
+
149
+ - [DataGridPro] Add `role="presentation"` to detail panel toggle header content (#21634) @michelengelen
150
+ - [DataGridPro] Fix sorting not reflected in nested server-side data (#21619) @MBilalShafi
151
+
152
+ #### `@mui/x-data-grid-premium@9.0.0-alpha.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
153
+
154
+ Same changes as in `@mui/x-data-grid-pro@9.0.0-alpha.3`.
155
+
156
+ ### Date and Time Pickers
157
+
158
+ #### `@mui/x-date-pickers@9.0.0-alpha.3`
159
+
160
+ - [pickers] Refactor `DateRangePickerDay` overrides to use a centralized `elementOverrides` object (#21426) @sai6855
161
+ - [pickers] Migrate from deprecated props for `PickersModalDialog` (#21702) @siriwatknp
162
+
163
+ #### `@mui/x-date-pickers-pro@9.0.0-alpha.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
164
+
165
+ Same changes as in `@mui/x-date-pickers@9.0.0-alpha.3`.
166
+
167
+ ### Charts
168
+
169
+ #### `@mui/x-charts@9.0.0-alpha.3`
170
+
171
+ - [charts] Differentiate Line Plot roots classes (#21679) @JCQuintas
172
+ - [charts] Enable keyboard navigation by default (#21675) @alexfauquette
173
+ - [charts] Fix keyboard tooltip radar (#21667) @alexfauquette
174
+ - [charts] Fix selector default parameter (#21638) @JCQuintas
175
+ - [charts] Fix tooltip blink between node and pointer anchor (#21611) @alexfauquette
176
+ - [charts] Let tooltip and legend reflect the line shape (#21475) @alexfauquette
177
+ - [charts] Refactor `BarChart` classes structure (#21601) @JCQuintas
178
+ - [charts] Refactor `LineChart` classes structure (#21648) @JCQuintas
179
+ - [charts] Refactor `ScatterChart` classes structure (#21651) @JCQuintas
180
+ - [charts] Refactor `PieChart` classes structure (#21649) @JCQuintas
181
+ - [charts] Remove batch rendering checks in highlight selectors (#21646) @bernardobelchior
182
+ - [charts] Standardize generic arg names to `SeriesType` (#21694) @alexfauquette
183
+ - [charts] Simplify highlight hooks return types (#21695) @alexfauquette
184
+
185
+ #### `@mui/x-charts-pro@9.0.0-alpha.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
186
+
187
+ Same changes as in `@mui/x-charts@9.0.0-alpha.3`, plus:
188
+
189
+ - [charts-pro] Fix heatmap style override from `arc` to `cell` (#21693) @Copilot
190
+ - [charts-pro] Fix image export truncated when page is zoomed out (#21685) @bernardobelchior
191
+ - [charts-pro] Speed-up heatmap cell search with an index lookup (#21130) @alexfauquette
192
+ - [charts-pro] Fix heatmap highlight not working (#21710) @Copilot
193
+
194
+ #### `@mui/x-charts-premium@9.0.0-alpha.3` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
195
+
196
+ Same changes as in `@mui/x-charts-pro@9.0.0-alpha.3`, plus:
197
+
198
+ - [charts-premium] Re-enable WebGL tests (#21708) @bernardobelchior
199
+
200
+ ### Tree View
201
+
202
+ #### Breaking changes
203
+
204
+ - Remove `TreeViewBaseItem` type (use `TreeViewDefaultItemModelProperties` or a custom interface)
205
+ - Remove `useTreeViewApiRef` hook (use `useRichTreeViewApiRef`, `useSimpleTreeViewApiRef`, or `useRichTreeViewProApiRef`)
206
+ - Remove `status` from content slot props returned by `getContentProps()` (use `data-*` attributes; `status` on `useTreeItem` return value is unchanged)
207
+ - Remove deprecated CSS state classes from `treeItemClasses`: `expanded`, `selected`, `focused`, `disabled`, `editable`, `editing` (use `[data-expanded]`, `[data-selected]`, etc.)
208
+ - The `<RichTreeViewPro />` component has now virtualization enabled by default.
209
+ - The items used inside the `<RichTreeViewPro />` now have a default height of `32px`.
210
+ - The events of the `<RichTreeViewPro />` are now rendered as a flat list instead of a nested tree.
211
+
212
+ #### `@mui/x-tree-view@9.0.0-alpha.3`
213
+
214
+ - [tree view] Remove deprecated APIs (#21591) @flaviendelangle
215
+ - [tree view] Fix collapsed children not selected with `selectionPropagation.descendants` in `SimpleTreeView` (#21253) @flaviendelangle
216
+
217
+ #### `@mui/x-tree-view-pro@9.0.0-alpha.3` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
218
+
219
+ Same changes as in `@mui/x-tree-view@9.0.0-alpha.3`, plus:
220
+
221
+ - [RichTreeViewPro] Make the virtualization opt-out and port the layout doc from the data grid (#21461) @flaviendelangle
222
+
223
+ ### Codemod
224
+
225
+ #### `@mui/x-codemod@9.0.0-alpha.3`
226
+
227
+ Internal changes.
228
+
229
+ ### Docs
230
+
231
+ - [docs] Fix `AssistantWithDataSource` demo crashing (#21555) @sai6855
232
+ - [docs] Remove `Preview` pill from Sankey (#21623) @bernardobelchior
233
+ - [docs] Migrate internal Material UI deprecated APIs (#21680) @siriwatknp
234
+ - [docs] Remove `New` flag on Tree View and Date and Time Pickers features released before v9 alpha (#21585) @flaviendelangle
235
+
236
+ ### Core
237
+
238
+ - [code-infra] Remove checkout step (#21688) @Janpot
239
+ - [code-infra] Fix contributor generation in changelog (#21718) @brijeshb42
240
+ - [docs-infra] Do not point to non-existent v8 subdomain (#21640) @cherniavskii
241
+
242
+ ### Miscellaneous
243
+
244
+ - [test] Add missing tests for forwarding props to filter operators in DataGrid (#21441) @siriwatknp
245
+ - [x-license] Export additional license types and constants (#21625) @aemartos
246
+ - [x-license] Refactor license verification to accept package info object and add v9 version gating (#21690) @aemartos
247
+
3
248
  ## 9.0.0-alpha.2
4
249
 
5
250
  _Mar 5, 2026_
@@ -92,7 +337,7 @@ Internal changes.
92
337
 
93
338
  - [docs] Add backticks and parentheses to all functions and hooks (DX-173) (#21496) @mapache-salvaje
94
339
  - [docs] Remove mentions of `mySvgRef` (#21559) @bernardobelchior
95
- - [docs] Update Roadmap section in the docs (#20892) @alelthomas
340
+ - [docs] Update Roadmap section in the docs (#20892) @alelthomas
96
341
  - [docs] Add tutorial and example app for aggregation with row grouping (DX-162) (#21102) @mapache-salvaje
97
342
  - [docs] Fix missing codemod docs (#21604) @JCQuintas
98
343
 
@@ -30,22 +30,16 @@ const useUtilityClasses = (classes, ownerState) => {
30
30
  };
31
31
  return (0, _composeClasses.default)(slots, _pickersSlideTransitionClasses.getPickersSlideTransitionUtilityClass, classes);
32
32
  };
33
+ const elementOverrides = ['slideEnter-left', 'slideEnter-right', 'slideEnterActive', 'slideExit', 'slideExitActiveLeft-left', 'slideExitActiveLeft-right'];
33
34
  const PickersSlideTransitionRoot = (0, _styles.styled)(_reactTransitionGroup.TransitionGroup, {
34
35
  name: 'MuiPickersSlideTransition',
35
36
  slot: 'Root',
36
- overridesResolver: (_, styles) => [styles.root, {
37
- [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses['slideEnter-left']}`]: styles['slideEnter-left']
38
- }, {
39
- [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses['slideEnter-right']}`]: styles['slideEnter-right']
40
- }, {
41
- [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses.slideEnterActive}`]: styles.slideEnterActive
42
- }, {
43
- [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses.slideExit}`]: styles.slideExit
44
- }, {
45
- [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses['slideExitActiveLeft-left']}`]: styles['slideExitActiveLeft-left']
46
- }, {
47
- [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses['slideExitActiveLeft-right']}`]: styles['slideExitActiveLeft-right']
48
- }]
37
+ overridesResolver: (_, styles) => elementOverrides.reduce((acc, key) => {
38
+ acc.push({
39
+ [`.${_pickersSlideTransitionClasses.pickersSlideTransitionClasses[key]}`]: styles[key]
40
+ });
41
+ return acc;
42
+ }, [styles.root])
49
43
  })(({
50
44
  theme
51
45
  }) => {
@@ -22,22 +22,16 @@ const useUtilityClasses = (classes, ownerState) => {
22
22
  };
23
23
  return composeClasses(slots, getPickersSlideTransitionUtilityClass, classes);
24
24
  };
25
+ const elementOverrides = ['slideEnter-left', 'slideEnter-right', 'slideEnterActive', 'slideExit', 'slideExitActiveLeft-left', 'slideExitActiveLeft-right'];
25
26
  const PickersSlideTransitionRoot = styled(TransitionGroup, {
26
27
  name: 'MuiPickersSlideTransition',
27
28
  slot: 'Root',
28
- overridesResolver: (_, styles) => [styles.root, {
29
- [`.${pickersSlideTransitionClasses['slideEnter-left']}`]: styles['slideEnter-left']
30
- }, {
31
- [`.${pickersSlideTransitionClasses['slideEnter-right']}`]: styles['slideEnter-right']
32
- }, {
33
- [`.${pickersSlideTransitionClasses.slideEnterActive}`]: styles.slideEnterActive
34
- }, {
35
- [`.${pickersSlideTransitionClasses.slideExit}`]: styles.slideExit
36
- }, {
37
- [`.${pickersSlideTransitionClasses['slideExitActiveLeft-left']}`]: styles['slideExitActiveLeft-left']
38
- }, {
39
- [`.${pickersSlideTransitionClasses['slideExitActiveLeft-right']}`]: styles['slideExitActiveLeft-right']
40
- }]
29
+ overridesResolver: (_, styles) => elementOverrides.reduce((acc, key) => {
30
+ acc.push({
31
+ [`.${pickersSlideTransitionClasses[key]}`]: styles[key]
32
+ });
33
+ return acc;
34
+ }, [styles.root])
41
35
  })(({
42
36
  theme
43
37
  }) => {
@@ -108,6 +108,10 @@ process.env.NODE_ENV !== "production" ? DateField.propTypes = {
108
108
  * @default true
109
109
  */
110
110
  enableAccessibleFieldDOMStructure: _propTypes.default.bool,
111
+ /**
112
+ * The ref object used to imperatively interact with the field.
113
+ */
114
+ fieldRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
111
115
  /**
112
116
  * If `true`, the component is displayed in focused state.
113
117
  */
@@ -320,10 +324,6 @@ process.env.NODE_ENV !== "production" ? DateField.propTypes = {
320
324
  * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.
321
325
  */
322
326
  timezone: _propTypes.default.string,
323
- /**
324
- * The ref object used to imperatively interact with the field.
325
- */
326
- unstableFieldRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
327
327
  /**
328
328
  * The selected value.
329
329
  * Used when the component is controlled.
@@ -101,6 +101,10 @@ process.env.NODE_ENV !== "production" ? DateField.propTypes = {
101
101
  * @default true
102
102
  */
103
103
  enableAccessibleFieldDOMStructure: PropTypes.bool,
104
+ /**
105
+ * The ref object used to imperatively interact with the field.
106
+ */
107
+ fieldRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
104
108
  /**
105
109
  * If `true`, the component is displayed in focused state.
106
110
  */
@@ -313,10 +317,6 @@ process.env.NODE_ENV !== "production" ? DateField.propTypes = {
313
317
  * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.
314
318
  */
315
319
  timezone: PropTypes.string,
316
- /**
317
- * The ref object used to imperatively interact with the field.
318
- */
319
- unstableFieldRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
320
320
  /**
321
321
  * The selected value.
322
322
  * Used when the component is controlled.
@@ -118,6 +118,10 @@ process.env.NODE_ENV !== "production" ? DateTimeField.propTypes = {
118
118
  * @default true
119
119
  */
120
120
  enableAccessibleFieldDOMStructure: _propTypes.default.bool,
121
+ /**
122
+ * The ref object used to imperatively interact with the field.
123
+ */
124
+ fieldRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
121
125
  /**
122
126
  * If `true`, the component is displayed in focused state.
123
127
  */
@@ -360,10 +364,6 @@ process.env.NODE_ENV !== "production" ? DateTimeField.propTypes = {
360
364
  * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.
361
365
  */
362
366
  timezone: _propTypes.default.string,
363
- /**
364
- * The ref object used to imperatively interact with the field.
365
- */
366
- unstableFieldRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
367
367
  /**
368
368
  * The selected value.
369
369
  * Used when the component is controlled.
@@ -111,6 +111,10 @@ process.env.NODE_ENV !== "production" ? DateTimeField.propTypes = {
111
111
  * @default true
112
112
  */
113
113
  enableAccessibleFieldDOMStructure: PropTypes.bool,
114
+ /**
115
+ * The ref object used to imperatively interact with the field.
116
+ */
117
+ fieldRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
114
118
  /**
115
119
  * If `true`, the component is displayed in focused state.
116
120
  */
@@ -353,10 +357,6 @@ process.env.NODE_ENV !== "production" ? DateTimeField.propTypes = {
353
357
  * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.
354
358
  */
355
359
  timezone: PropTypes.string,
356
- /**
357
- * The ref object used to imperatively interact with the field.
358
- */
359
- unstableFieldRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
360
360
  /**
361
361
  * The selected value.
362
362
  * Used when the component is controlled.
@@ -111,6 +111,7 @@ const DigitalClock = exports.DigitalClock = /*#__PURE__*/React.forwardRef(functi
111
111
  const containerRef = React.useRef(null);
112
112
  const handleRef = (0, _useForkRef.default)(ref, containerRef);
113
113
  const listRef = React.useRef(null);
114
+ const lastActiveRef = React.useRef(null);
114
115
  const props = (0, _styles.useThemeProps)({
115
116
  props: inProps,
116
117
  name: 'MuiDigitalClock'
@@ -206,7 +207,8 @@ const DigitalClock = exports.DigitalClock = /*#__PURE__*/React.forwardRef(functi
206
207
  return;
207
208
  }
208
209
  const offsetTop = activeItem.offsetTop;
209
- if (autoFocus || !!focusedView) {
210
+ if ((autoFocus || !!focusedView) && activeItem !== lastActiveRef.current) {
211
+ lastActiveRef.current = activeItem;
210
212
  activeItem.focus();
211
213
  }
212
214
 
@@ -104,6 +104,7 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
104
104
  const containerRef = React.useRef(null);
105
105
  const handleRef = useForkRef(ref, containerRef);
106
106
  const listRef = React.useRef(null);
107
+ const lastActiveRef = React.useRef(null);
107
108
  const props = useThemeProps({
108
109
  props: inProps,
109
110
  name: 'MuiDigitalClock'
@@ -199,7 +200,8 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
199
200
  return;
200
201
  }
201
202
  const offsetTop = activeItem.offsetTop;
202
- if (autoFocus || !!focusedView) {
203
+ if ((autoFocus || !!focusedView) && activeItem !== lastActiveRef.current) {
204
+ lastActiveRef.current = activeItem;
203
205
  activeItem.focus();
204
206
  }
205
207
 
@@ -17,6 +17,7 @@ var _MenuList = _interopRequireDefault(require("@mui/material/MenuList"));
17
17
  var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem"));
18
18
  var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
19
19
  var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
20
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
20
21
  var _multiSectionDigitalClockSectionClasses = require("./multiSectionDigitalClockSectionClasses");
21
22
  var _dimensions = require("../internals/constants/dimensions");
22
23
  var _utils = require("../internals/utils/utils");
@@ -100,6 +101,7 @@ const MultiSectionDigitalClockSection = exports.MultiSectionDigitalClockSection
100
101
  const containerRef = React.useRef(null);
101
102
  const handleRef = (0, _useForkRef.default)(ref, containerRef);
102
103
  const previousActive = React.useRef(null);
104
+ const shouldRefocusOnNextRender = React.useRef(false);
103
105
  const props = (0, _styles.useThemeProps)({
104
106
  props: inProps,
105
107
  name: 'MuiMultiSectionDigitalClockSection'
@@ -131,13 +133,21 @@ const MultiSectionDigitalClockSection = exports.MultiSectionDigitalClockSection
131
133
  return;
132
134
  }
133
135
  const activeItem = containerRef.current.querySelector('[role="option"][tabindex="0"], [role="option"][aria-selected="true"]');
134
- if (active && autoFocus && activeItem) {
136
+ if (!activeItem) {
137
+ return;
138
+ }
139
+ const activeElement = document.activeElement;
140
+ const isSameItemAsPrevious = previousActive.current === activeItem;
141
+ const isFocusInsideSection = !!activeElement && containerRef.current.contains(activeElement);
142
+ const shouldRefocusSameItem = isSameItemAsPrevious && shouldRefocusOnNextRender.current;
143
+ if (active && autoFocus && (!isSameItemAsPrevious || shouldRefocusSameItem) && (previousActive.current == null || shouldRefocusOnNextRender.current || isFocusInsideSection)) {
144
+ previousActive.current = activeItem;
145
+ shouldRefocusOnNextRender.current = false;
135
146
  activeItem.focus();
136
147
  }
137
- if (!activeItem || previousActive.current === activeItem) {
148
+ if (isSameItemAsPrevious) {
138
149
  return;
139
150
  }
140
- previousActive.current = activeItem;
141
151
  const offsetTop = activeItem.offsetTop;
142
152
  const itemHeight = activeItem.offsetHeight;
143
153
  const containerHeight = containerRef.current.clientHeight;
@@ -155,9 +165,35 @@ const MultiSectionDigitalClockSection = exports.MultiSectionDigitalClockSection
155
165
  // Ensure we don't scroll past the top
156
166
  containerRef.current.scrollTop = Math.max(0, scrollPosition);
157
167
  });
168
+ const handleBlur = (0, _useEventCallback.default)(event => {
169
+ // Keep focus restoration only for in-picker keyboard navigation.
170
+ // Do not restore focus after leaving the picker, which would steal focus from external inputs.
171
+ const relatedTarget = event.relatedTarget;
172
+ const blurParent = relatedTarget?.parentElement;
173
+ const relatedTargetRole = relatedTarget?.getAttribute('role');
174
+ const shouldRefocus = blurParent?.nodeName === 'UL' && blurParent !== containerRef.current || relatedTargetRole === 'gridcell';
175
+ shouldRefocusOnNextRender.current = shouldRefocus;
176
+ if (previousActive.current && blurParent?.nodeName === 'UL' && blurParent !== containerRef.current) {
177
+ previousActive.current = null;
178
+ }
179
+ });
180
+
181
+ // Reset tracking when section becomes inactive
182
+ // so focus can be reapplied when user returns via keyboard
183
+ React.useEffect(() => {
184
+ if (!active) {
185
+ previousActive.current = null;
186
+ }
187
+ }, [active]);
158
188
  const focusedOptionIndex = items.findIndex(item => item.isFocused(item.value));
159
- const handleKeyDown = event => {
189
+ const handleKeyDown = (0, _useEventCallback.default)(event => {
160
190
  switch (event.key) {
191
+ case 'Tab':
192
+ {
193
+ // Preserve focus restoration when leaving the section with keyboard navigation.
194
+ shouldRefocusOnNextRender.current = true;
195
+ break;
196
+ }
161
197
  case 'PageUp':
162
198
  {
163
199
  const newIndex = (0, _utils.getFocusedListItemIndex)(containerRef.current) - 5;
@@ -183,15 +219,16 @@ const MultiSectionDigitalClockSection = exports.MultiSectionDigitalClockSection
183
219
  break;
184
220
  }
185
221
  default:
222
+ break;
186
223
  }
187
- };
224
+ });
188
225
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(MultiSectionDigitalClockSectionRoot, (0, _extends2.default)({
189
226
  ref: handleRef,
190
227
  className: (0, _clsx.default)(classes.root, className),
191
228
  ownerState: ownerState,
192
- autoFocusItem: autoFocus && active,
193
229
  role: "listbox",
194
- onKeyDown: handleKeyDown
230
+ onKeyDown: handleKeyDown,
231
+ onBlur: handleBlur
195
232
  }, other, {
196
233
  children: items.map((option, index) => {
197
234
  const isItemDisabled = option.isDisabled?.(option.value);
@@ -11,6 +11,7 @@ import MenuList from '@mui/material/MenuList';
11
11
  import MenuItem from '@mui/material/MenuItem';
12
12
  import useForkRef from '@mui/utils/useForkRef';
13
13
  import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
14
+ import useEventCallback from '@mui/utils/useEventCallback';
14
15
  import { getMultiSectionDigitalClockSectionUtilityClass } from "./multiSectionDigitalClockSectionClasses.mjs";
15
16
  import { DIGITAL_CLOCK_VIEW_HEIGHT, MULTI_SECTION_CLOCK_SECTION_WIDTH } from "../internals/constants/dimensions.mjs";
16
17
  import { getFocusedListItemIndex } from "../internals/utils/utils.mjs";
@@ -93,6 +94,7 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
93
94
  const containerRef = React.useRef(null);
94
95
  const handleRef = useForkRef(ref, containerRef);
95
96
  const previousActive = React.useRef(null);
97
+ const shouldRefocusOnNextRender = React.useRef(false);
96
98
  const props = useThemeProps({
97
99
  props: inProps,
98
100
  name: 'MuiMultiSectionDigitalClockSection'
@@ -124,13 +126,21 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
124
126
  return;
125
127
  }
126
128
  const activeItem = containerRef.current.querySelector('[role="option"][tabindex="0"], [role="option"][aria-selected="true"]');
127
- if (active && autoFocus && activeItem) {
129
+ if (!activeItem) {
130
+ return;
131
+ }
132
+ const activeElement = document.activeElement;
133
+ const isSameItemAsPrevious = previousActive.current === activeItem;
134
+ const isFocusInsideSection = !!activeElement && containerRef.current.contains(activeElement);
135
+ const shouldRefocusSameItem = isSameItemAsPrevious && shouldRefocusOnNextRender.current;
136
+ if (active && autoFocus && (!isSameItemAsPrevious || shouldRefocusSameItem) && (previousActive.current == null || shouldRefocusOnNextRender.current || isFocusInsideSection)) {
137
+ previousActive.current = activeItem;
138
+ shouldRefocusOnNextRender.current = false;
128
139
  activeItem.focus();
129
140
  }
130
- if (!activeItem || previousActive.current === activeItem) {
141
+ if (isSameItemAsPrevious) {
131
142
  return;
132
143
  }
133
- previousActive.current = activeItem;
134
144
  const offsetTop = activeItem.offsetTop;
135
145
  const itemHeight = activeItem.offsetHeight;
136
146
  const containerHeight = containerRef.current.clientHeight;
@@ -148,9 +158,35 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
148
158
  // Ensure we don't scroll past the top
149
159
  containerRef.current.scrollTop = Math.max(0, scrollPosition);
150
160
  });
161
+ const handleBlur = useEventCallback(event => {
162
+ // Keep focus restoration only for in-picker keyboard navigation.
163
+ // Do not restore focus after leaving the picker, which would steal focus from external inputs.
164
+ const relatedTarget = event.relatedTarget;
165
+ const blurParent = relatedTarget?.parentElement;
166
+ const relatedTargetRole = relatedTarget?.getAttribute('role');
167
+ const shouldRefocus = blurParent?.nodeName === 'UL' && blurParent !== containerRef.current || relatedTargetRole === 'gridcell';
168
+ shouldRefocusOnNextRender.current = shouldRefocus;
169
+ if (previousActive.current && blurParent?.nodeName === 'UL' && blurParent !== containerRef.current) {
170
+ previousActive.current = null;
171
+ }
172
+ });
173
+
174
+ // Reset tracking when section becomes inactive
175
+ // so focus can be reapplied when user returns via keyboard
176
+ React.useEffect(() => {
177
+ if (!active) {
178
+ previousActive.current = null;
179
+ }
180
+ }, [active]);
151
181
  const focusedOptionIndex = items.findIndex(item => item.isFocused(item.value));
152
- const handleKeyDown = event => {
182
+ const handleKeyDown = useEventCallback(event => {
153
183
  switch (event.key) {
184
+ case 'Tab':
185
+ {
186
+ // Preserve focus restoration when leaving the section with keyboard navigation.
187
+ shouldRefocusOnNextRender.current = true;
188
+ break;
189
+ }
154
190
  case 'PageUp':
155
191
  {
156
192
  const newIndex = getFocusedListItemIndex(containerRef.current) - 5;
@@ -176,15 +212,16 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
176
212
  break;
177
213
  }
178
214
  default:
215
+ break;
179
216
  }
180
- };
217
+ });
181
218
  return /*#__PURE__*/_jsx(MultiSectionDigitalClockSectionRoot, _extends({
182
219
  ref: handleRef,
183
220
  className: clsx(classes.root, className),
184
221
  ownerState: ownerState,
185
- autoFocusItem: autoFocus && active,
186
222
  role: "listbox",
187
- onKeyDown: handleKeyDown
223
+ onKeyDown: handleKeyDown,
224
+ onBlur: handleBlur
188
225
  }, other, {
189
226
  children: items.map((option, index) => {
190
227
  const isItemDisabled = option.isDisabled?.(option.value);
@@ -118,6 +118,10 @@ process.env.NODE_ENV !== "production" ? TimeField.propTypes = {
118
118
  * @default true
119
119
  */
120
120
  enableAccessibleFieldDOMStructure: _propTypes.default.bool,
121
+ /**
122
+ * The ref object used to imperatively interact with the field.
123
+ */
124
+ fieldRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
121
125
  /**
122
126
  * If `true`, the component is displayed in focused state.
123
127
  */
@@ -321,10 +325,6 @@ process.env.NODE_ENV !== "production" ? TimeField.propTypes = {
321
325
  * @default The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.
322
326
  */
323
327
  timezone: _propTypes.default.string,
324
- /**
325
- * The ref object used to imperatively interact with the field.
326
- */
327
- unstableFieldRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
328
328
  /**
329
329
  * The selected value.
330
330
  * Used when the component is controlled.