@mui/x-virtualizer 1.0.0-beta.0 → 1.0.0-beta.1
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.
- package/CHANGELOG.md +107 -1
- package/features/dimensions.js +46 -1
- package/features/dimensions.mjs +46 -1
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,111 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.0.0-beta.0
|
|
4
|
+
|
|
5
|
+
<!-- generated comparing v9.0.0-alpha.4..master -->
|
|
6
|
+
|
|
7
|
+
_Mar 27, 2026_
|
|
8
|
+
|
|
9
|
+
We'd like to extend a big thank you to the 10 contributors who made this release possible. Here are some highlights ✨:
|
|
10
|
+
|
|
11
|
+
- 🔊 New Charts voiceover component for improved screen reader support
|
|
12
|
+
- ⌨️ Charts keyboard navigation improvements: axis tooltip now shows when navigating with the keyboard
|
|
13
|
+
- 📊 Charts axes now can be set to automatically resize to fit their content
|
|
14
|
+
- 📝 New `rowCheckbox` slot in Data Grid for easier checkbox column customization
|
|
15
|
+
- ⚡️ `fetchRows()` API in Data Grid Pro now defaults `start` and `end` based on scroll position with lazy loading
|
|
16
|
+
- 🐞 Bugfixes and internal improvements
|
|
17
|
+
|
|
18
|
+
The following team members contributed to this release:
|
|
19
|
+
@aemartos, @alexfauquette, @arminmeh, @cherniavskii, @Janpot, @JCQuintas, @mapache-salvaje, @michelengelen, @noraleonte, @rita-codes
|
|
20
|
+
|
|
21
|
+
### Data Grid
|
|
22
|
+
|
|
23
|
+
#### `@mui/x-data-grid@9.0.0-beta.0`
|
|
24
|
+
|
|
25
|
+
- [DataGrid] Add `rowCheckbox` slot for easier customization (#21797) @michelengelen
|
|
26
|
+
- [DataGrid] Prevent repeated `hasScrollbar` state updates (#21820) @arminmeh
|
|
27
|
+
|
|
28
|
+
#### `@mui/x-data-grid-pro@9.0.0-beta.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
29
|
+
|
|
30
|
+
Same changes as in `@mui/x-data-grid@9.0.0-beta.0`, plus:
|
|
31
|
+
|
|
32
|
+
- [DataGridPro] `fetchRows()` API's default `start` and `end` params based on scroll position with lazy loading (#21742) @arminmeh
|
|
33
|
+
|
|
34
|
+
#### `@mui/x-data-grid-premium@9.0.0-beta.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
35
|
+
|
|
36
|
+
Same changes as in `@mui/x-data-grid-pro@9.0.0-beta.0`.
|
|
37
|
+
|
|
38
|
+
### Date and Time Pickers
|
|
39
|
+
|
|
40
|
+
#### `@mui/x-date-pickers@9.0.0-beta.0`
|
|
41
|
+
|
|
42
|
+
Internal changes.
|
|
43
|
+
|
|
44
|
+
#### `@mui/x-date-pickers-pro@9.0.0-beta.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
45
|
+
|
|
46
|
+
Same changes as in `@mui/x-date-pickers@9.0.0-beta.0`.
|
|
47
|
+
|
|
48
|
+
### Charts
|
|
49
|
+
|
|
50
|
+
#### `@mui/x-charts@9.0.0-beta.0`
|
|
51
|
+
|
|
52
|
+
- [charts] Add `className` prop to Pro chart plot components (#21793) @JCQuintas
|
|
53
|
+
- [charts] Add experimental position-based pointer interaction for line series (#21809) @JCQuintas
|
|
54
|
+
- [charts] Add l10n to the bar accessibility (#21815) @alexfauquette
|
|
55
|
+
- [charts] Add localization for the basic charts (#21822) @alexfauquette
|
|
56
|
+
- [charts] Add voiceover component (#21344) @alexfauquette
|
|
57
|
+
- [charts] Allow axes to automatically resize to content (#21087) @JCQuintas
|
|
58
|
+
- [charts] Document multiple use-cases for references (#21768) @alexfauquette
|
|
59
|
+
- [charts] Remove compatibility layer for React vs native events (#21780) @JCQuintas
|
|
60
|
+
- [charts] Remove deprecated `barLabel` props (#21783) @alexfauquette
|
|
61
|
+
- [charts] Show axis tooltip when navigating with keyboard (#21689) @Copilot
|
|
62
|
+
|
|
63
|
+
#### `@mui/x-charts-pro@9.0.0-beta.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
64
|
+
|
|
65
|
+
Same changes as in `@mui/x-charts@9.0.0-beta.0`.
|
|
66
|
+
|
|
67
|
+
#### `@mui/x-charts-premium@9.0.0-beta.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
68
|
+
|
|
69
|
+
Same changes as in `@mui/x-charts-pro@9.0.0-beta.0`.
|
|
70
|
+
|
|
71
|
+
### Tree View
|
|
72
|
+
|
|
73
|
+
#### `@mui/x-tree-view@9.0.0-alpha.4`
|
|
74
|
+
|
|
75
|
+
Internal changes.
|
|
76
|
+
|
|
77
|
+
#### `@mui/x-tree-view-pro@9.0.0-alpha.4` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
78
|
+
|
|
79
|
+
Same changes as in `@mui/x-tree-view@9.0.0-alpha.4`.
|
|
80
|
+
|
|
81
|
+
### Codemod
|
|
82
|
+
|
|
83
|
+
#### `@mui/x-codemod@9.0.0-alpha.4`
|
|
84
|
+
|
|
85
|
+
Internal changes.
|
|
86
|
+
|
|
87
|
+
### Docs
|
|
88
|
+
|
|
89
|
+
- [docs] Document how to customize voiceover announcement (#21833) @alexfauquette
|
|
90
|
+
- [docs] Remove Discord mention from docs (#21855) @mapache-salvaje
|
|
91
|
+
- [docs] Remove stabilized experimental feature from demo (#21869) @JCQuintas
|
|
92
|
+
- [docs] Update telemetry guide to reflect pseudonymous data collection and license compliance (#21812) @aemartos
|
|
93
|
+
- [docs] Revise the Sparkline doc (#21614) @mapache-salvaje
|
|
94
|
+
- [docs] Revise the Gauge doc (#21673) @mapache-salvaje
|
|
95
|
+
- [docs] Revise the Heatmap doc (#21676) @mapache-salvaje
|
|
96
|
+
|
|
97
|
+
### Core
|
|
98
|
+
|
|
99
|
+
- [code-infra] Remove unused deps and unify es-toolkit via catalog (#21840) @Janpot
|
|
100
|
+
- [code-infra] Update @mui/internal-bundle-size-checker to canary.68 (#21836) @Janpot
|
|
101
|
+
- [code-infra] Update next (#21837) @Janpot
|
|
102
|
+
- [internal] Remove headless data grid packages (#21843) @cherniavskii
|
|
103
|
+
|
|
104
|
+
### Miscellaneous
|
|
105
|
+
|
|
106
|
+
- Add @romgrk to CODEOWNERS for `x-virtualizer` and `x-internals` (#21819) @Copilot
|
|
107
|
+
- [x-license] add 2022 plan version (#21814) @aemartos
|
|
108
|
+
|
|
3
109
|
## 9.0.0-alpha.4
|
|
4
110
|
|
|
5
111
|
_Mar 19, 2026_
|
|
@@ -59,7 +165,7 @@ Same changes as in `@mui/x-date-pickers@9.0.0-alpha.4`.
|
|
|
59
165
|
- [charts] Remove deprecated `useMouseTracker()` (#21787) @alexfauquette
|
|
60
166
|
- [charts] Remove deprecated classes (#21775) @alexfauquette
|
|
61
167
|
- [charts] Remove deprecated props from PieArcLabel animation (#21789) @alexfauquette
|
|
62
|
-
- [charts] Remove get
|
|
168
|
+
- [charts] Remove get\*UtilityClass from public exports (#21769) @JCQuintas
|
|
63
169
|
- [charts] Remove the deprecated `disableHover` property (#21785) @alexfauquette
|
|
64
170
|
- [charts] Remove the deprecated `message` prop (#21784) @alexfauquette
|
|
65
171
|
- [charts] Remove deprecated props about voronoi (#21796) @alexfauquette
|
package/features/dimensions.js
CHANGED
|
@@ -97,6 +97,21 @@ function initializeState(params) {
|
|
|
97
97
|
}
|
|
98
98
|
function useDimensions(store, params, _api) {
|
|
99
99
|
const isFirstSizing = React.useRef(true);
|
|
100
|
+
|
|
101
|
+
// Vertical scrollbar oscillation detector.
|
|
102
|
+
// Counts consecutive hasScrollY flips that happen with no row-height change.
|
|
103
|
+
// After 2 flips it is certainly a layout feedback loop, so every further flip
|
|
104
|
+
// is forced to false (no scrollbar). The counter resets when row heights change.
|
|
105
|
+
// Only vertical scrollbar can oscillate because column widths are never 'auto'.
|
|
106
|
+
// https://github.com/mui/mui-x/issues/20539
|
|
107
|
+
const scrollYOscillation = React.useRef({
|
|
108
|
+
counter: 0,
|
|
109
|
+
heights: {
|
|
110
|
+
content: 0,
|
|
111
|
+
pinnedTop: 0,
|
|
112
|
+
pinnedBottom: 0
|
|
113
|
+
}
|
|
114
|
+
});
|
|
100
115
|
const {
|
|
101
116
|
layout,
|
|
102
117
|
dimensions: {
|
|
@@ -130,6 +145,7 @@ function useDimensions(store, params, _api) {
|
|
|
130
145
|
width: columnsTotalWidth,
|
|
131
146
|
height: (0, _math.roundToDecimalPlaces)(rowsMeta.currentPageTotalHeight, 1)
|
|
132
147
|
};
|
|
148
|
+
const prevDimensions = store.state.dimensions;
|
|
133
149
|
let viewportOuterSize;
|
|
134
150
|
let viewportInnerSize;
|
|
135
151
|
let hasScrollX = false;
|
|
@@ -167,6 +183,36 @@ function useDimensions(store, params, _api) {
|
|
|
167
183
|
hasScrollY = content.height + scrollbarSize > container.height;
|
|
168
184
|
}
|
|
169
185
|
}
|
|
186
|
+
|
|
187
|
+
// Detect vertical scrollbar oscillation.
|
|
188
|
+
// Track consecutive hasScrollY flips with no row-height change.
|
|
189
|
+
// Once confirmed (≥ 2 flips), force hasScrollY off — the scrollbar is
|
|
190
|
+
// not genuinely needed, it is a layout feedback loop caused by stale
|
|
191
|
+
// rootSize or the horizontal scrollbar's height cascading.
|
|
192
|
+
{
|
|
193
|
+
const osc = scrollYOscillation.current;
|
|
194
|
+
const heightsChanged = rowsMeta.currentPageTotalHeight !== osc.heights.content || rowsMeta.pinnedTopRowsTotalHeight !== osc.heights.pinnedTop || rowsMeta.pinnedBottomRowsTotalHeight !== osc.heights.pinnedBottom;
|
|
195
|
+
if (heightsChanged) {
|
|
196
|
+
osc.counter = 0;
|
|
197
|
+
osc.heights = {
|
|
198
|
+
content: rowsMeta.currentPageTotalHeight,
|
|
199
|
+
pinnedTop: rowsMeta.pinnedTopRowsTotalHeight,
|
|
200
|
+
pinnedBottom: rowsMeta.pinnedBottomRowsTotalHeight
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (prevDimensions.isReady && hasScrollY !== prevDimensions.hasScrollY) {
|
|
204
|
+
if (!heightsChanged) {
|
|
205
|
+
osc.counter += 1;
|
|
206
|
+
}
|
|
207
|
+
if (osc.counter >= 2) {
|
|
208
|
+
hasScrollY = false;
|
|
209
|
+
// Recompute hasScrollX without the vertical scrollbar's width impact,
|
|
210
|
+
// otherwise the cascade (hasScrollY → narrower viewport → hasScrollX)
|
|
211
|
+
// keeps the horizontal scrollbar/filler alive and the root keeps resizing.
|
|
212
|
+
hasScrollX = hasScrollXIfNoYScrollBar;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
170
216
|
if (hasScrollY) {
|
|
171
217
|
viewportInnerSize.width -= scrollbarSize;
|
|
172
218
|
}
|
|
@@ -205,7 +251,6 @@ function useDimensions(store, params, _api) {
|
|
|
205
251
|
autoHeight: params.dimensions.autoHeight,
|
|
206
252
|
minimalContentHeight: params.dimensions.minimalContentHeight
|
|
207
253
|
};
|
|
208
|
-
const prevDimensions = store.state.dimensions;
|
|
209
254
|
if ((0, _isDeepEqual.isDeepEqual)(prevDimensions, newDimensions)) {
|
|
210
255
|
return;
|
|
211
256
|
}
|
package/features/dimensions.mjs
CHANGED
|
@@ -90,6 +90,21 @@ function initializeState(params) {
|
|
|
90
90
|
}
|
|
91
91
|
function useDimensions(store, params, _api) {
|
|
92
92
|
const isFirstSizing = React.useRef(true);
|
|
93
|
+
|
|
94
|
+
// Vertical scrollbar oscillation detector.
|
|
95
|
+
// Counts consecutive hasScrollY flips that happen with no row-height change.
|
|
96
|
+
// After 2 flips it is certainly a layout feedback loop, so every further flip
|
|
97
|
+
// is forced to false (no scrollbar). The counter resets when row heights change.
|
|
98
|
+
// Only vertical scrollbar can oscillate because column widths are never 'auto'.
|
|
99
|
+
// https://github.com/mui/mui-x/issues/20539
|
|
100
|
+
const scrollYOscillation = React.useRef({
|
|
101
|
+
counter: 0,
|
|
102
|
+
heights: {
|
|
103
|
+
content: 0,
|
|
104
|
+
pinnedTop: 0,
|
|
105
|
+
pinnedBottom: 0
|
|
106
|
+
}
|
|
107
|
+
});
|
|
93
108
|
const {
|
|
94
109
|
layout,
|
|
95
110
|
dimensions: {
|
|
@@ -123,6 +138,7 @@ function useDimensions(store, params, _api) {
|
|
|
123
138
|
width: columnsTotalWidth,
|
|
124
139
|
height: roundToDecimalPlaces(rowsMeta.currentPageTotalHeight, 1)
|
|
125
140
|
};
|
|
141
|
+
const prevDimensions = store.state.dimensions;
|
|
126
142
|
let viewportOuterSize;
|
|
127
143
|
let viewportInnerSize;
|
|
128
144
|
let hasScrollX = false;
|
|
@@ -160,6 +176,36 @@ function useDimensions(store, params, _api) {
|
|
|
160
176
|
hasScrollY = content.height + scrollbarSize > container.height;
|
|
161
177
|
}
|
|
162
178
|
}
|
|
179
|
+
|
|
180
|
+
// Detect vertical scrollbar oscillation.
|
|
181
|
+
// Track consecutive hasScrollY flips with no row-height change.
|
|
182
|
+
// Once confirmed (≥ 2 flips), force hasScrollY off — the scrollbar is
|
|
183
|
+
// not genuinely needed, it is a layout feedback loop caused by stale
|
|
184
|
+
// rootSize or the horizontal scrollbar's height cascading.
|
|
185
|
+
{
|
|
186
|
+
const osc = scrollYOscillation.current;
|
|
187
|
+
const heightsChanged = rowsMeta.currentPageTotalHeight !== osc.heights.content || rowsMeta.pinnedTopRowsTotalHeight !== osc.heights.pinnedTop || rowsMeta.pinnedBottomRowsTotalHeight !== osc.heights.pinnedBottom;
|
|
188
|
+
if (heightsChanged) {
|
|
189
|
+
osc.counter = 0;
|
|
190
|
+
osc.heights = {
|
|
191
|
+
content: rowsMeta.currentPageTotalHeight,
|
|
192
|
+
pinnedTop: rowsMeta.pinnedTopRowsTotalHeight,
|
|
193
|
+
pinnedBottom: rowsMeta.pinnedBottomRowsTotalHeight
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
if (prevDimensions.isReady && hasScrollY !== prevDimensions.hasScrollY) {
|
|
197
|
+
if (!heightsChanged) {
|
|
198
|
+
osc.counter += 1;
|
|
199
|
+
}
|
|
200
|
+
if (osc.counter >= 2) {
|
|
201
|
+
hasScrollY = false;
|
|
202
|
+
// Recompute hasScrollX without the vertical scrollbar's width impact,
|
|
203
|
+
// otherwise the cascade (hasScrollY → narrower viewport → hasScrollX)
|
|
204
|
+
// keeps the horizontal scrollbar/filler alive and the root keeps resizing.
|
|
205
|
+
hasScrollX = hasScrollXIfNoYScrollBar;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
163
209
|
if (hasScrollY) {
|
|
164
210
|
viewportInnerSize.width -= scrollbarSize;
|
|
165
211
|
}
|
|
@@ -198,7 +244,6 @@ function useDimensions(store, params, _api) {
|
|
|
198
244
|
autoHeight: params.dimensions.autoHeight,
|
|
199
245
|
minimalContentHeight: params.dimensions.minimalContentHeight
|
|
200
246
|
};
|
|
201
|
-
const prevDimensions = store.state.dimensions;
|
|
202
247
|
if (isDeepEqual(prevDimensions, newDimensions)) {
|
|
203
248
|
return;
|
|
204
249
|
}
|
package/index.js
CHANGED
package/index.mjs
CHANGED