@mui/x-data-grid 9.11.0 → 9.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/CHANGELOG.md +317 -0
  2. package/DataGrid/DataGrid.js +4 -2
  3. package/DataGrid/DataGrid.mjs +4 -2
  4. package/DataGrid/useDataGridProps.d.mts +1 -1
  5. package/DataGrid/useDataGridProps.d.ts +1 -1
  6. package/components/GridPagination.js +1 -1
  7. package/components/GridPagination.mjs +1 -1
  8. package/components/GridRow.d.mts +1 -0
  9. package/components/GridRow.d.ts +1 -0
  10. package/components/GridRow.js +41 -6
  11. package/components/GridRow.mjs +41 -6
  12. package/components/cell/GridCell.js +21 -5
  13. package/components/cell/GridCell.mjs +21 -5
  14. package/components/cell/GridEditBooleanCell.d.mts +1 -1
  15. package/components/cell/GridEditBooleanCell.d.ts +1 -1
  16. package/components/cell/GridEditBooleanCell.js +4 -4
  17. package/components/cell/GridEditBooleanCell.mjs +4 -4
  18. package/components/cell/GridEditDateCell.d.mts +1 -1
  19. package/components/cell/GridEditDateCell.d.ts +1 -1
  20. package/components/cell/GridEditDateCell.js +5 -5
  21. package/components/cell/GridEditDateCell.mjs +5 -5
  22. package/components/cell/GridEditInputCell.d.mts +1 -1
  23. package/components/cell/GridEditInputCell.d.ts +1 -1
  24. package/components/cell/GridEditInputCell.js +1 -1
  25. package/components/cell/GridEditInputCell.mjs +1 -1
  26. package/components/cell/GridEditLongTextCell.d.mts +1 -1
  27. package/components/cell/GridEditLongTextCell.d.ts +1 -1
  28. package/components/cell/GridEditLongTextCell.js +2 -2
  29. package/components/cell/GridEditLongTextCell.mjs +2 -2
  30. package/components/cell/GridEditSingleSelectCell.d.mts +1 -1
  31. package/components/cell/GridEditSingleSelectCell.d.ts +1 -1
  32. package/components/cell/GridEditSingleSelectCell.js +4 -4
  33. package/components/cell/GridEditSingleSelectCell.mjs +4 -4
  34. package/components/columnHeaders/GridBaseColumnHeaders.js +1 -1
  35. package/components/columnHeaders/GridBaseColumnHeaders.mjs +1 -1
  36. package/components/columnHeaders/GridColumnHeaderItem.js +4 -0
  37. package/components/columnHeaders/GridColumnHeaderItem.mjs +4 -0
  38. package/components/columnHeaders/GridGenericColumnHeaderItem.d.mts +7 -0
  39. package/components/columnHeaders/GridGenericColumnHeaderItem.d.ts +7 -0
  40. package/components/columnHeaders/GridGenericColumnHeaderItem.js +5 -4
  41. package/components/columnHeaders/GridGenericColumnHeaderItem.mjs +5 -4
  42. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +18 -6
  43. package/components/panel/filterPanel/GridFilterInputSingleSelect.mjs +18 -6
  44. package/components/toolbarV8/Toolbar.d.mts +5 -1
  45. package/components/toolbarV8/Toolbar.d.ts +5 -1
  46. package/components/toolbarV8/Toolbar.js +34 -12
  47. package/components/toolbarV8/Toolbar.mjs +33 -11
  48. package/constants/gridClasses.d.mts +12 -0
  49. package/constants/gridClasses.d.ts +12 -0
  50. package/constants/gridClasses.js +1 -1
  51. package/constants/gridClasses.mjs +1 -1
  52. package/constants/localeTextConstants.js +4 -0
  53. package/constants/localeTextConstants.mjs +4 -0
  54. package/hooks/core/useGridApiInitialization.js +5 -1
  55. package/hooks/core/useGridApiInitialization.mjs +5 -1
  56. package/hooks/core/useGridStateInitialization.js +3 -1
  57. package/hooks/core/useGridStateInitialization.mjs +3 -1
  58. package/hooks/core/useGridVirtualizer.js +17 -1
  59. package/hooks/core/useGridVirtualizer.mjs +17 -1
  60. package/hooks/features/columnResize/useGridColumnResize.js +5 -0
  61. package/hooks/features/columnResize/useGridColumnResize.mjs +5 -0
  62. package/hooks/features/columns/gridColumnsUtils.d.mts +1 -1
  63. package/hooks/features/columns/gridColumnsUtils.d.ts +1 -1
  64. package/hooks/features/columns/gridColumnsUtils.js +2 -2
  65. package/hooks/features/columns/gridColumnsUtils.mjs +2 -2
  66. package/hooks/features/dataSource/gridDataSourceSelector.js +6 -2
  67. package/hooks/features/dataSource/gridDataSourceSelector.mjs +6 -2
  68. package/hooks/features/dataSource/models.d.mts +2 -2
  69. package/hooks/features/dataSource/models.d.ts +2 -2
  70. package/hooks/features/dataSource/useGridDataSourceBase.js +25 -8
  71. package/hooks/features/dataSource/useGridDataSourceBase.mjs +26 -9
  72. package/hooks/features/dataSource/useGridDataSourceFilterModelChange.d.mts +9 -0
  73. package/hooks/features/dataSource/useGridDataSourceFilterModelChange.d.ts +9 -0
  74. package/hooks/features/dataSource/useGridDataSourceFilterModelChange.js +57 -0
  75. package/hooks/features/dataSource/useGridDataSourceFilterModelChange.mjs +49 -0
  76. package/hooks/features/editing/useGridCellEditing.js +3 -1
  77. package/hooks/features/editing/useGridCellEditing.mjs +3 -1
  78. package/hooks/features/editing/useGridRowEditing.js +3 -1
  79. package/hooks/features/editing/useGridRowEditing.mjs +3 -1
  80. package/hooks/features/filter/gridFilterUtils.d.mts +13 -0
  81. package/hooks/features/filter/gridFilterUtils.d.ts +13 -0
  82. package/hooks/features/filter/gridFilterUtils.js +32 -1
  83. package/hooks/features/filter/gridFilterUtils.mjs +29 -1
  84. package/hooks/features/filter/useGridFilter.js +1 -21
  85. package/hooks/features/filter/useGridFilter.mjs +2 -22
  86. package/hooks/features/headerFiltering/gridHeaderFilteringSelectors.js +1 -1
  87. package/hooks/features/headerFiltering/gridHeaderFilteringSelectors.mjs +1 -1
  88. package/hooks/features/pivoting/gridPivotingInterfaces.d.mts +2 -2
  89. package/hooks/features/pivoting/gridPivotingInterfaces.d.ts +2 -2
  90. package/hooks/features/rowSelection/useGridRowSelection.js +1 -1
  91. package/hooks/features/rowSelection/useGridRowSelection.mjs +2 -2
  92. package/hooks/features/rows/gridRowsUtils.d.mts +37 -3
  93. package/hooks/features/rows/gridRowsUtils.d.ts +37 -3
  94. package/hooks/features/rows/gridRowsUtils.js +120 -23
  95. package/hooks/features/rows/gridRowsUtils.mjs +115 -22
  96. package/hooks/features/rows/useGridRowSpanning.js +5 -0
  97. package/hooks/features/rows/useGridRowSpanning.mjs +5 -0
  98. package/hooks/features/rows/useGridRows.js +10 -1
  99. package/hooks/features/rows/useGridRows.mjs +10 -1
  100. package/hooks/features/virtualization/gridVirtualizationSelectors.d.mts +1 -1
  101. package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +1 -1
  102. package/hooks/utils/useGridEvent.d.mts +2 -2
  103. package/hooks/utils/useGridEvent.d.ts +2 -2
  104. package/hooks/utils/useGridEvent.js +2 -0
  105. package/hooks/utils/useGridEvent.mjs +2 -0
  106. package/index.js +1 -1
  107. package/index.mjs +1 -1
  108. package/internals/index.d.mts +4 -2
  109. package/internals/index.d.ts +4 -2
  110. package/internals/index.js +48 -0
  111. package/internals/index.mjs +4 -2
  112. package/locales/arSD.js +5 -0
  113. package/locales/arSD.mjs +5 -0
  114. package/locales/beBY.js +5 -0
  115. package/locales/beBY.mjs +5 -0
  116. package/locales/bgBG.js +5 -0
  117. package/locales/bgBG.mjs +5 -0
  118. package/locales/bnBD.js +5 -0
  119. package/locales/bnBD.mjs +5 -0
  120. package/locales/caES.js +5 -0
  121. package/locales/caES.mjs +5 -0
  122. package/locales/csCZ.js +5 -0
  123. package/locales/csCZ.mjs +5 -0
  124. package/locales/daDK.js +5 -0
  125. package/locales/daDK.mjs +5 -0
  126. package/locales/deDE.js +5 -0
  127. package/locales/deDE.mjs +5 -0
  128. package/locales/elGR.js +5 -0
  129. package/locales/elGR.mjs +5 -0
  130. package/locales/esES.js +5 -0
  131. package/locales/esES.mjs +5 -0
  132. package/locales/faIR.js +5 -0
  133. package/locales/faIR.mjs +5 -0
  134. package/locales/fiFI.js +5 -0
  135. package/locales/fiFI.mjs +5 -0
  136. package/locales/frFR.js +5 -0
  137. package/locales/frFR.mjs +5 -0
  138. package/locales/heIL.js +5 -0
  139. package/locales/heIL.mjs +5 -0
  140. package/locales/hrHR.js +5 -0
  141. package/locales/hrHR.mjs +5 -0
  142. package/locales/huHU.js +5 -0
  143. package/locales/huHU.mjs +5 -0
  144. package/locales/hyAM.js +5 -0
  145. package/locales/hyAM.mjs +5 -0
  146. package/locales/idID.js +5 -0
  147. package/locales/idID.mjs +5 -0
  148. package/locales/isIS.js +5 -0
  149. package/locales/isIS.mjs +5 -0
  150. package/locales/itIT.js +5 -0
  151. package/locales/itIT.mjs +5 -0
  152. package/locales/jaJP.js +5 -0
  153. package/locales/jaJP.mjs +5 -0
  154. package/locales/koKR.js +5 -0
  155. package/locales/koKR.mjs +5 -0
  156. package/locales/nbNO.js +5 -0
  157. package/locales/nbNO.mjs +5 -0
  158. package/locales/nlNL.js +5 -0
  159. package/locales/nlNL.mjs +5 -0
  160. package/locales/nnNO.js +5 -0
  161. package/locales/nnNO.mjs +5 -0
  162. package/locales/plPL.js +5 -0
  163. package/locales/plPL.mjs +5 -0
  164. package/locales/ptBR.js +5 -0
  165. package/locales/ptBR.mjs +5 -0
  166. package/locales/ptPT.js +5 -0
  167. package/locales/ptPT.mjs +5 -0
  168. package/locales/roRO.js +5 -0
  169. package/locales/roRO.mjs +5 -0
  170. package/locales/ruRU.js +5 -0
  171. package/locales/ruRU.mjs +5 -0
  172. package/locales/skSK.js +5 -0
  173. package/locales/skSK.mjs +5 -0
  174. package/locales/svSE.js +5 -0
  175. package/locales/svSE.mjs +5 -0
  176. package/locales/thTH.js +5 -0
  177. package/locales/thTH.mjs +5 -0
  178. package/locales/trTR.js +5 -0
  179. package/locales/trTR.mjs +5 -0
  180. package/locales/ukUA.js +5 -0
  181. package/locales/ukUA.mjs +5 -0
  182. package/locales/urPK.js +5 -0
  183. package/locales/urPK.mjs +5 -0
  184. package/locales/viVN.js +5 -0
  185. package/locales/viVN.mjs +5 -0
  186. package/locales/zhCN.js +5 -0
  187. package/locales/zhCN.mjs +5 -0
  188. package/locales/zhHK.js +5 -0
  189. package/locales/zhHK.mjs +5 -0
  190. package/locales/zhTW.js +5 -0
  191. package/locales/zhTW.mjs +5 -0
  192. package/material/variables.d.mts +6 -1
  193. package/material/variables.d.ts +6 -1
  194. package/material/variables.js +17 -3
  195. package/material/variables.mjs +14 -4
  196. package/models/api/gridApiCommon.d.mts +2 -2
  197. package/models/api/gridApiCommon.d.ts +2 -2
  198. package/models/api/gridCallbackDetails.d.mts +11 -1
  199. package/models/api/gridCallbackDetails.d.ts +11 -1
  200. package/models/api/gridLocaleTextApi.d.mts +3 -0
  201. package/models/api/gridLocaleTextApi.d.ts +3 -0
  202. package/models/api/gridRowApi.d.mts +19 -7
  203. package/models/api/gridRowApi.d.ts +19 -7
  204. package/models/api/gridStateApi.d.mts +3 -2
  205. package/models/api/gridStateApi.d.ts +3 -2
  206. package/models/api/index.d.mts +1 -1
  207. package/models/api/index.d.ts +1 -1
  208. package/models/colDef/gridColDef.d.mts +5 -0
  209. package/models/colDef/gridColDef.d.ts +5 -0
  210. package/models/configuration/gridConfiguration.d.mts +13 -1
  211. package/models/configuration/gridConfiguration.d.ts +13 -1
  212. package/models/controlStateItem.d.mts +3 -2
  213. package/models/controlStateItem.d.ts +3 -2
  214. package/models/events/gridEventListener.d.mts +3 -2
  215. package/models/events/gridEventListener.d.ts +3 -2
  216. package/models/gridDataSource.d.mts +3 -0
  217. package/models/gridDataSource.d.ts +3 -0
  218. package/models/gridRows.d.mts +28 -1
  219. package/models/gridRows.d.ts +28 -1
  220. package/models/props/DataGridProps.d.mts +41 -38
  221. package/models/props/DataGridProps.d.ts +41 -38
  222. package/package.json +6 -6
  223. package/utils/domUtils.js +1 -1
  224. package/utils/domUtils.mjs +1 -1
  225. package/utils/getPublicApiRef.d.mts +2 -2
  226. package/utils/getPublicApiRef.d.ts +2 -2
  227. package/utils/getPublicApiRef.js +15 -3
  228. package/utils/getPublicApiRef.mjs +15 -3
  229. package/utils/keyboardUtils.d.mts +1 -0
  230. package/utils/keyboardUtils.d.ts +1 -0
  231. package/utils/keyboardUtils.js +6 -0
  232. package/utils/keyboardUtils.mjs +5 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,322 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.13.0
4
+
5
+ <!-- generated comparing v9.12.0..master -->
6
+
7
+ _Sep 4, 2026_
8
+
9
+ We'd like to extend a big thank you to the 14 contributors who made this release possible. Here are some highlights ✨:
10
+
11
+ - 🦮 Improve keyboard navigation features of the Charts.
12
+ - 🎨 Improved customization of the edit event dialog in the `EventCalendar`
13
+ - 🐞 Bugfixes
14
+ - 📚 Documentation improvements
15
+
16
+ Special thanks go out to these community members for their valuable contributions:
17
+ @Anexus5919, @jvskriubakken, @mustafajw07, @roychan1
18
+
19
+ The following team members contributed to this release:
20
+ @brijeshb42, @flaviendelangle, @hasdfa, @Janpot, @JCQuintas, @LukasTy, @michelengelen, @noraleonte, @rita-codes, @silviuaavram
21
+
22
+ ### Data Grid
23
+
24
+ #### `@mui/x-data-grid@9.13.0`
25
+
26
+ - [DataGrid] Call `onValueChange` after `setEditCellValue` in edit cells (#23417) @michelengelen
27
+ - [DataGrid] Add support for replacing rows instead of merging updates (#23323) @jvskriubakken
28
+ - [DataGrid] Always render `rowHeader` in virtualized setups (#23386) @silviuaavram
29
+ - [DataGrid] Export `ToolbarRoot` (#23322) @JCQuintas
30
+ - [DataGrid] Fix `rowsPerPage` selector appearing when `autoPageSize` is enabled and `pageSize` is one of `pageSizeOptions` (#23401) @roychan1
31
+ - [DataGrid] Fix row tree reset when a data source grid becomes visible (#23288) @JCQuintas
32
+
33
+ #### `@mui/x-data-grid-pro@9.13.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
34
+
35
+ Same changes as in `@mui/x-data-grid@9.13.0`, plus:
36
+
37
+ - [DataGridPro] Remove rows deleted server-side on nested lazy loading revalidation (#23320) @JCQuintas
38
+ - [DataGridPro] Stop `disableDebounce` from reaching the DOM in multi select filter (#23445) @JCQuintas
39
+
40
+ #### `@mui/x-data-grid-premium@9.13.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
41
+
42
+ Same changes as in `@mui/x-data-grid-pro@9.13.0`, plus:
43
+
44
+ - [DataGridPremium] Refine cell selection and speed up clipboard copy (#23473) @michelengelen
45
+ - [DataGridPremium] Select all cells with Ctrl+A (#23415) @michelengelen
46
+
47
+ ### Date and Time Pickers
48
+
49
+ #### `@mui/x-date-pickers@9.13.0`
50
+
51
+ Internal changes.
52
+
53
+ #### `@mui/x-date-pickers-pro@9.13.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
54
+
55
+ Same changes as in `@mui/x-date-pickers@9.13.0`.
56
+
57
+ ### Charts
58
+
59
+ #### `@mui/x-charts@9.13.0`
60
+
61
+ - [charts] Activate the focused axis with Enter/Space (#23219) @JCQuintas
62
+ - [charts] Add keyboard zoom and pan (#23369) @JCQuintas
63
+ - [charts] Fix line mark position under browser zoom in Safari (#23387) @noraleonte
64
+ - [charts] Fix y axis tick labels shortened near the top of the chart (#23435) @JCQuintas
65
+ - [charts] Focus the clicked item on radar charts (#23287) @JCQuintas
66
+ - [charts] Stop text measurements leaking into each other (#23430) @JCQuintas
67
+
68
+ #### `@mui/x-charts-pro@9.13.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
69
+
70
+ Same changes as in `@mui/x-charts@9.13.0`.
71
+
72
+ #### `@mui/x-charts-premium@9.13.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
73
+
74
+ Same changes as in `@mui/x-charts-pro@9.13.0`.
75
+
76
+ ### Tree View
77
+
78
+ #### `@mui/x-tree-view@9.13.0`
79
+
80
+ - [tree view] Add `loading` prop and customizable loading UI (#22251) @michelengelen
81
+ - [tree view] Reduce selector bundle size (#23412) @flaviendelangle
82
+ - [tree view] Remove dead UI from community component (#23487) @noraleonte
83
+ - [tree view] Remove unused dependencies (#23488) @noraleonte
84
+ - [tree view] Use `useId` for the default tree id (#23341) @Anexus5919
85
+
86
+ #### `@mui/x-tree-view-pro@9.13.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
87
+
88
+ Same changes as in `@mui/x-tree-view@9.13.0`.
89
+
90
+ ### Scheduler
91
+
92
+ #### `@mui/x-scheduler@9.0.0-beta.11`
93
+
94
+ - [scheduler] Absorb un-acted `ResizeObserver` deliveries after rendering the timeline (#23444) @rita-codes
95
+ - [scheduler] Add `EventContextMenu` with Edit and Delete actions (#23379) @mustafajw07
96
+ - [scheduler] Add aria-hidden to collapsed side panel and refactor landmark structure (#23425) @mustafajw07
97
+ - [scheduler] Add the `eventDialogGeneralTab` slot (#23338) @rita-codes
98
+ - [scheduler] Fix the un-awaited act warning in the event dialog slot test (#23446) @JCQuintas
99
+ - [scheduler] Improve timeline event layout performance (#23364) @flaviendelangle
100
+ - [scheduler] Keep `aria-expanded` present when ViewSwitcher and PreferencesMenu menus are closed (#23427) @mustafajw07
101
+ - [scheduler] Make the event dialog General-tab building blocks public (#23398) @rita-codes
102
+ - [scheduler] Migrate to the pragmatic-drag-and-drop v3 entry points (#23442) @rita-codes
103
+ - [scheduler] Reduce selector bundle size (#23413) @flaviendelangle
104
+ - [scheduler] Reuse processed events between updates (#23363) @flaviendelangle
105
+ - [scheduler] Add `aria-expanded` and `aria-controls` to side panel toggle button (#23402) @mustafajw07
106
+
107
+ #### `@mui/x-scheduler-premium@9.0.0-beta.11` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
108
+
109
+ Same changes as in `@mui/x-scheduler@9.0.0-beta.11`, plus:
110
+
111
+ - [scheduler-premium] Dependencies - Keep event drags working over the arrow hit-areas (#23441) @rita-codes
112
+ - [scheduler-premium] Dependencies - Reject dependencies that would create a cycle (#23389) @rita-codes
113
+ - [scheduler-premium] Key recurring `exDates` on their data-timezone day (#23467) @rita-codes
114
+
115
+ ### Codemod
116
+
117
+ #### `@mui/x-codemod@9.13.0`
118
+
119
+ Internal changes.
120
+
121
+ ### Docs
122
+
123
+ - [docs] Add synchronized tooltip and crosshair demo to charts (#23368) @JCQuintas
124
+ - [docs] Add sticky headers recipe to `RichTreeView` customization (#22908) @michelengelen
125
+ - [docs] Pin the visible date of the scheduler preferences demos (#23432) @rita-codes
126
+ - [docs] Star-prefix bare :where() dark-mode selectors (#23419) @Janpot
127
+ - [docs] Consolidate demo data into shared dataset files (#23496) @michelengelen
128
+
129
+ ### Core
130
+
131
+ - [code-infra] Consume shared commands from code-infra orb (#23485) @brijeshb42
132
+ - [code-infra] Move the shared spy helpers off Sinon (#23466) @JCQuintas
133
+ - [code-infra] Point the support validator link at frontend-public (#23422) @Janpot
134
+ - [code-infra] Reduce per-page memory in the browser test suite (#23424) @Janpot
135
+ - [code-infra] Remove Sinon (#23476) @JCQuintas
136
+ - [code-infra] Remove the explicit `styled-components` dependency (#23479) @LukasTy
137
+ - [code-infra] Replace the mechanical sinon `spy()` usages with `vi.fn()` (#23443) @JCQuintas
138
+ - [code-infra] Replace the sinon `spy(fn)` usages with `vi.fn(fn)` (#23460) @JCQuintas
139
+ - [code-infra] Replace the sinon spy types with the Vitest ones (#23464) @JCQuintas
140
+ - [code-infra] Replace the sinon spy-on-object calls with `vi.spyOn` (#23474) @JCQuintas
141
+ - [code-infra] Replace the sinon stubs with Vitest mocks (#23472) @JCQuintas
142
+ - [code-infra] Run TypeScript 7 alongside the TS6 JS API (#23471) @brijeshb42
143
+ - [code-infra] Trim the shared browser test setup graph (#23426) @LukasTy
144
+ - [code-infra] Update CircleCI orb (#23418) @JCQuintas
145
+ - [code-infra] Use explicit vitest imports in test files (#23375) @michelengelen
146
+
147
+ ### Miscellaneous
148
+
149
+ - [chat] Enforce top-level type imports (#23037) @Janpot
150
+ - [chat] Fix global preload error from the `remend` import (#23263) @hasdfa
151
+ - [ci] Add Claude PR review via mui-public reusable workflow (#23423) @Janpot
152
+ - [telemetry] Fix get-context test leaking mock from sender test (#23447) @JCQuintas
153
+ - [test] Fail the regression run when a webfont does not load (#23376) @LukasTy
154
+
155
+ ## 9.12.0
156
+
157
+ _Aug 21, 2026_
158
+
159
+ We'd like to extend a big thank you to the 12 contributors who made this release possible. Here are some highlights ✨:
160
+
161
+ - 🧮 Support [Formulas](https://mui.com/x/react-data-grid/formulas/) on the Data Grid: cells in opted-in columns can hold spreadsheet-like formulas (`=SUM(RANGE(…))`, `=price * quantity`) evaluated by a built-in engine, with a formula editor and [Formula Bar](https://mui.com/x/react-data-grid/components/formula-bar/), autocomplete, reference highlighting, optional A1 notation, fill-handle reference adjustment, custom functions, and live formula Excel export
162
+ - ♿️ Improve the accessibility of Data Grid cells and picker day cells
163
+ - 🗓️ Enable multi-resource event creation and editing in the Scheduler
164
+ - 🐞 Bugfixes
165
+ - 📚 Documentation improvements
166
+
167
+ Special thanks go out to these community members for their valuable contributions:
168
+ @Anexus5919, @mustafajw07
169
+
170
+ The following team members contributed to this release:
171
+ @brijeshb42, @flaviendelangle, @JCQuintas, @LukasTy, @MBilalShafi, @michelengelen, @noraleonte, @rita-codes, @romgrk, @silviuaavram
172
+
173
+ ### Data Grid
174
+
175
+ #### `@mui/x-data-grid@9.12.0`
176
+
177
+ - [DataGrid] Expose `apiRef` on `GridCallbackDetails` for selector access in callbacks (#22973) @michelengelen
178
+ - [DataGrid] Fix header height not updating when `headerFilters` or `columnGroupingModel` change (#23059) @MBilalShafi
179
+ - [DataGrid] Fix unhandled rejection when unmounting mid-autosize (#23319) @JCQuintas
180
+ - [DataGrid] Label the blank `singleSelect` filter option (#23294) @JCQuintas
181
+ - [DataGrid] Stop sending incomplete filter items to the data source (#23303) @JCQuintas
182
+ - [DataGrid] Support the `rowheader` attribute for grid cells (#23340) @silviuaavram
183
+
184
+ #### `@mui/x-data-grid-pro@9.12.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
185
+
186
+ Same changes as in `@mui/x-data-grid@9.12.0`, plus:
187
+
188
+ - [DataGridPro] Honor `hasNextPage` in infinite lazy loading (#23048) @MBilalShafi
189
+
190
+ #### `@mui/x-data-grid-premium@9.12.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
191
+
192
+ Same changes as in `@mui/x-data-grid-pro@9.12.0`, plus:
193
+
194
+ - [DataGridPremium] Formula support (#22807) @MBilalShafi
195
+
196
+ ### Date and Time Pickers
197
+
198
+ #### `@mui/x-date-pickers@9.12.0`
199
+
200
+ - [fields] Keep the selected section on blank space clicks (#23318) @LukasTy
201
+ - [pickers] Associate the day cells with their week day column header (#23339) @LukasTy
202
+ - [pickers] Keep the `gridcell` role and the column index on filler cells (#23326) @Anexus5919
203
+
204
+ #### `@mui/x-date-pickers-pro@9.12.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
205
+
206
+ Same changes as in `@mui/x-date-pickers@9.12.0`, plus:
207
+
208
+ - [DateRangeCalendar] Round the range highlight at the month grid edges (#23297) @JCQuintas
209
+ - [DateRangePicker] Keep the range highlight opaque for disabled days (#23317) @JCQuintas
210
+
211
+ ### Charts
212
+
213
+ #### `@mui/x-charts@9.12.0`
214
+
215
+ - [charts] Add a demo for label on grid row (#23333) @noraleonte
216
+ - [charts] Fix React 18 `propTypes` warnings and stray-pointer test flakiness (#23384) @LukasTy
217
+ - [charts] Focus the clicked item for keyboard navigation (#23247) @JCQuintas
218
+
219
+ #### `@mui/x-charts-pro@9.12.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
220
+
221
+ Same changes as in `@mui/x-charts@9.12.0`.
222
+
223
+ #### `@mui/x-charts-premium@9.12.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
224
+
225
+ Same changes as in `@mui/x-charts-pro@9.12.0`, plus:
226
+
227
+ - [charts-premium] Add `onItemClick` to the radial charts (#23253) @JCQuintas
228
+
229
+ ### Tree View
230
+
231
+ #### `@mui/x-tree-view@9.12.0`
232
+
233
+ Internal changes.
234
+
235
+ #### `@mui/x-tree-view-pro@9.12.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
236
+
237
+ Same changes as in `@mui/x-tree-view@9.12.0`.
238
+
239
+ ### Scheduler
240
+
241
+ #### `@mui/x-scheduler@9.0.0-beta.10`
242
+
243
+ - [scheduler] Add `onEventEditingStart` to let consumers open their own edit UI (#23361) @rita-codes
244
+ - [scheduler] Fix keyboard and focus issues around the "+N more" popover (#23312) @rita-codes
245
+ - [scheduler] Honor `viewConfig` hour limits in the compact day and week views (#23316) @rita-codes
246
+ - [scheduler] Share timeline event layout data (#23366) @flaviendelangle
247
+ - [scheduler] enable multi-resource event creation and editing (#23313) @mustafajw07
248
+
249
+ #### `@mui/x-scheduler-premium@9.0.0-beta.10` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
250
+
251
+ Same changes as in `@mui/x-scheduler@9.0.0-beta.10`, plus:
252
+
253
+ - [scheduler-premium] Allow to control the min and max hour in the Event Timeline (#23212) @rita-codes
254
+ - [scheduler-premium] Dependencies - Create, select and delete via terminals (#23200) @rita-codes
255
+
256
+ ### Codemod
257
+
258
+ #### `@mui/x-codemod@9.12.0`
259
+
260
+ Internal changes.
261
+
262
+ ### Docs
263
+
264
+ - [docs][charts] Document line mark size customization (#23370) @JCQuintas
265
+ - [docs] Add recipe for constraining the `make-child` drop action by item type (#22940) @michelengelen
266
+ - [docs] Redirect the renamed Event Timeline views page (#23324) @brijeshb42
267
+ - [docs] Remove unused `adapter-dependencies.json` (#23328) @LukasTy
268
+
269
+ ### Core
270
+
271
+ - [code-infra] Add release skill (#23308) @brijeshb42
272
+ - [code-infra] Fix changelog categorization of docs and `DateRangeCalendar` tags (#23385) @JCQuintas
273
+ - [code-infra] Sync mui-release skill (#23330) @brijeshb42
274
+
275
+ ### Miscellaneous
276
+
277
+ - [core] Declare the missing `react-dom` peer dependencies (#23381) @LukasTy
278
+ - [test] Fix act warnings in the data source filter tests (#23360) @JCQuintas
279
+ - [virtualizer] Add inverse-sticky layout (#23053) @romgrk
280
+
281
+ ## 9.11.1
282
+
283
+ _Aug 6, 2026_
284
+
285
+ We'd like to extend a big thank you to the 2 contributors who made this release possible. Here are some highlights ✨:
286
+
287
+ - 🐛 Fix the empty `@mui/x-charts-vendor` package published in v9.11.0
288
+
289
+ The following team members contributed to this release:
290
+ @JCQuintas, @rita-codes
291
+
292
+ ### Charts
293
+
294
+ #### `@mui/x-charts@9.11.1`
295
+
296
+ - [charts] Fix empty `@mui/x-charts-vendor` published package (#23310) @JCQuintas
297
+
298
+ #### `@mui/x-charts-pro@9.11.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
299
+
300
+ Same changes as in `@mui/x-charts@9.11.1`.
301
+
302
+ #### `@mui/x-charts-premium@9.11.1` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
303
+
304
+ Same changes as in `@mui/x-charts-pro@9.11.1`.
305
+
306
+ #### `@mui/x-charts-vendor@9.11.1`
307
+
308
+ - [charts] Fix empty `@mui/x-charts-vendor` published package (#23310) @JCQuintas
309
+
310
+ ### Scheduler
311
+
312
+ #### `@mui/x-scheduler@9.0.0-beta.9`
313
+
314
+ - [scheduler] Show the range validation errors on the End date and End time fields (#23291) @rita-codes
315
+
316
+ #### `@mui/x-scheduler-premium@9.0.0-beta.9` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
317
+
318
+ Same changes as in `@mui/x-scheduler@9.0.0-beta.9`.
319
+
3
320
  ## 9.11.0
4
321
 
5
322
  _Aug 6, 2026_
@@ -33,7 +33,8 @@ const configuration = {
33
33
  useGridParamsOverridableMethods: _useGridParamsOverridableMethods.useGridParamsOverridableMethods,
34
34
  useIsCellEditable: _useGridCellEditable.useIsCellEditable,
35
35
  useCellAggregationResult: () => null,
36
- useFilterValueGetter: apiRef => apiRef.current.getRowValue
36
+ useFilterValueGetter: apiRef => apiRef.current.getRowValue,
37
+ useColumnHeaderAdornment: () => null
37
38
  }
38
39
  };
39
40
  const DataGridRaw = function DataGrid(inProps, ref) {
@@ -166,6 +167,7 @@ process.env.NODE_ENV !== "production" ? DataGridRaw.propTypes /* remove-proptype
166
167
  renderEditCell: _propTypes.default.func,
167
168
  renderHeader: _propTypes.default.func,
168
169
  resizable: _propTypes.default.bool,
170
+ rowHeader: _propTypes.default.bool,
169
171
  rowSpanValueGetter: _propTypes.default.func,
170
172
  sortable: _propTypes.default.bool,
171
173
  sortComparator: _propTypes.default.func,
@@ -775,7 +777,7 @@ process.env.NODE_ENV !== "production" ? DataGridRaw.propTypes /* remove-proptype
775
777
  * @param {R} newRow Row object with the new values.
776
778
  * @param {R} oldRow Row object with the old values.
777
779
  * @param {{ rowId: GridRowId }} params Additional parameters.
778
- * @returns {Promise<R> | R} The final values to update the row.
780
+ * @returns {Promise<R | GridRowModelReplace<R>> | R | GridRowModelReplace<R>} The final values to update the row, or a `{ _action: 'replace', row }` update to store `row` as the new row without merging.
779
781
  */
780
782
  processRowUpdate: _propTypes.default.func,
781
783
  /**
@@ -26,7 +26,8 @@ const configuration = {
26
26
  useGridParamsOverridableMethods,
27
27
  useIsCellEditable,
28
28
  useCellAggregationResult: () => null,
29
- useFilterValueGetter: apiRef => apiRef.current.getRowValue
29
+ useFilterValueGetter: apiRef => apiRef.current.getRowValue,
30
+ useColumnHeaderAdornment: () => null
30
31
  }
31
32
  };
32
33
  const DataGridRaw = function DataGrid(inProps, ref) {
@@ -159,6 +160,7 @@ process.env.NODE_ENV !== "production" ? DataGridRaw.propTypes /* remove-proptype
159
160
  renderEditCell: PropTypes.func,
160
161
  renderHeader: PropTypes.func,
161
162
  resizable: PropTypes.bool,
163
+ rowHeader: PropTypes.bool,
162
164
  rowSpanValueGetter: PropTypes.func,
163
165
  sortable: PropTypes.bool,
164
166
  sortComparator: PropTypes.func,
@@ -768,7 +770,7 @@ process.env.NODE_ENV !== "production" ? DataGridRaw.propTypes /* remove-proptype
768
770
  * @param {R} newRow Row object with the new values.
769
771
  * @param {R} oldRow Row object with the old values.
770
772
  * @param {{ rowId: GridRowId }} params Additional parameters.
771
- * @returns {Promise<R> | R} The final values to update the row.
773
+ * @returns {Promise<R | GridRowModelReplace<R>> | R | GridRowModelReplace<R>} The final values to update the row, or a `{ _action: 'replace', row }` update to store `row` as the new row without merging.
772
774
  */
773
775
  processRowUpdate: PropTypes.func,
774
776
  /**
@@ -1,3 +1,3 @@
1
1
  import type { DataGridProcessedProps, DataGridProps } from "../models/props/DataGridProps.mjs";
2
2
  import type { GridValidRowModel } from "../models/index.mjs";
3
- export declare const useDataGridProps: <R extends GridValidRowModel>(inProps: DataGridProps<R>) => DataGridProcessedProps<R>;
3
+ export declare const useDataGridProps: <R extends GridValidRowModel>(inProps: DataGridProps<R>) => DataGridProcessedProps<R, any>;
@@ -1,3 +1,3 @@
1
1
  import type { DataGridProcessedProps, DataGridProps } from "../models/props/DataGridProps.js";
2
2
  import type { GridValidRowModel } from "../models/index.js";
3
- export declare const useDataGridProps: <R extends GridValidRowModel>(inProps: DataGridProps<R>) => DataGridProcessedProps<R>;
3
+ export declare const useDataGridProps: <R extends GridValidRowModel>(inProps: DataGridProps<R>) => DataGridProcessedProps<R, any>;
@@ -71,7 +71,7 @@ function GridPagination() {
71
71
  warnedOnceMissingInPageSizeOptions.current = true;
72
72
  }
73
73
  }
74
- const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
74
+ const pageSizeOptions = !rootProps.autoPageSize && isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
75
75
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridPaginationRoot, (0, _extends2.default)({
76
76
  as: rootProps.slots.basePagination,
77
77
  count: rowCount ?? -1,
@@ -64,7 +64,7 @@ function GridPagination() {
64
64
  warnedOnceMissingInPageSizeOptions.current = true;
65
65
  }
66
66
  }
67
- const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
67
+ const pageSizeOptions = !rootProps.autoPageSize && isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
68
68
  return /*#__PURE__*/_jsx(GridPaginationRoot, _extends({
69
69
  as: rootProps.slots.basePagination,
70
70
  count: rowCount ?? -1,
@@ -16,6 +16,7 @@ export interface GridRowProps extends React.HTMLAttributes<HTMLDivElement> {
16
16
  columnsTotalWidth: number;
17
17
  firstColumnIndex: number;
18
18
  lastColumnIndex: number;
19
+ retainedColumnIndexes: number[];
19
20
  visibleColumns: GridStateColDef[];
20
21
  pinnedColumns: GridPinnedColumns;
21
22
  /**
@@ -16,6 +16,7 @@ export interface GridRowProps extends React.HTMLAttributes<HTMLDivElement> {
16
16
  columnsTotalWidth: number;
17
17
  firstColumnIndex: number;
18
18
  lastColumnIndex: number;
19
+ retainedColumnIndexes: number[];
19
20
  visibleColumns: GridStateColDef[];
20
21
  pinnedColumns: GridPinnedColumns;
21
22
  /**
@@ -39,7 +39,7 @@ var _useGridConfiguration = require("../hooks/utils/useGridConfiguration");
39
39
  var _useGridPrivateApiContext = require("../hooks/utils/useGridPrivateApiContext");
40
40
  var _createSelector = require("../utils/createSelector");
41
41
  var _jsxRuntime = require("react/jsx-runtime");
42
- const _excluded = ["selected", "rowId", "row", "index", "style", "rowHeight", "className", "visibleColumns", "pinnedColumns", "offsetLeft", "columnsTotalWidth", "firstColumnIndex", "lastColumnIndex", "focusedColumnIndex", "isFirstVisible", "isLastVisible", "isNotVisible", "showBottomBorder", "scrollbarWidth", "gridHasFiller", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave", "onMouseOut", "onMouseOver"];
42
+ const _excluded = ["selected", "rowId", "row", "index", "style", "rowHeight", "className", "visibleColumns", "pinnedColumns", "offsetLeft", "columnsTotalWidth", "firstColumnIndex", "lastColumnIndex", "retainedColumnIndexes", "focusedColumnIndex", "isFirstVisible", "isLastVisible", "isNotVisible", "showBottomBorder", "scrollbarWidth", "gridHasFiller", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave", "onMouseOut", "onMouseOver"];
43
43
  const isRowReorderingEnabledSelector = (0, _createSelector.createSelector)(_gridEditingSelectors.gridEditRowsStateSelector, (editRows, {
44
44
  rowReordering,
45
45
  treeData
@@ -65,6 +65,7 @@ const GridRow = (0, _forwardRef.forwardRef)(function GridRow(props, refProp) {
65
65
  columnsTotalWidth,
66
66
  firstColumnIndex,
67
67
  lastColumnIndex,
68
+ retainedColumnIndexes,
68
69
  focusedColumnIndex,
69
70
  isFirstVisible,
70
71
  isLastVisible,
@@ -231,7 +232,16 @@ const GridRow = (0, _forwardRef.forwardRef)(function GridRow(props, refProp) {
231
232
  const width = cellColSpanInfo?.cellProps.width ?? column.computedWidth;
232
233
  const colSpan = cellColSpanInfo?.cellProps.colSpan ?? 1;
233
234
  const pinnedOffset = (0, _getPinnedCellOffset.getPinnedCellOffset)(pinnedPosition, column.computedWidth, indexRelativeToAllColumns, columnPositions, columnsTotalWidth, scrollbarWidth);
235
+
236
+ // Virtual cells stay mounted for focus and accessibility relationships, but GridCell collapses
237
+ // them to zero size so they do not participate in the visible row layout.
238
+ const cellIsNotVisible = pinnedPosition === _constants.PinnedColumnPosition.VIRTUAL;
234
239
  if (rowNode.type === 'skeletonRow') {
240
+ // Skeleton cells have no value to expose and don't support the collapsed style, so a virtual
241
+ // one would only add a full-width placeholder that shifts the rest of the row.
242
+ if (cellIsNotVisible) {
243
+ return null;
244
+ }
235
245
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(slots.skeletonCell, {
236
246
  type: column.type,
237
247
  width: width,
@@ -254,7 +264,6 @@ const GridRow = (0, _forwardRef.forwardRef)(function GridRow(props, refProp) {
254
264
  const canReorderColumn = !(disableColumnReorder || column.disableReorder);
255
265
  const canReorderRow = isRowReorderingEnabled && !sortModel.length;
256
266
  const disableDragEvents = !(canReorderColumn || isReorderCell && canReorderRow || isRowDragActive);
257
- const cellIsNotVisible = pinnedPosition === _constants.PinnedColumnPosition.VIRTUAL;
258
267
  const showLeftBorder = (0, _cellBorderUtils.shouldCellShowLeftBorder)(pinnedPosition, indexInSection, rootProps.showCellVerticalBorder, rootProps.pinnedColumnsSectionSeparator);
259
268
  const showRightBorder = (0, _cellBorderUtils.shouldCellShowRightBorder)(pinnedPosition, indexInSection, sectionLength, rootProps.showCellVerticalBorder, gridHasFiller, rootProps.pinnedColumnsSectionSeparator);
260
269
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(slots.cell, (0, _extends2.default)({
@@ -284,9 +293,27 @@ const GridRow = (0, _forwardRef.forwardRef)(function GridRow(props, refProp) {
284
293
  return getCell(column, i, indexRelativeToAllColumns, pinnedColumns.right.length, _constants.PinnedColumnPosition.RIGHT);
285
294
  });
286
295
  const middleColumnsLength = visibleColumns.length - pinnedColumns.left.length - pinnedColumns.right.length;
296
+
297
+ // Build the middle section in visual column order:
298
+ // 1. retained or focused virtual cells before the render context;
299
+ // 2. the cells inside the render context;
300
+ // 3. retained or focused virtual cells after the render context.
287
301
  const cells = [];
288
- if (hasVirtualFocusCellLeft) {
289
- cells.push(getCell(visibleColumns[focusedColumnIndex], focusedColumnIndex - pinnedColumns.left.length, focusedColumnIndex, middleColumnsLength, _constants.PinnedColumnPosition.VIRTUAL));
302
+ const firstUnpinnedColumnIndex = pinnedColumns.left.length;
303
+ const lastUnpinnedColumnIndex = visibleColumns.length - pinnedColumns.right.length;
304
+
305
+ // Select retained columns before the render context. The unpinned bounds exclude retained
306
+ // columns already rendered by `leftCells` or `rightCells`.
307
+ const virtualColumnIndexesLeft = retainedColumnIndexes.filter(columnIndex => columnIndex >= firstUnpinnedColumnIndex && columnIndex < firstColumnIndex);
308
+
309
+ // The grid already retains a focused cell outside the render context. Add it to the same ordered
310
+ // list, unless the column is a retained row header and is therefore already present.
311
+ if (hasVirtualFocusCellLeft && !virtualColumnIndexesLeft.includes(focusedColumnIndex)) {
312
+ virtualColumnIndexesLeft.push(focusedColumnIndex);
313
+ virtualColumnIndexesLeft.sort((a, b) => a - b);
314
+ }
315
+ for (const columnIndex of virtualColumnIndexesLeft) {
316
+ cells.push(getCell(visibleColumns[columnIndex], columnIndex - pinnedColumns.left.length, columnIndex, middleColumnsLength, _constants.PinnedColumnPosition.VIRTUAL));
290
317
  }
291
318
  for (let i = firstColumnIndex; i < lastColumnIndex; i += 1) {
292
319
  const column = visibleColumns[i];
@@ -296,8 +323,15 @@ const GridRow = (0, _forwardRef.forwardRef)(function GridRow(props, refProp) {
296
323
  }
297
324
  cells.push(getCell(column, indexInSection, i, middleColumnsLength));
298
325
  }
299
- if (hasVirtualFocusCellRight) {
300
- cells.push(getCell(visibleColumns[focusedColumnIndex], focusedColumnIndex - pinnedColumns.left.length, focusedColumnIndex, middleColumnsLength, _constants.PinnedColumnPosition.VIRTUAL));
326
+
327
+ // Repeat the retention step for unpinned columns after the render context.
328
+ const virtualColumnIndexesRight = retainedColumnIndexes.filter(columnIndex => columnIndex >= lastColumnIndex && columnIndex < lastUnpinnedColumnIndex);
329
+ if (hasVirtualFocusCellRight && !virtualColumnIndexesRight.includes(focusedColumnIndex)) {
330
+ virtualColumnIndexesRight.push(focusedColumnIndex);
331
+ virtualColumnIndexesRight.sort((a, b) => a - b);
332
+ }
333
+ for (const columnIndex of virtualColumnIndexesRight) {
334
+ cells.push(getCell(visibleColumns[columnIndex], columnIndex - pinnedColumns.left.length, columnIndex, middleColumnsLength, _constants.PinnedColumnPosition.VIRTUAL));
301
335
  }
302
336
  const eventHandlers = row ? {
303
337
  onClick: publishClick,
@@ -358,6 +392,7 @@ process.env.NODE_ENV !== "production" ? GridRow.propTypes /* remove-proptypes */
358
392
  onMouseEnter: _propTypes.default.func,
359
393
  onMouseLeave: _propTypes.default.func,
360
394
  pinnedColumns: _propTypes.default.object.isRequired,
395
+ retainedColumnIndexes: _propTypes.default.arrayOf(_propTypes.default.number).isRequired,
361
396
  row: _propTypes.default.object.isRequired,
362
397
  rowHeight: _propTypes.default.oneOfType([_propTypes.default.oneOf(['auto']), _propTypes.default.number]).isRequired,
363
398
  rowId: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]).isRequired,
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
- const _excluded = ["selected", "rowId", "row", "index", "style", "rowHeight", "className", "visibleColumns", "pinnedColumns", "offsetLeft", "columnsTotalWidth", "firstColumnIndex", "lastColumnIndex", "focusedColumnIndex", "isFirstVisible", "isLastVisible", "isNotVisible", "showBottomBorder", "scrollbarWidth", "gridHasFiller", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave", "onMouseOut", "onMouseOver"];
5
+ const _excluded = ["selected", "rowId", "row", "index", "style", "rowHeight", "className", "visibleColumns", "pinnedColumns", "offsetLeft", "columnsTotalWidth", "firstColumnIndex", "lastColumnIndex", "retainedColumnIndexes", "focusedColumnIndex", "isFirstVisible", "isLastVisible", "isNotVisible", "showBottomBorder", "scrollbarWidth", "gridHasFiller", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave", "onMouseOut", "onMouseOver"];
6
6
  import * as React from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import clsx from 'clsx';
@@ -58,6 +58,7 @@ const GridRow = forwardRef(function GridRow(props, refProp) {
58
58
  columnsTotalWidth,
59
59
  firstColumnIndex,
60
60
  lastColumnIndex,
61
+ retainedColumnIndexes,
61
62
  focusedColumnIndex,
62
63
  isFirstVisible,
63
64
  isLastVisible,
@@ -224,7 +225,16 @@ const GridRow = forwardRef(function GridRow(props, refProp) {
224
225
  const width = cellColSpanInfo?.cellProps.width ?? column.computedWidth;
225
226
  const colSpan = cellColSpanInfo?.cellProps.colSpan ?? 1;
226
227
  const pinnedOffset = getPinnedCellOffset(pinnedPosition, column.computedWidth, indexRelativeToAllColumns, columnPositions, columnsTotalWidth, scrollbarWidth);
228
+
229
+ // Virtual cells stay mounted for focus and accessibility relationships, but GridCell collapses
230
+ // them to zero size so they do not participate in the visible row layout.
231
+ const cellIsNotVisible = pinnedPosition === PinnedColumnPosition.VIRTUAL;
227
232
  if (rowNode.type === 'skeletonRow') {
233
+ // Skeleton cells have no value to expose and don't support the collapsed style, so a virtual
234
+ // one would only add a full-width placeholder that shifts the rest of the row.
235
+ if (cellIsNotVisible) {
236
+ return null;
237
+ }
228
238
  return /*#__PURE__*/_jsx(slots.skeletonCell, {
229
239
  type: column.type,
230
240
  width: width,
@@ -247,7 +257,6 @@ const GridRow = forwardRef(function GridRow(props, refProp) {
247
257
  const canReorderColumn = !(disableColumnReorder || column.disableReorder);
248
258
  const canReorderRow = isRowReorderingEnabled && !sortModel.length;
249
259
  const disableDragEvents = !(canReorderColumn || isReorderCell && canReorderRow || isRowDragActive);
250
- const cellIsNotVisible = pinnedPosition === PinnedColumnPosition.VIRTUAL;
251
260
  const showLeftBorder = shouldCellShowLeftBorder(pinnedPosition, indexInSection, rootProps.showCellVerticalBorder, rootProps.pinnedColumnsSectionSeparator);
252
261
  const showRightBorder = shouldCellShowRightBorder(pinnedPosition, indexInSection, sectionLength, rootProps.showCellVerticalBorder, gridHasFiller, rootProps.pinnedColumnsSectionSeparator);
253
262
  return /*#__PURE__*/_jsx(slots.cell, _extends({
@@ -277,9 +286,27 @@ const GridRow = forwardRef(function GridRow(props, refProp) {
277
286
  return getCell(column, i, indexRelativeToAllColumns, pinnedColumns.right.length, PinnedColumnPosition.RIGHT);
278
287
  });
279
288
  const middleColumnsLength = visibleColumns.length - pinnedColumns.left.length - pinnedColumns.right.length;
289
+
290
+ // Build the middle section in visual column order:
291
+ // 1. retained or focused virtual cells before the render context;
292
+ // 2. the cells inside the render context;
293
+ // 3. retained or focused virtual cells after the render context.
280
294
  const cells = [];
281
- if (hasVirtualFocusCellLeft) {
282
- cells.push(getCell(visibleColumns[focusedColumnIndex], focusedColumnIndex - pinnedColumns.left.length, focusedColumnIndex, middleColumnsLength, PinnedColumnPosition.VIRTUAL));
295
+ const firstUnpinnedColumnIndex = pinnedColumns.left.length;
296
+ const lastUnpinnedColumnIndex = visibleColumns.length - pinnedColumns.right.length;
297
+
298
+ // Select retained columns before the render context. The unpinned bounds exclude retained
299
+ // columns already rendered by `leftCells` or `rightCells`.
300
+ const virtualColumnIndexesLeft = retainedColumnIndexes.filter(columnIndex => columnIndex >= firstUnpinnedColumnIndex && columnIndex < firstColumnIndex);
301
+
302
+ // The grid already retains a focused cell outside the render context. Add it to the same ordered
303
+ // list, unless the column is a retained row header and is therefore already present.
304
+ if (hasVirtualFocusCellLeft && !virtualColumnIndexesLeft.includes(focusedColumnIndex)) {
305
+ virtualColumnIndexesLeft.push(focusedColumnIndex);
306
+ virtualColumnIndexesLeft.sort((a, b) => a - b);
307
+ }
308
+ for (const columnIndex of virtualColumnIndexesLeft) {
309
+ cells.push(getCell(visibleColumns[columnIndex], columnIndex - pinnedColumns.left.length, columnIndex, middleColumnsLength, PinnedColumnPosition.VIRTUAL));
283
310
  }
284
311
  for (let i = firstColumnIndex; i < lastColumnIndex; i += 1) {
285
312
  const column = visibleColumns[i];
@@ -289,8 +316,15 @@ const GridRow = forwardRef(function GridRow(props, refProp) {
289
316
  }
290
317
  cells.push(getCell(column, indexInSection, i, middleColumnsLength));
291
318
  }
292
- if (hasVirtualFocusCellRight) {
293
- cells.push(getCell(visibleColumns[focusedColumnIndex], focusedColumnIndex - pinnedColumns.left.length, focusedColumnIndex, middleColumnsLength, PinnedColumnPosition.VIRTUAL));
319
+
320
+ // Repeat the retention step for unpinned columns after the render context.
321
+ const virtualColumnIndexesRight = retainedColumnIndexes.filter(columnIndex => columnIndex >= lastColumnIndex && columnIndex < lastUnpinnedColumnIndex);
322
+ if (hasVirtualFocusCellRight && !virtualColumnIndexesRight.includes(focusedColumnIndex)) {
323
+ virtualColumnIndexesRight.push(focusedColumnIndex);
324
+ virtualColumnIndexesRight.sort((a, b) => a - b);
325
+ }
326
+ for (const columnIndex of virtualColumnIndexesRight) {
327
+ cells.push(getCell(visibleColumns[columnIndex], columnIndex - pinnedColumns.left.length, columnIndex, middleColumnsLength, PinnedColumnPosition.VIRTUAL));
294
328
  }
295
329
  const eventHandlers = row ? {
296
330
  onClick: publishClick,
@@ -351,6 +385,7 @@ process.env.NODE_ENV !== "production" ? GridRow.propTypes /* remove-proptypes */
351
385
  onMouseEnter: PropTypes.func,
352
386
  onMouseLeave: PropTypes.func,
353
387
  pinnedColumns: PropTypes.object.isRequired,
388
+ retainedColumnIndexes: PropTypes.arrayOf(PropTypes.number).isRequired,
354
389
  row: PropTypes.object.isRequired,
355
390
  rowHeight: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number]).isRequired,
356
391
  rowId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,